103 lines
2.4 KiB
Markdown
103 lines
2.4 KiB
Markdown
# 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
|
|
|
|
```c
|
|
typedef void (*eventcallback_t)(void *params, void *user);
|
|
|
|
typedef struct {
|
|
eventcallback_t *callbacks;
|
|
void **users;
|
|
size_t size;
|
|
uint32_t count;
|
|
} event_t;
|
|
```
|
|
|
|
### Initialise
|
|
|
|
```c
|
|
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
|
|
|
|
```c
|
|
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
|
|
|
|
```c
|
|
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:
|
|
|
|
```c
|
|
#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.)
|