Observers And Events
Observers run callbacks when an event is emitted for an entity matching a query.
Built-In Events
Section titled “Built-In Events”SIECS currently exposes three built-in events:
| Event | Trigger |
|---|---|
EcsOnAdd | A component is added to an entity. |
EcsOnRemove | A component is removed from an entity. |
EcsOnSet | A component value is set with ecs_set() or ecs_set_cid(). |
Create An Observer
Section titled “Create An Observer”static void on_position_set(ecs_observer_event_t *event) { const Position *value = event->trigger_data; (void)value;}
ecs_observer({ .on = EcsOnSet, .query = { .terms = { ecs_in(Position) } }, .callback = on_position_set,});ecs::observe<ecs::OnSet>().each([](const Position &position) { std::cout << position.x << '\n';});callback is required.
Observer queries follow the same matching rules as normal queries. Entities with
the built-in Disabled component do not trigger matching observers unless the
observer query mentions Disabled explicitly:
ecs_observer({
.on = EcsOnSet,
.query = {
.terms = { ecs_in(Position), ecs_filter(Disabled) },
},
.callback = on_disabled_position_set,
});#include <siecs.h>
ecs_observer({
.on = EcsOnSet,
.query = {
.terms = { ecs_in(Position), ecs_filter(Disabled) },
},
.callback = on_disabled_position_set,
});Observers are enabled by default. Use ecs_observer_disable() and
ecs_observer_enable() to toggle an observer without unregistering it.
Pass small callback context through user_data when needed:
ecs_observer({
.on = EcsOnSet,
.query.terms = { ecs_in(Position) },
.callback = on_position_set,
.user_data = (uintptr_t)counter_ptr,
});#include <siecs.h>
ecs_observer({
.on = EcsOnSet,
.query.terms = { ecs_in(Position) },
.callback = on_position_set,
.user_data = (uintptr_t)counter_ptr,
});Event Payload
Section titled “Event Payload”The callback receives ecs_observer_event_t:
typedef struct {
ecs_entity_t entity;
ecs_event_t event;
uintptr_t user_data;
const void *trigger_data;
} ecs_observer_event_t;#include <siecs.h>
typedef struct {
ecs_entity_t entity;
ecs_event_t event;
uintptr_t user_data;
const void *trigger_data;
} ecs_observer_event_t;trigger_data depends on the event:
| Event | trigger_data |
|---|---|
EcsOnAdd | Pointer to the added component storage. |
EcsOnRemove | Pointer to the component value before removal. |
EcsOnSet | Pointer to the new value passed to ecs_set() or ecs_set_cid(). |
| Custom event | Pointer passed to ecs_observer_trigger(). |
For OnSet, the stored component value has not been overwritten yet when hooks
and observers run.
Component hooks run before matching observers for the same operation.
Custom Events
Section titled “Custom Events”Create custom event ids with ecs_event():
ecs_event_t Damaged = ecs_event();
ecs_observer({
.on = Damaged,
.query = {
.terms = { ecs_in(Health) },
},
.callback = on_damaged,
});
Damage damage = { .amount = 10 };
ecs_observer_trigger(entity, Damaged, &damage);#include <siecs.h>
ecs_event_t Damaged = ecs_event();
ecs_observer({
.on = Damaged,
.query = {
.terms = { ecs_in(Health) },
},
.callback = on_damaged,
});
Damage damage = { .amount = 10 };
ecs_observer_trigger(entity, Damaged, &damage);