Skip to content

Commit

Permalink
#1381 Fix issue with yield existing flags and multi-term observers
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens authored Sep 27, 2024
1 parent 2e5365d commit 5abfb06
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 1 deletion.
1 change: 1 addition & 0 deletions distr/flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -14759,6 +14759,7 @@ int flecs_multi_observer_init(
child_desc.run_ctx = NULL;
child_desc.run_ctx_free = NULL;
child_desc.yield_existing = false;
child_desc.flags_ &= ~(EcsObserverYieldOnCreate|EcsObserverYieldOnDelete);
ecs_os_zeromem(&child_desc.entity);
ecs_os_zeromem(&child_desc.query.terms);
ecs_os_zeromem(&child_desc.query);
Expand Down
1 change: 1 addition & 0 deletions src/observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,7 @@ int flecs_multi_observer_init(
child_desc.run_ctx = NULL;
child_desc.run_ctx_free = NULL;
child_desc.yield_existing = false;
child_desc.flags_ &= ~(EcsObserverYieldOnCreate|EcsObserverYieldOnDelete);
ecs_os_zeromem(&child_desc.entity);
ecs_os_zeromem(&child_desc.query.terms);
ecs_os_zeromem(&child_desc.query);
Expand Down
3 changes: 3 additions & 0 deletions test/core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,9 @@
"on_add_remove_yield_existing_flags",
"on_add_remove_no_on_add_yield_existing",
"on_add_remove_no_on_remove_yield_existing",
"yield_existing_flags_w_multi_observer",
"yield_on_create_without_on_add",
"yield_on_delete_without_on_remove",
"observer_superset_wildcard",
"observer_superset_wildcard_add_isa",
"observer_superset_wildcard_add_isa_at_offset",
Expand Down
148 changes: 148 additions & 0 deletions test/core/src/Observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -4331,6 +4331,154 @@ void Observer_on_add_remove_no_on_remove_yield_existing(void) {
ecs_fini(world);
}

void Observer_yield_existing_flags_w_multi_observer(void) {
ecs_world_t *world = ecs_mini();

ECS_TAG(world, TagA);
ECS_TAG(world, TagB);

/* Create entities before trigger */
ecs_entity_t e1 = ecs_new_w(world, TagA);
ecs_add(world, e1, TagB);
ecs_entity_t e2 = ecs_new_w(world, TagA);
ecs_add(world, e2, TagB);
ecs_entity_t e3 = ecs_new_w(world, TagA);
ecs_add(world, e3, TagB);

test_assert(e1 != 0);
test_assert(e2 != 0);
test_assert(e3 != 0);

Probe ctx = {0};
ecs_entity_t t = ecs_observer_init(world, &(ecs_observer_desc_t){
.query.terms = {{ TagA }, { TagB }},
.events = {EcsOnAdd, EcsOnRemove},
.callback = Observer,
.ctx = &ctx,
.flags_ = EcsObserverYieldOnCreate|EcsObserverYieldOnDelete
});

test_int(ctx.invoked, 1);
test_int(ctx.count, 3);
test_int(ctx.system, t);
test_int(ctx.event, EcsOnAdd);
test_int(ctx.term_count, 2);
test_null(ctx.param);

test_int(ctx.e[0], e1);
test_int(ctx.e[1], e2);
test_int(ctx.e[2], e3);
test_int(ctx.c[0][0], TagA);
test_int(ctx.c[0][1], TagB);

ecs_os_zeromem(&ctx);

ecs_delete(world, t);

test_int(ctx.invoked, 1);
test_int(ctx.count, 3);
test_int(ctx.system, t);
test_int(ctx.event, EcsOnRemove);
test_int(ctx.term_count, 2);
test_null(ctx.param);

test_int(ctx.e[0], e1);
test_int(ctx.e[1], e2);
test_int(ctx.e[2], e3);
test_int(ctx.c[0][0], TagA);
test_int(ctx.c[0][1], TagB);

ecs_fini(world);
}

void Observer_yield_on_create_without_on_add(void) {
ecs_world_t *world = ecs_mini();

ECS_TAG(world, Tag);

/* Create entities before trigger */
ecs_entity_t e1 = ecs_new_w(world, Tag);
ecs_entity_t e2 = ecs_new_w(world, Tag);
ecs_entity_t e3 = ecs_new_w(world, Tag);

test_assert(e1 != 0);
test_assert(e2 != 0);
test_assert(e3 != 0);

Probe ctx = {0};
ecs_entity_t t = ecs_observer_init(world, &(ecs_observer_desc_t){
.query.terms = {{ Tag }},
.events = {EcsOnRemove},
.callback = Observer,
.ctx = &ctx,
.flags_ = EcsObserverYieldOnCreate|EcsObserverYieldOnDelete
});

test_int(ctx.invoked, 0);

ecs_delete(world, t);

test_int(ctx.invoked, 1);
test_int(ctx.count, 3);
test_int(ctx.system, t);
test_int(ctx.event, EcsOnRemove);
test_int(ctx.event_id, Tag);
test_int(ctx.term_count, 1);
test_null(ctx.param);

test_int(ctx.e[0], e1);
test_int(ctx.e[1], e2);
test_int(ctx.e[2], e3);
test_int(ctx.c[0][0], Tag);

ecs_fini(world);
}

void Observer_yield_on_delete_without_on_remove(void) {
ecs_world_t *world = ecs_mini();

ECS_TAG(world, Tag);

/* Create entities before trigger */
ecs_entity_t e1 = ecs_new_w(world, Tag);
ecs_entity_t e2 = ecs_new_w(world, Tag);
ecs_entity_t e3 = ecs_new_w(world, Tag);

test_assert(e1 != 0);
test_assert(e2 != 0);
test_assert(e3 != 0);

Probe ctx = {0};
ecs_entity_t t = ecs_observer_init(world, &(ecs_observer_desc_t){
.query.terms = {{ Tag }},
.events = {EcsOnAdd},
.callback = Observer,
.ctx = &ctx,
.flags_ = EcsObserverYieldOnCreate|EcsObserverYieldOnDelete
});

test_int(ctx.invoked, 1);
test_int(ctx.count, 3);
test_int(ctx.system, t);
test_int(ctx.event, EcsOnAdd);
test_int(ctx.event_id, Tag);
test_int(ctx.term_count, 1);
test_null(ctx.param);

test_int(ctx.e[0], e1);
test_int(ctx.e[1], e2);
test_int(ctx.e[2], e3);
test_int(ctx.c[0][0], Tag);

ecs_os_zeromem(&ctx);

ecs_delete(world, t);

test_int(ctx.invoked, 0);

ecs_fini(world);
}

void Observer_observer_superset_wildcard(void) {
ecs_world_t *world = ecs_mini();

Expand Down
17 changes: 16 additions & 1 deletion test/core/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,9 @@ void Observer_on_add_remove_yield_existing(void);
void Observer_on_add_remove_yield_existing_flags(void);
void Observer_on_add_remove_no_on_add_yield_existing(void);
void Observer_on_add_remove_no_on_remove_yield_existing(void);
void Observer_yield_existing_flags_w_multi_observer(void);
void Observer_yield_on_create_without_on_add(void);
void Observer_yield_on_delete_without_on_remove(void);
void Observer_observer_superset_wildcard(void);
void Observer_observer_superset_wildcard_add_isa(void);
void Observer_observer_superset_wildcard_add_isa_at_offset(void);
Expand Down Expand Up @@ -7949,6 +7952,18 @@ bake_test_case Observer_testcases[] = {
"on_add_remove_no_on_remove_yield_existing",
Observer_on_add_remove_no_on_remove_yield_existing
},
{
"yield_existing_flags_w_multi_observer",
Observer_yield_existing_flags_w_multi_observer
},
{
"yield_on_create_without_on_add",
Observer_yield_on_create_without_on_add
},
{
"yield_on_delete_without_on_remove",
Observer_yield_on_delete_without_on_remove
},
{
"observer_superset_wildcard",
Observer_observer_superset_wildcard
Expand Down Expand Up @@ -11180,7 +11195,7 @@ static bake_test_suite suites[] = {
"Observer",
NULL,
NULL,
219,
222,
Observer_testcases
},
{
Expand Down

0 comments on commit 5abfb06

Please sign in to comment.