跳到正文
本頁目錄

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++
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++
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++
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++
enum class EventPriority {
    Highest = 0,
    High    = 100,
    Normal  = 200,
    Low     = 300,
    Lowest  = 400,
};

Cancellable<T>

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

C++
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鼠標輸入是
BeforeUIRenderEventUI 渲染之前否
AfterUIRenderEventUI 渲染之後否

使用方法

監聽事件

C++
#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++
#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++
#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++
#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++
#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++
#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);
}

平臺說明

  • 服務器事件(ServerStartedEvent、ServerStoppingEvent):在服務端和客戶端構建中都可用,但僅在服務端觸發。
  • 客戶端事件(ClientJoinLevelEvent、KeyInputEvent、MouseInputEvent、渲染事件):僅在客戶端構建中可用(src-client/ll/api/event/)。

相關模塊