跳转至

Event(事件系统)

ll/api/event/ · 通用 / 服务端 / 客户端

概述

Event 模块提供了发布-订阅事件系统。包括事件总线单例、带优先级控制的类型化监听器、可取消事件,以及涵盖玩家操作、世界变化、实体、服务器生命周期、命令和客户端特定事件的全面内置事件集合。

头文件

头文件 说明
ll/api/event/EventBus.h 事件总线单例
ll/api/event/Event.h 事件基类
ll/api/event/EventId.h 事件类型标识
ll/api/event/Listener.h 类型化事件监听器
ll/api/event/ListenerBase.h 带优先级的监听器基类
ll/api/event/Cancellable.h 可取消事件混入
ll/api/event/Emitter.h 事件发射器基类
ll/api/event/DynamicListener.h 运行时监听器创建
ll/api/event/MultiListener.h 监听多种事件类型

核心类

EventBus

事件总线单例。所有事件的发布和订阅都通过它进行。

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace ll::event {
class EventBus {
public:
    static EventBus& getInstance();

    // 发布事件
    template <class T> void publish(T&& event);
    template <class T> void publish(std::string_view modName, T&& event);

    // 添加/移除监听器
    template <class T> bool addListener(std::shared_ptr<Listener<T>> const& listener);
    bool removeListener(ListenerPtr const& listener);
    template <class T> bool removeListener(ListenerPtr const& listener);

    // 便捷方法:创建并添加
    template <class T, class L = Listener<T>, class... Args>
    auto emplaceListener(Args&&... args);

    // 查询
    template <class T> size_t getListenerCount();
    bool hasEvent(EventIdView const& eventId) const;
    bool hasListener(ListenerId id) const;

    // 设置发射器工厂
    template <class T> bool setEventEmitter(FactoryFn fn, std::weak_ptr<mod::Mod> mod);
};
}

Event

所有事件的抽象基类。

C++
1
2
3
4
5
6
7
8
9
namespace ll::event {
class Event {
public:
    virtual ~Event();
    virtual void serialize(CompoundTag&) const;
    virtual void deserialize(CompoundTag const&);
    virtual EventId getId() const;
};
}

Listener\<T>

绑定到特定事件类型的类型化监听器。

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
namespace ll::event {
template <class T>
class Listener : public ListenerBase {
public:
    using event_type  = T;
    using callback_fn = std::function<void(event_type&)>;

    explicit Listener(callback_fn fn, EventPriority priority = EventPriority::Normal,
                      std::weak_ptr<mod::Mod> mod = mod::NativeMod::current());

    static std::shared_ptr<Listener> create(callback_fn fn, EventPriority priority = EventPriority::Normal,
                                             std::weak_ptr<mod::Mod> mod = mod::NativeMod::current());
};
}

EventPriority

C++
1
2
3
4
5
6
7
enum class EventPriority {
    Highest = 0,
    High    = 100,
    Normal  = 200,
    Low     = 300,
    Lowest  = 400,
};

Cancellable\<T>

使事件可取消的混入模板。

C++
1
2
3
4
5
6
7
8
9
namespace ll::event {
template <class T>
class Cancellable : public T {
public:
    bool isCancelled();
    void setCancelled(bool cancelled);
    void cancel();
};
}

内置事件

玩家事件 [通用]

事件 说明 可取消
PlayerJoinEvent 玩家加入服务器
PlayerDisconnectEvent 玩家断开连接
PlayerChatEvent 玩家发送聊天消息
PlayerAttackEvent 玩家攻击实体
PlayerDestroyBlockEvent 玩家破坏方块
PlayerPlaceBlockEvent 玩家放置方块
PlayerInteractBlockEvent 玩家与方块交互
PlayerUseItemEvent 玩家使用物品
PlayerSwingEvent 玩家挥手
PlayerJumpEvent 玩家跳跃
PlayerSneakEvent 玩家开始/停止潜行
PlayerSprintEvent 玩家开始/停止疾跑
PlayerPickUpItemEvent 玩家拾取物品
PlayerRespawnEvent 玩家重生
PlayerDieEvent 玩家死亡
PlayerChangePermEvent 玩家权限等级变更
PlayerAddExperienceEvent 玩家获得经验值

实体事件 [通用]

事件 说明 可取消
ActorHurtEvent 实体受到伤害
MobDieEvent 生物死亡

世界事件 [通用]

事件 说明 可取消
LevelTickEvent 每个服务器刻
SpawnMobEvent 生物生成
BlockChangedEvent 方块变化
FireSpreadEvent 火焰蔓延

服务器事件 [通用]

事件 说明 可取消
ServerStartedEvent 服务器已启动
ServerStoppingEvent 服务器正在停止

命令事件 [通用]

事件 说明 可取消
ExecuteCommandEvent 执行命令

服务事件 [通用]

事件 说明 可取消
ServiceRegisterEvent 服务被注册
ServiceUnregisterEvent 服务被注销

客户端事件 [仅客户端]

事件 说明 可取消
ClientJoinLevelEvent 客户端加入关卡
ClientExitLevelEvent 客户端退出关卡
ClientStartJoinLevelEvent 客户端开始加入关卡
ClientCancelJoinLevelEvent 客户端取消加入关卡
KeyInputEvent 键盘输入
MouseInputEvent 鼠标输入
BeforeUIRenderEvent UI 渲染之前
AfterUIRenderEvent UI 渲染之后

使用方法

监听事件

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#include "ll/api/event/EventBus.h"
#include "ll/api/event/player/PlayerJoinEvent.h"

void setupListeners() {
    auto& bus = ll::event::EventBus::getInstance();

    auto listener = bus.emplaceListener<ll::event::PlayerJoinEvent>(
        [](ll::event::PlayerJoinEvent& event) {
            // 处理玩家加入
        }
    );
}

带优先级监听

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include "ll/api/event/EventBus.h"
#include "ll/api/event/player/PlayerChatEvent.h"

void setupPriorityListener() {
    auto& bus = ll::event::EventBus::getInstance();

    bus.emplaceListener<ll::event::PlayerChatEvent>(
        [](ll::event::PlayerChatEvent& event) {
            // 在 Normal 优先级的监听器之前执行
        },
        ll::event::EventPriority::High
    );
}

取消事件

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include "ll/api/event/EventBus.h"
#include "ll/api/event/player/PlayerChatEvent.h"

void blockBadWords() {
    auto& bus = ll::event::EventBus::getInstance();

    bus.emplaceListener<ll::event::PlayerChatEvent>(
        [](ll::event::PlayerChatEvent& event) {
            // 取消事件以阻止聊天消息
            event.cancel();
        }
    );
}

移除监听器

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include "ll/api/event/EventBus.h"
#include "ll/api/event/server/ServerStartedEvent.h"

void setupAndRemove() {
    auto& bus = ll::event::EventBus::getInstance();

    auto listener = bus.emplaceListener<ll::event::ServerStartedEvent>(
        [](ll::event::ServerStartedEvent&) {
            // 一次性设置
        }
    );

    // 稍后,移除监听器
    bus.removeListener(listener);
}

发布自定义事件

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "ll/api/event/Event.h"
#include "ll/api/event/EventBus.h"

// 1. 定义事件(必须是 final)
class MyCustomEvent final : public ll::event::Event {
    std::string mData;
public:
    MyCustomEvent(std::string data) : mData(std::move(data)) {}
    std::string const& data() const { return mData; }
};

// 2. 发布
void fireEvent() {
    MyCustomEvent event{"hello"};
    ll::event::EventBus::getInstance().publish(event);
}

// 3. 监听
void listenCustom() {
    ll::event::EventBus::getInstance().emplaceListener<MyCustomEvent>(
        [](MyCustomEvent& event) {
            // event.data() == "hello"
        }
    );
}

MultiListener

用单个回调监听多种事件类型:

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include "ll/api/event/MultiListener.h"
#include "ll/api/event/player/PlayerJoinEvent.h"
#include "ll/api/event/player/PlayerDisconnectEvent.h"

void setupMulti() {
    auto listener = ll::event::MultiListener<
        ll::event::PlayerJoinEvent,
        ll::event::PlayerDisconnectEvent
    >::create([](auto&& event) {
        // 对加入和断开连接都会调用
    });

    ll::event::EventBus::getInstance().addListener(listener);
}

平台说明

  • 服务器事件ServerStartedEventServerStoppingEvent):在服务端和客户端构建中都可用,但仅在服务端触发。
  • 客户端事件ClientJoinLevelEventKeyInputEventMouseInputEvent、渲染事件):仅在客户端构建中可用(src-client/ll/api/event/)。

相关模块