事件监听器

要监听一个事件,必须要注册一个事件监听器。方法是创建一个方法,方法名任意,将方法的第一个参数定义为目标事件类型,然后给该方法附上 Listener 注解,如下所示。

import org.spongepowered.api.event.Listener;

@Listener
public void onSomeEvent(SomeEvent event) {
    // Do something with the event
}

此外,包含这些方法的类必须在事件管理器注册:

小技巧

如果你的主类(即附有 Plugin 注解的类)有事件监听器,则你不需要注册事件对象,因为 Sponge 会自动执行此操作。

备注

The event bus supports supertypes. For example, ChangeBlockEvent.All extends ChangeBlockEvent. Therefore, a plugin could listen to ChangeBlockEvent and still receive ChangeBlockEvent.Alls. However, a plugin listening to just ChangeBlockEvent.All would not be notified of other types of ChangeBlockEvent.

注册或取消事件监听器

在插件主类之外,添加注解``@Listener``来对事件监听器进行注册,你可以通过使用 EventManager#registerListeners(Object, Object) 方法来注册这个事件监听器,该方法需要一个插件主类的引用以及事件监听类的实例。

示例:在其他类中注册事件监听器

import org.spongepowered.api.Sponge;

public class ExampleListener {

    @Listener
    public void onSomeEvent(SomeEvent event) {
        // Do something with the event
    }
}

Sponge.getEventManager().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();
Sponge.getEventManager().registerListener(this, ChangeBlockEvent.All.class, listener);

小技巧

通过 @Listener 注解注册的监听器可自行决定其执行顺序(参见 关于 @Listener 部分的内容)。对于动态注册的事件监听器,可通过向 EventManager#registerListener 传入第三个参数 Order 来实现一样的效果。

取消注册事件监听器

你可以通过使用 EventManager#unregisterListeners(Object) 方法来去取消一个事件监听器的注册,该方法接受一个事件监听器类的实例作为参数。

EventListener listener = ...;
Sponge.getEventManager().unregisterListeners(listener);

或者,你可以通过传入一个插件的引用,调用 EventManager#unregisterPluginListeners(Object) 方法来取消掉所有该插件注册的事件监听器。请务必注意这个方法会移除 所有 此插件的事件监听器,包括那些用 @Listener 注册的监听器。

PluginContainer plugin = ...;
Sponge.getEventManager().unregisterPluginListeners(plugin);

关于 @Listener

注解 @Listener 有若干个可配置的字段:

  • order 用于设置事件监听器的执行优先级。参见 SpongeAPI 中 Order 这一枚举以获取可能的 order 选项。

  • beforeModifications 指定事件监听器是否在服务端 Mod ,如 Forge Mod 之前执行,默认为 false 。

默认情况下, @Listener 将会被配置成当事件是可取消而且已被(例如另一个插件)取消时,你的事件监听器 会被执行。

GameRefreshEvent

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 GameRefreshEvent 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.GameRefreshEvent;

@Listener
public void refresh(GameRefreshEvent event) {
    // Do refresh stuff
}

注意这和一般理解上的“重新加载”不同,这个事件仅仅是用于插件的回调,实际上其他的什么事情都没有做。

发布事件

为了调度一个事件,你需要一个实现了 Event 接口的对象。

你可以通过事件总线( EventManager )触发事件:

boolean cancelled = Sponge.getEventManager().post(theEventObject);

如果该事件被取消,则返回 true ,否则为 false