Files
dusk/.claude/events.md
T
2026-06-16 10:15:59 -05:00

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.
  • eventInvoke is 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, onReleased per action
  • Any engine subsystem that exposes hooks (network connect/disconnect, asset batch completion, etc.)