事件监听器
要监听一个事件,必须要注册一个事件监听器。方法是创建一个方法,方法名任意,将方法的第一个参数定义为目标事件类型,然后给该方法附上 Listener 注解,如下所示。
import org.spongepowered.api.event.Listener;
@Listener
public void onSomeEvent(SomeEvent event) {
// Do something with the event
}
此外,包含这些方法的类必须在事件管理器注册:
小技巧
如果你的主类(即附有 Plugin 注解的类)有事件监听器,则你不需要注册事件对象,因为 Sponge 会自动执行此操作。
备注
事件总线 支持父类型 。例如, ChangeBlockEvent.All 继承自 ChangeBlockEvent 。因此,一个插件监听了 ChangeBlockEvent
事件也会接收到 ChangeBlockEvent.All
。但是,一个插件监听 ChangeBlockEvent.All
不会被任何其他类型的 ChangeBlockEvent
通知。
注册或取消事件监听器
To register event listeners annotated by @Listener
that are not in the main plugin class, you can use
EventManager#registerListeners(PluginContainer, Object), which accepts a reference to the plugin and an instance of
the class containing the event listeners.
示例:在其他类中注册事件监听器
import org.spongepowered.api.Sponge;
public class ExampleListener {
@Listener
public void onSomeEvent(SomeEvent event) {
// Do something with the event
}
}
Sponge.eventManager().registerListeners(this, new ExampleListener());
动态注册事件监听器
一些像脚本插件的插件或许会希望有动态注册事件监听器的功能。这是指事件监听器不是单纯通过 @Listener
来注册的,而是让保有监听器的类实现 EventListener
接口。这个事件监听器可以通过调用 EventManager#registerListener
来注册,该方法需要插件主类的引用,被监听的事件类和这个实现了 EventListener
类的实例作为参数。同时,你可以将 Order 参数放在监听器参数之前,来指定该事件监听器的执行 Order
。或者在监听器类参数之前传入一个额外的布尔值参数,来决定这个监听器是否在服务器启动之前被调用。
示例:实现 EventListener
import org.spongepowered.api.event.EventListener;
import org.spongepowered.api.event.block.ChangeBlockEvent;
public class ExampleListener implements EventListener<ChangeBlockEvent.All> {
@Override
public void handle(ChangeBlockEvent.Break event) throws Exception {
[...]
}
}
示例:动态注册事件监听器
EventListener<ChangeBlockEvent.All> listener = new ExampleListener();
EventListenerRegistration registeration = EventListenerRegistration
.builder(ChangeBlockEvent.All.class)
.listener(listener)
.plugin(pluginContainer)
.build();
Sponge.eventManager().registerListener(registeration);
小技巧
通过 @Listener
注解注册的监听器可自行决定其执行顺序(参见 关于 @Listener 部分的内容)。对于动态注册的事件监听器,可通过向 EventManager#registerListener
传入第三个参数 Order
来实现一样的效果。
取消注册事件监听器
你可以通过使用 EventManager#unregisterListeners(Object) 方法来去取消一个事件监听器的注册,该方法接受一个事件监听器类的实例作为参数。
EventListener listener = ...;
Sponge.getEventManager().unregisterListeners(listener);
或者,你可以通过传入一个插件的引用,调用 EventManager#unregisterPluginListeners(Object) 方法来取消掉所有该插件注册的事件监听器。请务必注意这个方法会移除 所有 此插件的事件监听器,包括那些用 @Listener
注册的监听器。
PluginContainer plugin = ...;
Sponge.eventManager().unregisterListeners(plugin);
关于 @Listener
注解 @Listener
有若干个可配置的字段:
order
用于设置事件监听器的执行优先级。参见 SpongeAPI 中 Order 这一枚举以获取可能的order
选项。beforeModifications
指定事件监听器是否在服务端 Mod ,如 Forge Mod 之前执行,默认为 false 。
默认情况下, @Listener
将会被配置成当事件是可取消而且已被(例如另一个插件)取消时,你的事件监听器 不 会被执行。
RefreshGameEvent
To prevent all plugins providing their own reload commands, Sponge provides a built-in callback for plugins to listen
to, and when executed, perform any refresh actions. What constitutes as a ‘refresh action’ is purely up to the
plugin to decide. The RefreshGameEvent will fire when a player executes the
/sponge plugins refresh
command. The event is not necessarily limited to reloading configuration.
import org.spongepowered.api.event.lifecycle.RefreshGameEvent;
@Listener
public void refresh(GameRefreshEvent event) {
// Do refresh stuff
}
注意这和一般理解上的“重新加载”不同,这个事件仅仅是用于插件的回调,实际上其他的什么事情都没有做。
发布事件
为了调度一个事件,你需要一个实现了 Event 接口的对象。
你可以通过事件总线( EventManager )触发事件:
boolean cancelled = Sponge.eventManager().post(theEventObject);
如果该事件被取消,则返回 true
,否则为 false
。