英文:
Don't repeat checks on event methods (Bukkit/Spigot)
问题
我正在审查我一个重要项目的代码库,我注意到有超过150个事件处理程序,它们都运行基本相同的检查:
if (!(event.getDamager() instanceof Player))
return;
if (!(event.getEntity() instanceof Player))
return;
Player player = (Player) event.getDamager();
Player victim = (Player) event.getEntity();
if(!AntigriefManager.canInjure(player, victim)) return;
if (!EnchantChecks.mainhand(player, this)) return;
我的问题是,有没有一种很好的方法可以将这部分抽象出来?
是否可能将这些 player 和 victim 的值传递给多个 EntityDamageByEntityEvent
处理程序,而不是在每个处理程序上方重复编写它们?
谢谢!
英文:
I was reviewing my codebase for a major project of mine and i've noticed that there are over 150 event handlers that all run essentially the same check:
if (!(event.getDamager() instanceof Player))
return;
if (!(event.getEntity() instanceof Player))
return;
Player player = (Player) event.getDamager();
Player victim = (Player) event.getEntity();
if(!AntigriefManager.canInjure(player, victim)) return;
if (!EnchantChecks.mainhand(player, this)) return;
My question is, can would there be a good way of abstracting this away?
Is it possible to pass those player and victim values to multiple EntityDamageByEntityEvent
handlers instead of writing them above each one?
Thanks!
答案1
得分: 1
利用EventHandler
,特别是priority
和ignoreCancelled
。
你现在的代码是这样的:
@EventHandler
public void onMyEvent(SomeEvent event) {
//a) 一堆预检代码
//b) 你想要运行的实际代码,在几个不同的代码块中
}
你将要做的是将这些任务拆分为两个不同的监听器;一个将处理检查,另一个将运行它负责的任何内容。为此,我们的检查将在EventPriority.LOWEST
上运行,因为这些在任何其他优先级之前运行。除此之外,如果事件被取消,我们将使用EventHandler#ignoreCancelled
来表示我们的代码不应该被运行:
@EventHandler(priority = EventPriority.LOWEST)
public void onMyPrechecks(SomeEvent event) {
//a) 一堆预检代码,例如:
if (!AntigriefManager.canInjure(player, victim)) {
//注意,我们取消事件,而不是从方法中返回
event.setCancelled(true);
}
}
//其他地方,可能是另一个类中:
//优先级不应低于LOW
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onMyEvent(SomeEvent event) {
//b) 你想要运行的实际代码,例如:
event.getPlayer().sendMessage("运行事件!");
}
英文:
Make use of EventHandler
, specifically priority
and ignoreCancelled
.
Right now you have this:
@EventHandler
public void onMyEvent(SomeEvent event) {
//a) A bunch of precheck code
//b) The actual code you want to run, in several different code bodies
}
What you will end up doing is splitting these tasks into two different listeners; one will handle the checks, the other will run whatever it is responsible for. For this, our checks will run on EventPriority.LOWEST
, because those are run before any other priority. On top of that, if the event is cancelled, we will use EventHandler#ignoreCancelled
to indicate our code should not be run:
@EventHandler(priority = EventPriority.LOWEST)
public void onMyPrechecks(SomeEvent event) {
//a) A bunch of precheck code, for example:
if (!AntigriefManager.canInjure(player, victim)) {
//notice we cancel, instead of returning from a method
event.setCancelled(true);
}
}
//Elsewheres, in another class probably:
//priority should never go lower than LOW
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onMyEvent(SomeEvent event) {
//b) The actual code you want to run, e.g.:
event.getPlayer().sendMessage("running event!");
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论