Event
ll/api/event/ Β· Common / Server / Client
Overview
The Event module provides a publish-subscribe event system. It includes an event bus singleton, typed listeners with priority control, cancellable events, and a comprehensive set of built-in events for player actions, world changes, entities, server lifecycle, commands, and client-specific events.
| Header |
Description |
ll/api/event/EventBus.h |
Singleton event dispatcher |
ll/api/event/Event.h |
Base event class |
ll/api/event/EventId.h |
Event type identification |
ll/api/event/Listener.h |
Typed event listener |
ll/api/event/ListenerBase.h |
Base listener with priority |
ll/api/event/Cancellable.h |
Cancellable event mixin |
ll/api/event/Emitter.h |
Event emitter base |
ll/api/event/DynamicListener.h |
Runtime listener creation |
ll/api/event/MultiListener.h |
Listen to multiple event types |
Key Classes
EventBus
Singleton event dispatcher. All event publishing and subscription goes through this.
| 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();
// Publish an event
template <class T> void publish(T&& event);
template <class T> void publish(std::string_view modName, T&& event);
// Add/remove listeners
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);
// Convenience: create and add in one call
template <class T, class L = Listener<T>, class... Args>
auto emplaceListener(Args&&... args);
// Query
template <class T> size_t getListenerCount();
bool hasEvent(EventIdView const& eventId) const;
bool hasListener(ListenerId id) const;
// Set emitter factory
template <class T> bool setEventEmitter(FactoryFn fn, std::weak_ptr<mod::Mod> mod);
};
}
|
Event
Abstract base class for all events.
| 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>
Typed listener bound to a specific event type.
| 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++ |
|---|
| enum class EventPriority {
Highest = 0,
High = 100,
Normal = 200,
Low = 300,
Lowest = 400,
};
|
Cancellable\<T>
Mixin template to make an event cancellable.
| C++ |
|---|
| namespace ll::event {
template <class T>
class Cancellable : public T {
public:
bool isCancelled();
void setCancelled(bool cancelled);
void cancel();
};
}
|
Built-in Events
Player Events [Common]
| Event |
Description |
Cancellable |
PlayerJoinEvent |
Player joins the server |
No |
PlayerDisconnectEvent |
Player disconnects |
No |
PlayerChatEvent |
Player sends a chat message |
Yes |
PlayerAttackEvent |
Player attacks an entity |
Yes |
PlayerDestroyBlockEvent |
Player destroys a block |
Yes |
PlayerPlaceBlockEvent |
Player places a block |
Yes |
PlayerInteractBlockEvent |
Player interacts with a block |
Yes |
PlayerUseItemEvent |
Player uses an item |
Yes |
PlayerSwingEvent |
Player swings arm |
No |
PlayerJumpEvent |
Player jumps |
No |
PlayerSneakEvent |
Player starts/stops sneaking |
No |
PlayerSprintEvent |
Player starts/stops sprinting |
No |
PlayerPickUpItemEvent |
Player picks up an item |
Yes |
PlayerRespawnEvent |
Player respawns |
No |
PlayerDieEvent |
Player dies |
No |
PlayerChangePermEvent |
Player permission level changes |
No |
PlayerAddExperienceEvent |
Player gains experience |
No |
Entity Events [Common]
| Event |
Description |
Cancellable |
ActorHurtEvent |
An actor takes damage |
Yes |
MobDieEvent |
A mob dies |
No |
World Events [Common]
| Event |
Description |
Cancellable |
LevelTickEvent |
Each server tick |
No |
SpawnMobEvent |
A mob spawns |
Yes |
BlockChangedEvent |
A block changes |
No |
FireSpreadEvent |
Fire spreads |
Yes |
Server Events [Common]
| Event |
Description |
Cancellable |
ServerStartedEvent |
Server has started |
No |
ServerStoppingEvent |
Server is stopping |
No |
Command Events [Common]
| Event |
Description |
Cancellable |
ExecuteCommandEvent |
A command is executed |
Yes |
Service Events [Common]
| Event |
Description |
Cancellable |
ServiceRegisterEvent |
A service is registered |
No |
ServiceUnregisterEvent |
A service is unregistered |
No |
Client Events [Client Only]
| Event |
Description |
Cancellable |
ClientJoinLevelEvent |
Client joins a level |
No |
ClientExitLevelEvent |
Client exits a level |
No |
ClientStartJoinLevelEvent |
Client starts joining a level |
No |
ClientCancelJoinLevelEvent |
Client cancels level join |
No |
KeyInputEvent |
Keyboard input |
Yes |
MouseInputEvent |
Mouse input |
Yes |
BeforeUIRenderEvent |
Before UI rendering |
No |
AfterUIRenderEvent |
After UI rendering |
No |
Usage
Listening to an Event
| 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) {
// Handle player join
}
);
}
|
Listening with Priority
| 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) {
// This runs before Normal priority listeners
},
ll::event::EventPriority::High
);
}
|
Cancelling an 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 blockBadWords() {
auto& bus = ll::event::EventBus::getInstance();
bus.emplaceListener<ll::event::PlayerChatEvent>(
[](ll::event::PlayerChatEvent& event) {
// Cancel the event to prevent the chat message
event.cancel();
}
);
}
|
Removing a Listener
| 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&) {
// One-time setup
}
);
// Later, remove the listener
bus.removeListener(listener);
}
|
Publishing a Custom Event
| 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. Define the event (must be 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. Publish it
void fireEvent() {
MyCustomEvent event{"hello"};
ll::event::EventBus::getInstance().publish(event);
}
// 3. Listen to it
void listenCustom() {
ll::event::EventBus::getInstance().emplaceListener<MyCustomEvent>(
[](MyCustomEvent& event) {
// event.data() == "hello"
}
);
}
|
MultiListener
Listen to multiple event types with a single callback:
| 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) {
// Called for both join and disconnect
});
ll::event::EventBus::getInstance().addListener(listener);
}
|
- Server events (
ServerStartedEvent, ServerStoppingEvent): Available on both server and client builds, but only fire on the server side.
- Client events (
ClientJoinLevelEvent, KeyInputEvent, MouseInputEvent, render events): Only available in client builds (src-client/ll/api/event/).