diff --git a/distr/flecs.c b/distr/flecs.c index 875292213..d73c8cc9a 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -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); diff --git a/src/observer.c b/src/observer.c index 8465b3ae6..45faa18f6 100644 --- a/src/observer.c +++ b/src/observer.c @@ -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); diff --git a/test/core/project.json b/test/core/project.json index d93562be3..da0086ba1 100644 --- a/test/core/project.json +++ b/test/core/project.json @@ -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", diff --git a/test/core/src/Observer.c b/test/core/src/Observer.c index 736b4c63b..e447ec6e8 100644 --- a/test/core/src/Observer.c +++ b/test/core/src/Observer.c @@ -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(); diff --git a/test/core/src/main.c b/test/core/src/main.c index 2b82d02fc..760e7a9bb 100644 --- a/test/core/src/main.c +++ b/test/core/src/main.c @@ -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); @@ -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 @@ -11180,7 +11195,7 @@ static bake_test_suite suites[] = { "Observer", NULL, NULL, - 219, + 222, Observer_testcases }, {