|
2 | 2 |
|
3 | 3 | static ECS_COMPONENT_DECLARE(Position); |
4 | 4 |
|
| 5 | +typedef struct ReproObserverCtx { |
| 6 | + int32_t invoked; |
| 7 | + ecs_entity_t entity; |
| 8 | + ecs_entity_t source; |
| 9 | + Position child_position; |
| 10 | + Position parent_position; |
| 11 | +} ReproObserverCtx; |
| 12 | + |
| 13 | +static ReproObserverCtx repro_observer_ctx; |
| 14 | + |
| 15 | +static |
| 16 | +void ReproDummyObserver(ecs_iter_t *it) { |
| 17 | + test_int(it->count, 1); |
| 18 | + |
| 19 | + Position *child_position = ecs_field(it, Position, 0); |
| 20 | + Position *parent_position = ecs_field(it, Position, 1); |
| 21 | + test_assert(child_position != NULL); |
| 22 | + test_assert(parent_position != NULL); |
| 23 | + |
| 24 | + repro_observer_ctx.invoked ++; |
| 25 | + repro_observer_ctx.entity = it->entities[0]; |
| 26 | + repro_observer_ctx.source = it->sources[1]; |
| 27 | + repro_observer_ctx.child_position = child_position[0]; |
| 28 | + repro_observer_ctx.parent_position = parent_position[0]; |
| 29 | +} |
| 30 | + |
5 | 31 | void NonFragmentingChildOf_set_parent_no_ordered_children(void) { |
6 | 32 | ecs_world_t *world = ecs_mini(); |
7 | 33 |
|
@@ -3147,6 +3173,49 @@ void NonFragmentingChildOf_instantiate_tree_3_children(void) { |
3147 | 3173 | ecs_fini(world); |
3148 | 3174 | } |
3149 | 3175 |
|
| 3176 | +void NonFragmentingChildOf_instantiate_tree_w_on_set_up_childof_observer_crash(void) { |
| 3177 | + ecs_world_t *world = ecs_init(); |
| 3178 | + |
| 3179 | + ECS_COMPONENT(world, Position); |
| 3180 | + |
| 3181 | + ecs_entity_t prefab = ecs_new_w_id(world, EcsPrefab); |
| 3182 | + ecs_set(world, prefab, Position, {10, 20}); |
| 3183 | + |
| 3184 | + ecs_entity_t prefab_child = ecs_new_w_parent(world, prefab, "Child"); |
| 3185 | + ecs_set(world, prefab_child, Position, {11, 21}); |
| 3186 | + |
| 3187 | + ecs_os_zeromem(&repro_observer_ctx); |
| 3188 | + |
| 3189 | + ecs_observer(world, { |
| 3190 | + .query.expr = "Position, Position(up ChildOf)", |
| 3191 | + .events = { EcsOnSet }, |
| 3192 | + .callback = ReproDummyObserver |
| 3193 | + }); |
| 3194 | + |
| 3195 | + ecs_entity_t instance = ecs_new_w_pair(world, EcsIsA, prefab); |
| 3196 | + test_assert(instance != 0); |
| 3197 | + |
| 3198 | + ecs_entities_t children = ecs_get_ordered_children(world, instance); |
| 3199 | + test_int(children.count, 1); |
| 3200 | + ecs_entity_t instance_child = children.ids[0]; |
| 3201 | + test_assert(instance_child != 0); |
| 3202 | + |
| 3203 | + const Position *p = ecs_get(world, instance_child, Position); |
| 3204 | + test_assert(p != NULL); |
| 3205 | + test_int(p->x, 11); |
| 3206 | + test_int(p->y, 21); |
| 3207 | + |
| 3208 | + test_int(repro_observer_ctx.invoked, 1); |
| 3209 | + test_uint(repro_observer_ctx.entity, instance_child); |
| 3210 | + test_uint(repro_observer_ctx.source, instance); |
| 3211 | + test_int(repro_observer_ctx.child_position.x, 11); |
| 3212 | + test_int(repro_observer_ctx.child_position.y, 21); |
| 3213 | + test_int(repro_observer_ctx.parent_position.x, 10); |
| 3214 | + test_int(repro_observer_ctx.parent_position.y, 20); |
| 3215 | + |
| 3216 | + ecs_fini(world); |
| 3217 | +} |
| 3218 | + |
3150 | 3219 | void NonFragmentingChildOf_instantiate_w_dont_inherit(void) { |
3151 | 3220 | ecs_world_t *world = ecs_mini(); |
3152 | 3221 |
|
|
0 commit comments