Skip to content

Commit

Permalink
#1413 Fix issue where (OnInstantiate, Override) would not trigger OnSet
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens authored Nov 4, 2024
1 parent 08da32a commit d2935ce
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 31 deletions.
81 changes: 66 additions & 15 deletions distr/flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -13802,6 +13802,7 @@ void flecs_emit(
int32_t ider_i, ider_count = 0;
bool is_pair = ECS_IS_PAIR(id);
void *override_ptr = NULL;
bool override_base_added = false;
ecs_table_record_t *base_tr = NULL;
ecs_entity_t base = 0;
bool id_can_override = can_override;
Expand Down Expand Up @@ -13873,6 +13874,26 @@ void flecs_emit(
override_ptr = base_table->data.columns[base_column].data;
override_ptr = ECS_ELEM(override_ptr, ti->size, base_row);
}

/* For ids with override policy, check if base was added
* in same operation. This will determine later on
* whether we need to emit an OnSet event. */
if (!(idr->flags &
(EcsIdOnInstantiateInherit|EcsIdOnInstantiateDontInherit))) {
int32_t base_i;
for (base_i = 0; base_i < id_count; base_i ++) {
ecs_id_t base_id = id_array[base_i];
if (!ECS_IS_PAIR(base_id)) {
continue;
}
if (ECS_PAIR_FIRST(base_id) != EcsIsA) {
continue;
}
if (ECS_PAIR_SECOND(base_id) == (uint32_t)base) {
override_base_added = true;
}
}
}
}
}
}
Expand Down Expand Up @@ -13928,7 +13949,7 @@ void flecs_emit(
ptr = ECS_ELEM(c->data, size, offset);
}

/* safe, owned by observer */
/* Safe, owned by observer */
ECS_CONST_CAST(int32_t*, it.sizes)[0] = size;

if (override_ptr) {
Expand All @@ -13937,6 +13958,26 @@ void flecs_emit(
* with the value of the overridden component. */
flecs_override_copy(world, table, tr, ti, ptr,
override_ptr, offset, count);

/* If the base for this component got added in the same
* operation, generate an OnSet event as this is the
* first time this value is observed for the entity. */
if (override_base_added) {
ecs_event_id_record_t *iders_set[5] = {0};
int32_t ider_set_i, ider_set_count =
flecs_event_observers_get(er_onset, id, iders_set);
for (ider_set_i = 0; ider_set_i < ider_set_count; ider_set_i ++) {
ecs_event_id_record_t *ider = iders_set[ider_set_i];
flecs_observers_invoke(
world, &ider->self, &it, table, 0);
ecs_assert(it.event_cur == evtx,
ECS_INTERNAL_ERROR, NULL);
flecs_observers_invoke(
world, &ider->self_up, &it, table, 0);
ecs_assert(it.event_cur == evtx,
ECS_INTERNAL_ERROR, NULL);
}
}
} else if (er_onset && it.other_table) {
/* If an override was removed, this re-exposes the
* overridden component. Because this causes the actual
Expand Down Expand Up @@ -14519,8 +14560,7 @@ void flecs_observers_invoke(
while (ecs_map_next(&oit)) {
ecs_observer_t *o = ecs_map_ptr(&oit);
ecs_assert(it->table == table, ECS_INTERNAL_ERROR, NULL);
flecs_uni_observer_invoke(
world, o, it, table, trav);
flecs_uni_observer_invoke(world, o, it, table, trav);
}

ecs_table_unlock(it->world, table);
Expand Down Expand Up @@ -50690,85 +50730,96 @@ void FlecsMetaImport(

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsType),
.name = "type", .symbol = "EcsType"
.name = "type", .symbol = "EcsType",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsType),
.type.alignment = ECS_ALIGNOF(EcsType)
.type.alignment = ECS_ALIGNOF(EcsType),
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsPrimitive),
.name = "primitive", .symbol = "EcsPrimitive"
.name = "primitive", .symbol = "EcsPrimitive",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsPrimitive),
.type.alignment = ECS_ALIGNOF(EcsPrimitive)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = EcsConstant,
.name = "constant", .symbol = "EcsConstant"
.name = "constant", .symbol = "EcsConstant",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
})
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsEnum),
.name = "enum", .symbol = "EcsEnum"
.name = "enum", .symbol = "EcsEnum",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsEnum),
.type.alignment = ECS_ALIGNOF(EcsEnum)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsBitmask),
.name = "bitmask", .symbol = "EcsBitmask"
.name = "bitmask", .symbol = "EcsBitmask",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsBitmask),
.type.alignment = ECS_ALIGNOF(EcsBitmask)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsMember),
.name = "member", .symbol = "EcsMember"
.name = "member", .symbol = "EcsMember",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsMember),
.type.alignment = ECS_ALIGNOF(EcsMember)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsMemberRanges),
.name = "member_ranges", .symbol = "EcsMemberRanges"
.name = "member_ranges", .symbol = "EcsMemberRanges",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsMemberRanges),
.type.alignment = ECS_ALIGNOF(EcsMemberRanges)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsStruct),
.name = "struct", .symbol = "EcsStruct"
.name = "struct", .symbol = "EcsStruct",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsStruct),
.type.alignment = ECS_ALIGNOF(EcsStruct)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsArray),
.name = "array", .symbol = "EcsArray"
.name = "array", .symbol = "EcsArray",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsArray),
.type.alignment = ECS_ALIGNOF(EcsArray)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsVector),
.name = "vector", .symbol = "EcsVector"
.name = "vector", .symbol = "EcsVector",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsVector),
.type.alignment = ECS_ALIGNOF(EcsVector)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsOpaque),
.name = "opaque", .symbol = "EcsOpaque"
.name = "opaque", .symbol = "EcsOpaque",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsOpaque),
.type.alignment = ECS_ALIGNOF(EcsOpaque)
Expand Down
35 changes: 23 additions & 12 deletions src/addons/meta/meta.c
Original file line number Diff line number Diff line change
Expand Up @@ -1130,85 +1130,96 @@ void FlecsMetaImport(

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsType),
.name = "type", .symbol = "EcsType"
.name = "type", .symbol = "EcsType",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsType),
.type.alignment = ECS_ALIGNOF(EcsType)
.type.alignment = ECS_ALIGNOF(EcsType),
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsPrimitive),
.name = "primitive", .symbol = "EcsPrimitive"
.name = "primitive", .symbol = "EcsPrimitive",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsPrimitive),
.type.alignment = ECS_ALIGNOF(EcsPrimitive)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = EcsConstant,
.name = "constant", .symbol = "EcsConstant"
.name = "constant", .symbol = "EcsConstant",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
})
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsEnum),
.name = "enum", .symbol = "EcsEnum"
.name = "enum", .symbol = "EcsEnum",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsEnum),
.type.alignment = ECS_ALIGNOF(EcsEnum)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsBitmask),
.name = "bitmask", .symbol = "EcsBitmask"
.name = "bitmask", .symbol = "EcsBitmask",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsBitmask),
.type.alignment = ECS_ALIGNOF(EcsBitmask)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsMember),
.name = "member", .symbol = "EcsMember"
.name = "member", .symbol = "EcsMember",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsMember),
.type.alignment = ECS_ALIGNOF(EcsMember)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsMemberRanges),
.name = "member_ranges", .symbol = "EcsMemberRanges"
.name = "member_ranges", .symbol = "EcsMemberRanges",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsMemberRanges),
.type.alignment = ECS_ALIGNOF(EcsMemberRanges)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsStruct),
.name = "struct", .symbol = "EcsStruct"
.name = "struct", .symbol = "EcsStruct",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsStruct),
.type.alignment = ECS_ALIGNOF(EcsStruct)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsArray),
.name = "array", .symbol = "EcsArray"
.name = "array", .symbol = "EcsArray",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsArray),
.type.alignment = ECS_ALIGNOF(EcsArray)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsVector),
.name = "vector", .symbol = "EcsVector"
.name = "vector", .symbol = "EcsVector",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsVector),
.type.alignment = ECS_ALIGNOF(EcsVector)
});

ecs_component(world, {
.entity = ecs_entity(world, { .id = ecs_id(EcsOpaque),
.name = "opaque", .symbol = "EcsOpaque"
.name = "opaque", .symbol = "EcsOpaque",
.add = ecs_ids(ecs_pair(EcsOnInstantiate, EcsDontInherit))
}),
.type.size = sizeof(EcsOpaque),
.type.alignment = ECS_ALIGNOF(EcsOpaque)
Expand Down
43 changes: 42 additions & 1 deletion src/observable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,7 @@ void flecs_emit(
int32_t ider_i, ider_count = 0;
bool is_pair = ECS_IS_PAIR(id);
void *override_ptr = NULL;
bool override_base_added = false;
ecs_table_record_t *base_tr = NULL;
ecs_entity_t base = 0;
bool id_can_override = can_override;
Expand Down Expand Up @@ -1307,6 +1308,26 @@ void flecs_emit(
override_ptr = base_table->data.columns[base_column].data;
override_ptr = ECS_ELEM(override_ptr, ti->size, base_row);
}

/* For ids with override policy, check if base was added
* in same operation. This will determine later on
* whether we need to emit an OnSet event. */
if (!(idr->flags &
(EcsIdOnInstantiateInherit|EcsIdOnInstantiateDontInherit))) {
int32_t base_i;
for (base_i = 0; base_i < id_count; base_i ++) {
ecs_id_t base_id = id_array[base_i];
if (!ECS_IS_PAIR(base_id)) {
continue;
}
if (ECS_PAIR_FIRST(base_id) != EcsIsA) {
continue;
}
if (ECS_PAIR_SECOND(base_id) == (uint32_t)base) {
override_base_added = true;
}
}
}
}
}
}
Expand Down Expand Up @@ -1362,7 +1383,7 @@ void flecs_emit(
ptr = ECS_ELEM(c->data, size, offset);
}

/* safe, owned by observer */
/* Safe, owned by observer */
ECS_CONST_CAST(int32_t*, it.sizes)[0] = size;

if (override_ptr) {
Expand All @@ -1371,6 +1392,26 @@ void flecs_emit(
* with the value of the overridden component. */
flecs_override_copy(world, table, tr, ti, ptr,
override_ptr, offset, count);

/* If the base for this component got added in the same
* operation, generate an OnSet event as this is the
* first time this value is observed for the entity. */
if (override_base_added) {
ecs_event_id_record_t *iders_set[5] = {0};
int32_t ider_set_i, ider_set_count =
flecs_event_observers_get(er_onset, id, iders_set);
for (ider_set_i = 0; ider_set_i < ider_set_count; ider_set_i ++) {
ecs_event_id_record_t *ider = iders_set[ider_set_i];
flecs_observers_invoke(
world, &ider->self, &it, table, 0);
ecs_assert(it.event_cur == evtx,
ECS_INTERNAL_ERROR, NULL);
flecs_observers_invoke(
world, &ider->self_up, &it, table, 0);
ecs_assert(it.event_cur == evtx,
ECS_INTERNAL_ERROR, NULL);
}
}
} else if (er_onset && it.other_table) {
/* If an override was removed, this re-exposes the
* overridden component. Because this causes the actual
Expand Down
3 changes: 1 addition & 2 deletions src/observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,7 @@ void flecs_observers_invoke(
while (ecs_map_next(&oit)) {
ecs_observer_t *o = ecs_map_ptr(&oit);
ecs_assert(it->table == table, ECS_INTERNAL_ERROR, NULL);
flecs_uni_observer_invoke(
world, o, it, table, trav);
flecs_uni_observer_invoke(world, o, it, table, trav);
}

ecs_table_unlock(it->world, table);
Expand Down
3 changes: 3 additions & 0 deletions test/core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,9 @@
"on_set_self_auto_override",
"on_set_self_superset_auto_override",
"on_set_superset_auto_override",
"on_set_self_on_instantiate_override",
"on_set_self_up_on_instantiate_override",
"on_set_up_on_instantiate_override",
"not_only",
"not_only_w_base",
"not_only_w_base_no_match",
Expand Down
Loading

0 comments on commit d2935ce

Please sign in to comment.