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 | 鼠標輸入 | 是 |
BeforeUIRenderEvent | UI 渲染之前 | 否 |
AfterUIRenderEvent | UI 渲染之後 | 否 |
使用方法
監聽事件
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/)。
相關模塊
- 操作指南:事件 — 分步教程
- Input(輸入系統 · 客戶端) — 客戶端輸入事件詳情
- Service(服務系統) — 服務註冊/註銷事件