#include void Reference_setup(void) { ecs_log_set_level(-3); } void Reference_get_ref(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Reference_get_ref_after_add(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_add(world, e, Velocity); p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Reference_get_ref_after_remove(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); ecs_add(world, e, Velocity); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_remove(world, e, Velocity); p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Reference_get_ref_after_delete(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t dummy = ecs_new(world, Position); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_delete(world, dummy); p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Reference_get_ref_after_realloc(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); int i; for (i = 0; i < 1000; i ++) { // Creating lots of entities which will trigger allocations ecs_new(world, Position); } p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Reference_get_ref_staged(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_defer_begin(world); /* ecs_set() makes immediate changes */ ecs_set(world, e, Position, {30, 40}); p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); ecs_defer_end(world); p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); ecs_fini(world); } void Reference_get_ref_after_new_in_stage(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_defer_begin(world); ecs_new(world, Position); /* ecs_set() makes immediate changes */ ecs_set(world, e, Position, {30, 40}); p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); ecs_defer_end(world); p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); ecs_fini(world); } void Reference_get_ref_monitored(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); ecs_new_w_pair(world, EcsChildOf, e); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Reference_get_nonexisting(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_new(world, Position); ecs_ref_t ref = ecs_ref_init(world, e, Velocity); const Velocity *p = ecs_ref_get(world, &ref, Velocity); test_assert(p == NULL); ecs_fini(world); } static ECS_MOVE(Position, dst, src, { ecs_os_memcpy_t(dst, src, Position); }) void Reference_get_ref_after_realloc_w_lifecycle(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_set_hooks(world, Position, { .move = ecs_move(Position) }); ECS_ENTITY(world, e, Position); ECS_ENTITY(world, e2, Position); ecs_set(world, e, Position, {10, 20}); ecs_ref_t ref = ecs_ref_init(world, e, Position); const Position *p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); for (int i = 0; i < 1000; i ++) { ECS_ENTITY(world, e, Position); } p = ecs_ref_get(world, &ref, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Reference_get_ref_w_low_id_tag(void) { ecs_world_t *world = ecs_mini(); ecs_entity_t tag = ecs_component_init(world, &(ecs_component_desc_t){ .type.size = 0, .type.alignment = 0 }); ecs_entity_t comp = ecs_component_init(world, &(ecs_component_desc_t){ .type.size = 4, .type.alignment = 4 }); ecs_entity_t e = ecs_new_id(world); ecs_add_id(world, e, tag); ecs_add_id(world, e, comp); test_assert(ecs_get_id(world, e, comp) != NULL); ecs_ref_t ref = ecs_ref_init_id(world, e, comp); test_assert(ecs_ref_get_id(world, &ref, comp) == ecs_get_id(world, e, comp)); ecs_fini(world); } void Reference_get_ref_w_low_id_tag_after_add(void) { ecs_world_t *world = ecs_mini(); ecs_entity_t tag = ecs_component_init(world, &(ecs_component_desc_t){ .type.size = 0, .type.alignment = 0 }); ecs_entity_t id = ecs_new_low_id(world); ecs_entity_t comp = ecs_component_init(world, &(ecs_component_desc_t){ .type.size = 4, .type.alignment = 4 }); ecs_entity_t e = ecs_new_id(world); ecs_add_id(world, e, tag); ecs_add_id(world, e, comp); test_assert(ecs_get_id(world, e, comp) != NULL); ecs_ref_t ref = ecs_ref_init_id(world, e, comp); ecs_add_id(world, e, id); test_assert(ecs_ref_get_id(world, &ref, comp) == ecs_get_id(world, e, comp)); ecs_fini(world); }