Files
PixelDefense/engine/libs/flecs/test/api/src/Event.c

582 lines
14 KiB
C

#include <api.h>
static
void system_callback(ecs_iter_t *it) {
probe_iter(it);
}
void Event_table_1_id_w_trigger(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id);
ecs_table_t *table = ecs_get_table(world, e);
Probe ctx = {0};
ecs_entity_t s = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms[0].id = id,
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 1, .array = (ecs_id_t[]){ id }},
.table = table,
.observable = world
});
test_int(ctx.invoked, 1);
test_assert(ctx.system == s);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
void Event_table_2_ids_w_trigger(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id_a = ecs_new_id(world);
ecs_entity_t id_b = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id_a);
ecs_add_id(world, e, id_b);
ecs_table_t *table = ecs_get_table(world, e);
Probe ctx = {0};
ecs_entity_t s_a = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms[0].id = id_a,
.events = {evt},
.callback = system_callback,
.ctx = &ctx,
});
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 2, .array = (ecs_id_t[]){ id_a, id_b }},
.table = table,
.observable = world
});
test_int(ctx.invoked, 1);
test_assert(ctx.system == s_a);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id_a);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_delete(world, s_a);
ecs_entity_t s_b = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms[0].id = id_b,
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_os_zeromem(&ctx);
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 2, .array = (ecs_id_t[]){ id_a, id_b }},
.table = table,
.observable = world
});
test_int(ctx.invoked, 1);
test_assert(ctx.system == s_b);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id_b);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
void Event_table_1_id_w_observer(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id);
ecs_table_t *table = ecs_get_table(world, e);
Probe ctx = {0};
ecs_entity_t s = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms = {{ id }},
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 1, .array = (ecs_id_t[]){ id }},
.table = table,
.observable = world
});
test_int(ctx.invoked, 1);
test_assert(ctx.system == s);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
void Event_table_2_ids_w_observer(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id_a = ecs_new_id(world);
ecs_entity_t id_b = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id_a);
ecs_add_id(world, e, id_b);
ecs_table_t *table = ecs_get_table(world, e);
Probe ctx = {0};
ecs_entity_t s_a = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms = {{ id_a }},
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 2, .array = (ecs_id_t[]){ id_a, id_b }},
.table = table,
.observable = world
});
test_int(ctx.invoked, 1);
test_assert(ctx.system == s_a);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id_a || ctx.event_id == id_b);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
static int empty_table_callback_invoked = 0;
static
void empty_table_callback(ecs_iter_t *it) {
test_assert(it->table == it->ctx);
test_int(it->count, 0);
empty_table_callback_invoked++;
}
void Event_emit_event_for_empty_table(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, TagA);
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t e = ecs_new(world, TagA);
ecs_table_t *table = ecs_get_table(world, e);
ecs_delete(world, e);
ecs_entity_t o = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms = {{ TagA }},
.events = {evt},
.callback = empty_table_callback,
.ctx = table
});
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 1, .array = (ecs_id_t[]){ TagA }},
.table = table,
.observable = world
});
test_int(empty_table_callback_invoked, 1);
ecs_delete(world, o);
ecs_fini(world);
}
void Event_emit_table_event(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, TagA);
ecs_entity_t base = ecs_new_w_id(world, TagA);
ecs_table_t *base_table = ecs_get_table(world, base);
ecs_entity_t e = ecs_new_id(world);
ecs_add_pair(world, e, EcsIsA, base);
Probe ctx_a = {0};
Probe ctx_b = {0};
ecs_entity_t evt = ecs_new_id(world);
ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms[0].id = TagA,
.filter.terms[0].src.flags = EcsSelf,
.events = {evt},
.callback = system_callback,
.ctx = &ctx_a
});
ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms[0].id = TagA,
.filter.terms[0].src.flags = EcsUp,
.events = {evt},
.callback = system_callback,
.ctx = &ctx_b
});
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.array = (ecs_id_t[]){ TagA }, .count = 1},
.table = base_table,
.observable = world
});
test_int(ctx_a.invoked, 1);
test_int(ctx_b.invoked, 1);
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.array = (ecs_id_t[]){ TagA }, .count = 1},
.table = base_table,
.observable = world,
.flags = EcsEventTableOnly
});
test_int(ctx_a.invoked, 2);
test_int(ctx_b.invoked, 1);
ecs_fini(world);
}
void Event_emit_staged_from_world(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id);
ecs_table_t *table = ecs_get_table(world, e);
Probe ctx = {0};
ecs_entity_t s = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms[0].id = id,
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_readonly_begin(world);
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 1, .array = (ecs_id_t[]){ id }},
.table = table,
.observable = world
});
ecs_readonly_end(world);
test_int(ctx.invoked, 1);
test_assert(ctx.system == s);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
void Event_emit_staged_from_stage(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id);
ecs_table_t *table = ecs_get_table(world, e);
Probe ctx = {0};
ecs_entity_t s = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms[0].id = id,
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_readonly_begin(world);
ecs_world_t *stage = ecs_get_stage(world, 0);
ecs_emit(stage, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 1, .array = (ecs_id_t[]){ id }},
.table = table,
.observable = world
});
ecs_readonly_end(world);
test_int(ctx.invoked, 1);
test_assert(ctx.system == s);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
void Event_emit_staged_from_world_observer(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id);
ecs_table_t *table = ecs_get_table(world, e);
Probe ctx = {0};
ecs_entity_t s = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms = {{ id }},
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_readonly_begin(world);
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 1, .array = (ecs_id_t[]){ id }},
.table = table,
.observable = world
});
ecs_readonly_end(world);
test_int(ctx.invoked, 1);
test_assert(ctx.system == s);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
void Event_emit_staged_from_stage_observer(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id);
ecs_table_t *table = ecs_get_table(world, e);
Probe ctx = {0};
ecs_entity_t s = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms = {{ id }},
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_readonly_begin(world);
ecs_world_t *stage = ecs_get_stage(world, 0);
ecs_emit(stage, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 1, .array = (ecs_id_t[]){ id }},
.table = table,
.observable = world
});
ecs_readonly_end(world);
test_int(ctx.invoked, 1);
test_assert(ctx.system == s);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
void Event_emit_for_entity(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t evt = ecs_new_id(world);
ecs_entity_t id = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, id);
Probe ctx = {0};
ecs_entity_t s = ecs_observer_init(world, &(ecs_observer_desc_t){
.filter.terms[0].id = id,
.events = {evt},
.callback = system_callback,
.ctx = &ctx
});
ecs_emit(world, &(ecs_event_desc_t){
.event = evt,
.ids = &(ecs_type_t){.count = 1, .array = (ecs_id_t[]){ id }},
.entity = e
});
test_int(ctx.invoked, 1);
test_assert(ctx.system == s);
test_assert(ctx.event == evt);
test_assert(ctx.event_id == id);
test_int(ctx.count, 1);
test_assert(ctx.e[0] == e);
ecs_fini(world);
}
static int ObserverA_invoked = false;
static void ObserverA(ecs_iter_t *it) {
ObserverA_invoked ++;
}
static int ObserverB_invoked = false;
static void ObserverB(ecs_iter_t *it) {
ObserverB_invoked ++;
}
void Event_emit_custom_for_any(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, Tag);
ecs_entity_t MyEvent = ecs_new_id(world);
ecs_entity_t e1 = ecs_new(world, Tag);
ecs_entity_t e2 = ecs_new(world, Tag);
ecs_observer(world, {
.filter.terms = {{ .id = EcsAny, .src.id = e1 }},
.events = {MyEvent},
.callback = ObserverA
});
ecs_observer(world, {
.filter.terms = {{ .id = EcsAny, .src.id = e2 }},
.events = {MyEvent},
.callback = ObserverB
});
ecs_emit(world, &(ecs_event_desc_t) {
.ids = &(ecs_type_t){ .count = 1, .array = (ecs_id_t[]){ EcsAny } },
.entity = e1,
.event = MyEvent
});
test_int(ObserverA_invoked, 1);
test_int(ObserverB_invoked, 0);
ecs_emit(world, &(ecs_event_desc_t) {
.ids = &(ecs_type_t){ .count = 1, .array = (ecs_id_t[]){ EcsAny } },
.entity = e2,
.event = MyEvent
});
test_int(ObserverA_invoked, 1);
test_int(ObserverB_invoked, 1);
ecs_fini(world);
}
void Event_emit_custom_implicit_any(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, Tag);
ecs_entity_t MyEvent = ecs_new_id(world);
ecs_entity_t e1 = ecs_new(world, Tag);
ecs_entity_t e2 = ecs_new(world, Tag);
ecs_observer(world, {
.filter.terms = {{ .id = EcsAny, .src.id = e1 }},
.events = {MyEvent},
.callback = ObserverA
});
ecs_observer(world, {
.filter.terms = {{ .id = EcsAny, .src.id = e2 }},
.events = {MyEvent},
.callback = ObserverB
});
ecs_emit(world, &(ecs_event_desc_t) {
.entity = e1,
.event = MyEvent
});
test_int(ObserverA_invoked, 1);
test_int(ObserverB_invoked, 0);
ecs_emit(world, &(ecs_event_desc_t) {
.entity = e2,
.event = MyEvent
});
test_int(ObserverA_invoked, 1);
test_int(ObserverB_invoked, 1);
ecs_fini(world);
}
void Event_emit_custom_empty_type(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, Tag);
ecs_entity_t MyEvent = ecs_new_id(world);
ecs_entity_t e1 = ecs_new(world, Tag);
ecs_entity_t e2 = ecs_new(world, Tag);
ecs_observer(world, {
.filter.terms = {{ .id = EcsAny, .src.id = e1 }},
.events = {MyEvent},
.callback = ObserverA
});
ecs_observer(world, {
.filter.terms = {{ .id = EcsAny, .src.id = e2 }},
.events = {MyEvent},
.callback = ObserverB
});
ecs_emit(world, &(ecs_event_desc_t) {
.ids = &(ecs_type_t){ .count = 0 },
.entity = e1,
.event = MyEvent
});
test_int(ObserverA_invoked, 1);
test_int(ObserverB_invoked, 0);
ecs_emit(world, &(ecs_event_desc_t) {
.ids = &(ecs_type_t){ .count = 0 },
.entity = e2,
.event = MyEvent
});
test_int(ObserverA_invoked, 1);
test_int(ObserverB_invoked, 1);
ecs_fini(world);
}