事件监听器

要监听一个事件,必须要注册一个事件监听器。方法是创建一个方法,方法名任意,将方法的第一个参数定义为目标事件类型,然后给该方法附上 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