Skip to content

Commit

Permalink
Fix issue where event was incorrectly propagated for masked component
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Dec 17, 2024
1 parent 0c70671 commit cf6b8ec
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 9 deletions.
5 changes: 5 additions & 0 deletions distr/flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -14361,6 +14361,11 @@ void flecs_emit_forward(
ecs_dbg_assert(r->table == elem->table, ECS_INTERNAL_ERROR, NULL);
(void)r;

/* If entities already have the component, don't propagate */
if (flecs_id_record_get_table(rc_idr, it->table)) {
continue;
}

ecs_event_id_record_t *iders[5] = {0};
int32_t ider_count = flecs_event_observers_get(
er, rc_idr->id, iders);
Expand Down
5 changes: 5 additions & 0 deletions src/observable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,11 @@ void flecs_emit_forward(
ecs_dbg_assert(r->table == elem->table, ECS_INTERNAL_ERROR, NULL);
(void)r;

/* If entities already have the component, don't propagate */
if (flecs_id_record_get_table(rc_idr, it->table)) {
continue;
}

ecs_event_id_record_t *iders[5] = {0};
int32_t ider_count = flecs_event_observers_get(
er, rc_idr->id, iders);
Expand Down
1 change: 1 addition & 0 deletions test/core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,7 @@
"on_remove_multi_only_optional",
"on_add_multi_observers_w_prefab_instance",
"on_add_overlapping_multi_observers_w_prefab_instance",
"mask_propagated_component_after_reparent",
"cache_test_1",
"cache_test_2",
"cache_test_3",
Expand Down
69 changes: 61 additions & 8 deletions test/core/src/Observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ void Observer(ecs_iter_t *it) {
probe_system_w_ctx(it, it->ctx);
}

static
void Observer_w_field(ecs_iter_t *it) {
probe_system_w_ctx(it, it->ctx);

Position *p = ecs_field(it, Position, 0);
test_assert(p != NULL);
// data is uninitialized
}

static
void Observer_w_value_1(ecs_iter_t *it) {
probe_system_w_ctx(it, it->ctx);
Expand Down Expand Up @@ -8405,10 +8414,8 @@ void Observer_cache_test_9(void) {

ecs_clear(world, base_2);

/* Once for Position of base_2, twice because Position is reachable through
* two paths. */
test_int(ctx.invoked, 2);
test_int(ctx.count, 2);
test_int(ctx.invoked, 1);
test_int(ctx.count, 1);
test_int(ctx.e[0], inst);
test_int(ctx.s[0][0], base_2);
test_int(ctx.c[0][0], ecs_id(Position));
Expand All @@ -8418,10 +8425,8 @@ void Observer_cache_test_9(void) {

ecs_clear(world, base_3);

/* Once for Position of base_2, twice because Position is reachable through
* two paths. */
test_int(ctx.invoked, 2);
test_int(ctx.count, 2);
test_int(ctx.invoked, 1);
test_int(ctx.count, 1);
test_int(ctx.e[0], inst);
test_int(ctx.s[0][0], base_3);
test_int(ctx.c[0][0], ecs_id(Position));
Expand Down Expand Up @@ -9707,3 +9712,51 @@ void Observer_on_add_overlapping_multi_observers_w_prefab_instance(void) {

ecs_fini(world);
}

void Observer_mask_propagated_component_after_reparent(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), .src.id = EcsUp },
{ ecs_id(Position) }
},
.events = { EcsOnAdd },
.callback = Observer_w_field,
.ctx = &ctx
});

ecs_entity_t root = ecs_new_w(world, Position);
ecs_entity_t parent = ecs_new_w(world, Position);

test_int(ctx.invoked, 0);

ecs_entity_t child = ecs_new_w_pair(world, EcsChildOf, parent);
ecs_add(world, child, Position);

test_int(ctx.invoked, 1);
test_int(ctx.count, 1);
test_int(ctx.e[0], child);
test_int(ctx.system, o);
test_int(ctx.event, EcsOnAdd);
test_uint(ctx.s[0][0], parent);
test_uint(ctx.s[0][1], 0);

ecs_os_zeromem(&ctx);

ecs_add_pair(world, parent, EcsChildOf, root);

test_int(ctx.invoked, 1);
test_int(ctx.count, 1);
test_int(ctx.e[0], parent);
test_int(ctx.system, o);
test_int(ctx.event, EcsOnAdd);
test_uint(ctx.s[0][0], root);
test_uint(ctx.s[0][1], 0);

ecs_fini(world);
}
7 changes: 6 additions & 1 deletion test/core/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,7 @@ void Observer_on_add_multi_only_optional(void);
void Observer_on_remove_multi_only_optional(void);
void Observer_on_add_multi_observers_w_prefab_instance(void);
void Observer_on_add_overlapping_multi_observers_w_prefab_instance(void);
void Observer_mask_propagated_component_after_reparent(void);
void Observer_cache_test_1(void);
void Observer_cache_test_2(void);
void Observer_cache_test_3(void);
Expand Down Expand Up @@ -8674,6 +8675,10 @@ bake_test_case Observer_testcases[] = {
"on_add_overlapping_multi_observers_w_prefab_instance",
Observer_on_add_overlapping_multi_observers_w_prefab_instance
},
{
"mask_propagated_component_after_reparent",
Observer_mask_propagated_component_after_reparent
},
{
"cache_test_1",
Observer_cache_test_1
Expand Down Expand Up @@ -11565,7 +11570,7 @@ static bake_test_suite suites[] = {
"Observer",
NULL,
NULL,
231,
232,
Observer_testcases
},
{
Expand Down

0 comments on commit cf6b8ec

Please sign in to comment.