diff --git a/distr/flecs.c b/distr/flecs.c index e7f0caddfd..067111a231 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -14925,10 +14925,19 @@ void flecs_register_observer_for_id( ecs_term_t *term = &o->query->terms[0]; ecs_entity_t trav = term->trav; - int i; + int i, j; for (i = 0; i < o->event_count; i ++) { ecs_entity_t event = flecs_get_observer_event( term, o->events[i]); + for (j = 0; j < i; j ++) { + if (event == flecs_get_observer_event(term, o->events[j])) { + break; + } + } + if (i != j) { + /* Duplicate event, ignore */ + continue; + } /* Get observers for event */ ecs_event_record_t *er = flecs_event_record_ensure(observable, event); @@ -14985,10 +14994,19 @@ void flecs_unregister_observer_for_id( ecs_term_t *term = &o->query->terms[0]; ecs_entity_t trav = term->trav; - int i; + int i, j; for (i = 0; i < o->event_count; i ++) { ecs_entity_t event = flecs_get_observer_event( term, o->events[i]); + for (j = 0; j < i; j ++) { + if (event == flecs_get_observer_event(term, o->events[j])) { + break; + } + } + if (i != j) { + /* Duplicate event, ignore */ + continue; + } /* Get observers for event */ ecs_event_record_t *er = flecs_event_record_get(observable, event); diff --git a/src/observer.c b/src/observer.c index 9851b39db7..8e9b6bf691 100644 --- a/src/observer.c +++ b/src/observer.c @@ -130,10 +130,19 @@ void flecs_register_observer_for_id( ecs_term_t *term = &o->query->terms[0]; ecs_entity_t trav = term->trav; - int i; + int i, j; for (i = 0; i < o->event_count; i ++) { ecs_entity_t event = flecs_get_observer_event( term, o->events[i]); + for (j = 0; j < i; j ++) { + if (event == flecs_get_observer_event(term, o->events[j])) { + break; + } + } + if (i != j) { + /* Duplicate event, ignore */ + continue; + } /* Get observers for event */ ecs_event_record_t *er = flecs_event_record_ensure(observable, event); @@ -190,10 +199,19 @@ void flecs_unregister_observer_for_id( ecs_term_t *term = &o->query->terms[0]; ecs_entity_t trav = term->trav; - int i; + int i, j; for (i = 0; i < o->event_count; i ++) { ecs_entity_t event = flecs_get_observer_event( term, o->events[i]); + for (j = 0; j < i; j ++) { + if (event == flecs_get_observer_event(term, o->events[j])) { + break; + } + } + if (i != j) { + /* Duplicate event, ignore */ + continue; + } /* Get observers for event */ ecs_event_record_t *er = flecs_event_record_get(observable, event); diff --git a/test/core/project.json b/test/core/project.json index 260f13c038..35f5929962 100644 --- a/test/core/project.json +++ b/test/core/project.json @@ -1695,7 +1695,6 @@ "forward_up_flag_term_2", "propagate_up_flag_term_1", "propagate_up_flag_term_2", - "propagate_on_set_self_up", "row_flag_term_1", "row_flag_term_2", "on_add_optional", @@ -1712,6 +1711,8 @@ "on_table_create_is_deferred", "on_table_create_is_deferred_batched", "2_children_w_deferred_set", + "on_add_on_set_w_not_term", + "on_add_on_set_w_not_2_terms", "cache_test_1", "cache_test_2", "cache_test_3", diff --git a/test/core/src/Observer.c b/test/core/src/Observer.c index 071a663422..1a37df5da3 100644 --- a/test/core/src/Observer.c +++ b/test/core/src/Observer.c @@ -9975,3 +9975,88 @@ void Observer_2_children_w_deferred_set(void) { ecs_fini(world); } + +void Observer_on_add_on_set_w_not_term(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + + Probe ctx = {0}; + + ecs_entity_t o = ecs_observer(world, { + .query.terms = {{ ecs_id(Position), .oper = EcsNot }}, + .events = { EcsOnAdd, EcsOnSet }, + .callback = Observer_w_value_1, + .ctx = &ctx + }); + + ecs_entity_t e = ecs_insert(world, ecs_value(Position, {10, 20})); + test_int(ctx.invoked, 0); + + ecs_remove(world, e, Position); + test_int(ctx.invoked, 1); + test_int(ctx.count, 1); + test_int(ctx.system, o); + test_int(ctx.event, EcsOnAdd); + test_uint(ctx.e[0], e); + test_uint(ctx.s[0][0], 0); + + ecs_fini(world); +} + +void Observer_on_add_on_set_w_not_2_terms(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + ECS_COMPONENT(world, Velocity); + + Probe ctx = {0}; + + ecs_entity_t o = ecs_observer(world, { + .query.terms = {{ ecs_id(Position) }, { ecs_id(Velocity), .oper = EcsNot }}, + .events = { EcsOnAdd, EcsOnSet }, + .callback = Observer, + .ctx = &ctx + }); + + ecs_entity_t e = ecs_new_w(world, Position); + test_int(ctx.invoked, 1); + test_int(ctx.count, 1); + test_int(ctx.system, o); + test_int(ctx.event, EcsOnAdd); + test_uint(ctx.e[0], e); + test_uint(ctx.s[0][0], 0); + + ecs_os_zeromem(&ctx); + + ecs_set(world, e, Position, {10, 20}); + test_int(ctx.invoked, 1); + test_int(ctx.count, 1); + test_int(ctx.system, o); + test_int(ctx.event, EcsOnSet); + test_uint(ctx.e[0], e); + test_uint(ctx.s[0][0], 0); + + ecs_os_zeromem(&ctx); + + ecs_add(world, e, Velocity); + test_int(ctx.invoked, 0); + + ecs_set(world, e, Position, {20, 30}); + test_int(ctx.invoked, 0); + + ecs_remove(world, e, Velocity); + test_int(ctx.invoked, 1); + test_int(ctx.count, 1); + test_int(ctx.system, o); + test_int(ctx.event, EcsOnAdd); + test_uint(ctx.e[0], e); + test_uint(ctx.s[0][0], 0); + + ecs_os_zeromem(&ctx); + + ecs_remove(world, e, Position); + test_int(ctx.invoked, 0); + + ecs_fini(world); +} diff --git a/test/core/src/main.c b/test/core/src/main.c index 90e304f1a7..5d50cfd50c 100644 --- a/test/core/src/main.c +++ b/test/core/src/main.c @@ -1650,6 +1650,8 @@ void Observer_on_table_create(void); void Observer_on_table_create_is_deferred(void); void Observer_on_table_create_is_deferred_batched(void); void Observer_2_children_w_deferred_set(void); +void Observer_on_add_on_set_w_not_term(void); +void Observer_on_add_on_set_w_not_2_terms(void); void Observer_cache_test_1(void); void Observer_cache_test_2(void); void Observer_cache_test_3(void); @@ -8754,6 +8756,14 @@ bake_test_case Observer_testcases[] = { "2_children_w_deferred_set", Observer_2_children_w_deferred_set }, + { + "on_add_on_set_w_not_term", + Observer_on_add_on_set_w_not_term + }, + { + "on_add_on_set_w_not_2_terms", + Observer_on_add_on_set_w_not_2_terms + }, { "cache_test_1", Observer_cache_test_1 @@ -11665,7 +11675,7 @@ static bake_test_suite suites[] = { "Observer", NULL, NULL, - 237, + 239, Observer_testcases }, {