2.4 KiB
Event System
Source: src/dusk/event/
Overview
The event system is a simple publish-subscribe mechanism backed by caller-owned static arrays. There is no heap allocation in the event system itself -- the caller provides the backing storage.
API
typedef void (*eventcallback_t)(void *params, void *user);
typedef struct {
eventcallback_t *callbacks;
void **users;
size_t size;
uint32_t count;
} event_t;
Initialise
void eventInit(
event_t *event,
eventcallback_t *callbacks,
void **users,
size_t size
);
callbacks and users are caller-owned arrays of length size. Both
are zeroed by eventInit. users may be NULL if no subscriber needs
a user pointer.
Subscribe / unsubscribe
void eventSubscribe(event_t *event, eventcallback_t callback, void *user);
void eventUnsubscribe(event_t *event, eventcallback_t callback);
The same (callback, user) pair may only be subscribed once --
eventSubscribe asserts on a duplicate. eventUnsubscribe is a no-op
if the pair is not found. Unsubscribing uses swap-with-last to keep the
array packed; ordering is not preserved.
Fire
void eventInvoke(const event_t *event, void *params);
Calls every subscriber in registration order, passing params and
each subscriber's user pointer.
Usage pattern
Declare the backing arrays alongside the event struct, typically as struct fields or static variables:
#define MY_EVENT_CAPACITY 4
typedef struct {
event_t onComplete;
eventcallback_t _completeCbs[MY_EVENT_CAPACITY];
void *_completeUsers[MY_EVENT_CAPACITY];
} mystate_t;
// Init:
eventInit(
&state.onComplete,
state._completeCbs,
state._completeUsers,
MY_EVENT_CAPACITY
);
// Publish:
eventInvoke(&state.onComplete, &someParams);
// Subscribe from outside:
eventSubscribe(&state.onComplete, myHandler, myUserPtr);
Constraints
- Capacity is fixed at init time. Exceeding it is a runtime assertion.
- Subscriber order is not stable after an unsubscribe.
eventInvokeis synchronous -- all callbacks run on the calling thread before it returns.- Do not subscribe or unsubscribe from inside a callback -- the array may shift during iteration.
Where events are used
inputactiondata_t:onPressed,onReleasedper action- Any engine subsystem that exposes hooks (network connect/disconnect, asset batch completion, etc.)