4326 lines
126 KiB
C
4326 lines
126 KiB
C
#include <api.h>
|
|
|
|
static ecs_id_t NamePair;
|
|
|
|
void Prefab_setup(void) {
|
|
NamePair = ecs_pair(ecs_id(EcsIdentifier), EcsName);
|
|
}
|
|
|
|
static
|
|
void Iter(ecs_iter_t *it) {
|
|
Mass *m_ptr = ecs_field(it, Mass, 1);
|
|
bool shared = !ecs_field_is_self(it, 1);
|
|
|
|
Position *p = ecs_field(it, Position, 2);
|
|
|
|
Velocity *v = NULL;
|
|
if (it->field_count >= 3) {
|
|
v = ecs_field(it, Velocity, 3);
|
|
}
|
|
|
|
probe_iter(it);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
Mass m = 1;
|
|
if (m_ptr) {
|
|
if (shared) {
|
|
m = *m_ptr;
|
|
} else {
|
|
m = m_ptr[i];
|
|
}
|
|
}
|
|
|
|
p[i].x = 10 * m;
|
|
p[i].y = 20 * m;
|
|
|
|
if (v) {
|
|
v[i].x = 30 * m;
|
|
v[i].y = 40 * m;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Prefab_new_w_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
ecs_add(world, e1, Velocity);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has(world, e1, Velocity));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
ecs_entity_t e2 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert( ecs_has(world, e2, Position));
|
|
test_assert( ecs_has_pair(world, e2, EcsIsA, Prefab));
|
|
test_assert( !ecs_has_id(world, e2, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e2, NamePair));
|
|
test_assert( !ecs_get_id(world, e2, NamePair));
|
|
|
|
ecs_add(world, e2, Velocity);
|
|
test_assert( ecs_has(world, e2, Position));
|
|
test_assert( ecs_has(world, e2, Velocity));
|
|
test_assert( ecs_has_pair(world, e2, EcsIsA, Prefab));
|
|
test_assert( !ecs_has_id(world, e2, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e2, NamePair));
|
|
test_assert( !ecs_get_id(world, e2, NamePair));
|
|
|
|
const Position *p_1 = ecs_get(world, e1, Position);
|
|
const Position *p_2 = ecs_get(world, e2, Position);
|
|
|
|
test_assert(p_1 != NULL);
|
|
test_assert(p_2 != NULL);
|
|
test_assert(p_1 == p_2);
|
|
|
|
test_int(p_1->x, 10);
|
|
test_int(p_1->y, 20);
|
|
|
|
const Velocity *v_1 = ecs_get(world, e1, Velocity);
|
|
const Velocity *v_2 = ecs_get(world, e2, Velocity);
|
|
|
|
test_assert(v_1 != NULL);
|
|
test_assert(v_2 != NULL);
|
|
test_assert(v_1 != v_2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_new_w_count_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
const ecs_entity_t *ids = ecs_bulk_new_w_id(world, ecs_pair(EcsIsA, Prefab), 10);
|
|
test_assert(ids != NULL);
|
|
|
|
ecs_entity_t i;
|
|
const Position *p_prev = NULL;
|
|
for (i = 0; i < 10; i ++) {
|
|
ecs_entity_t e = ids[i];
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
|
|
if (p_prev) test_ptr(p, p_prev);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
p_prev = p;
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_new_w_type_w_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Prefab, Position, OVERRIDE | Velocity);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
|
|
ecs_entity_t e2 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert( ecs_has(world, e2, Position));
|
|
test_assert( ecs_has_pair(world, e2, EcsIsA, Prefab));
|
|
test_assert( !ecs_has_id(world, e2, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e2, NamePair));
|
|
|
|
const Position *p_1 = ecs_get(world, e1, Position);
|
|
const Position *p_2 = ecs_get(world, e2, Position);
|
|
const Position *p_prefab = ecs_get(world, Prefab, Position);
|
|
|
|
test_assert(p_1 != NULL);
|
|
test_assert(p_2 != NULL);
|
|
test_assert(p_1 == p_2);
|
|
test_assert(p_1 == p_prefab);
|
|
|
|
test_int(p_1->x, 10);
|
|
test_int(p_1->y, 20);
|
|
|
|
const Velocity *v_1 = ecs_get(world, e1, Velocity);
|
|
const Velocity *v_2 = ecs_get(world, e2, Velocity);
|
|
|
|
test_assert(v_1 != NULL);
|
|
test_assert(v_2 != NULL);
|
|
test_assert(v_1 != v_2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_add_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
ecs_entity_t e1 = ecs_new(world, Velocity);
|
|
test_assert(e1 != 0);
|
|
|
|
ecs_add_pair(world, e1, EcsIsA, Prefab);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
|
|
ecs_entity_t e2 = ecs_new(world, Velocity);
|
|
test_assert(e2 != 0);
|
|
|
|
ecs_add_pair(world, e2, EcsIsA, Prefab);
|
|
test_assert( ecs_has(world, e2, Position));
|
|
test_assert( ecs_has_pair(world, e2, EcsIsA, Prefab));
|
|
test_assert( !ecs_has_id(world, e2, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e2, NamePair));
|
|
|
|
const Position *p_1 = ecs_get(world, e1, Position);
|
|
const Position *p_2 = ecs_get(world, e2, Position);
|
|
const Position *p_prefab = ecs_get(world, Prefab, Position);
|
|
|
|
test_assert(p_1 != NULL);
|
|
test_assert(p_2 != NULL);
|
|
test_assert(p_1 == p_2);
|
|
test_assert(p_prefab == p_1);
|
|
|
|
test_int(p_1->x, 10);
|
|
test_int(p_1->y, 20);
|
|
|
|
const Velocity *v_1 = ecs_get(world, e1, Velocity);
|
|
const Velocity *v_2 = ecs_get(world, e2, Velocity);
|
|
|
|
test_assert(v_1 != NULL);
|
|
test_assert(v_2 != NULL);
|
|
test_assert(v_1 != v_2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_remove_prefab_after_new(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
ecs_remove_pair(world, e1, EcsIsA, Prefab);
|
|
test_assert( !ecs_has(world, e1, Position));
|
|
test_assert( !ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_remove_prefab_after_add(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
ecs_entity_t e1 = ecs_new(world, 0);
|
|
test_assert(e1 != 0);
|
|
|
|
ecs_add_pair(world, e1, EcsIsA, Prefab);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
ecs_remove_pair(world, e1, EcsIsA, Prefab);
|
|
test_assert( !ecs_has(world, e1, Position));
|
|
test_assert( !ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_component(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
ecs_set(world, e1, Position, {20, 30});
|
|
p = ecs_get(world, e1, Position);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 30);
|
|
|
|
const Position *p_prefab = ecs_get(world, Prefab, Position);
|
|
test_assert(p != p_prefab);
|
|
test_int(p_prefab->x, 10);
|
|
test_int(p_prefab->y, 20);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_remove_component(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
ecs_set(world, e1, Position, {20, 30});
|
|
p = ecs_get(world, e1, Position);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 30);
|
|
|
|
const Position *p_prefab = ecs_get(world, Prefab, Position);
|
|
test_assert(p_prefab != NULL);
|
|
test_assert(p != p_prefab);
|
|
test_int(p_prefab->x, 10);
|
|
test_int(p_prefab->y, 20);
|
|
|
|
ecs_remove(world, e1, Position);
|
|
p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == p_prefab);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_2_of_3_components_1_self(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
ECS_COMPONENT(world, Rotation);
|
|
ECS_PREFAB(world, Prefab, Position, Velocity, Mass);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
ecs_set(world, Prefab, Velocity, {30, 40});
|
|
ecs_set(world, Prefab, Mass, {50});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
|
|
ecs_set(world, e1, Rotation, {60});
|
|
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has(world, e1, Velocity));
|
|
test_assert( ecs_has(world, e1, Mass));
|
|
test_assert( ecs_has(world, e1, Rotation));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
ecs_set(world, e1, Position, {20, 30});
|
|
p = ecs_get(world, e1, Position);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 30);
|
|
|
|
const Position *p_prefab = ecs_get(world, Prefab, Position);
|
|
test_assert(p != p_prefab);
|
|
test_int(p_prefab->x, 10);
|
|
test_int(p_prefab->y, 20);
|
|
|
|
const Velocity *v = ecs_get(world, e1, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 30);
|
|
test_int(v->y, 40);
|
|
|
|
ecs_set(world, e1, Velocity, {40, 50});
|
|
v = ecs_get(world, e1, Velocity);
|
|
test_int(v->x, 40);
|
|
test_int(v->y, 50);
|
|
|
|
const Velocity *v_prefab = ecs_get(world, Prefab, Velocity);
|
|
test_assert(v != v_prefab);
|
|
test_int(v_prefab->x, 30);
|
|
test_int(v_prefab->y, 40);
|
|
|
|
const Mass *m = ecs_get(world, e1, Mass);
|
|
test_assert(m != NULL);
|
|
test_int(*m, 50);
|
|
|
|
const Mass *m_prefab = ecs_get(world, Prefab, Mass);
|
|
test_assert(m_prefab != NULL);
|
|
test_ptr(m_prefab, m);
|
|
|
|
const Rotation *r = ecs_get(world, e1, Rotation);
|
|
test_assert(r != NULL);
|
|
test_int(*r, 60);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_new_type_w_1_override(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Prefab, Position, Velocity, OVERRIDE | Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
ecs_set(world, Prefab, Velocity, {30, 40});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has(world, e1, Velocity));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
const Position *p_prefab = ecs_get(world, Prefab, Position);
|
|
test_assert(p_prefab != NULL);
|
|
test_assert(p != p_prefab);
|
|
test_int(p_prefab->x, 10);
|
|
test_int(p_prefab->y, 20);
|
|
|
|
const Velocity *v = ecs_get(world, e1, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 30);
|
|
test_int(v->y, 40);
|
|
|
|
const Velocity *v_prefab = ecs_get(world, Prefab, Velocity);
|
|
test_assert(v_prefab != NULL);
|
|
test_assert(v == v_prefab);
|
|
test_int(v_prefab->x, 30);
|
|
test_int(v_prefab->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_new_type_w_2_overrides(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Prefab, Position, Velocity, OVERRIDE | Position, OVERRIDE | Velocity);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
ecs_set(world, Prefab, Velocity, {30, 40});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has(world, e1, Velocity));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
|
|
/* These components should never be inherited from prefabs */
|
|
test_assert( !ecs_has_id(world, e1, EcsPrefab));
|
|
test_assert( !ecs_has_id(world, e1, NamePair));
|
|
test_assert( !ecs_get_id(world, e1, NamePair));
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
const Position *p_prefab = ecs_get(world, Prefab, Position);
|
|
test_assert(p_prefab != NULL);
|
|
test_assert(p != p_prefab);
|
|
test_int(p_prefab->x, 10);
|
|
test_int(p_prefab->y, 20);
|
|
|
|
const Velocity *v = ecs_get(world, e1, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 30);
|
|
test_int(v->y, 40);
|
|
|
|
const Velocity *v_prefab = ecs_get(world, Prefab, Velocity);
|
|
test_assert(v_prefab != NULL);
|
|
test_assert(v != v_prefab);
|
|
test_int(v_prefab->x, 30);
|
|
test_int(v_prefab->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_ptr_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, Prefab));
|
|
test_assert( ecs_get_id(world, e1, Prefab) == NULL);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void Prefab_w_shared(ecs_iter_t *it) {
|
|
Velocity *v = NULL;
|
|
if (it->field_count >= 2) {
|
|
v = ecs_field(it, Velocity, 2);
|
|
if (v) {
|
|
test_assert(!ecs_field_is_self(it, 2));
|
|
}
|
|
}
|
|
|
|
Mass *m = NULL;
|
|
if (it->field_count >= 3) {
|
|
m = ecs_field(it, Mass, 3);
|
|
}
|
|
|
|
probe_iter(it);
|
|
|
|
Position *pos = ecs_field(it, Position, 1);
|
|
|
|
for (int i = 0; i < it->count; i ++) {
|
|
Position *p = &pos[i];
|
|
p->x += v->x;
|
|
p->y += v->y;
|
|
|
|
if (m) {
|
|
p->x += *m;
|
|
p->y += *m;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Prefab_iterate_w_prefab_shared(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Prefab, Velocity);
|
|
ECS_SYSTEM(world, Prefab_w_shared, EcsOnUpdate, Position, Velocity(up|self));
|
|
|
|
ecs_set(world, Prefab, Velocity, {1, 2});
|
|
|
|
ECS_ENTITY(world, e1, (IsA, Prefab), Position);
|
|
test_assert(e1 != 0);
|
|
ecs_set(world, e1, Position, {0, 0});
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 1);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Prefab_w_shared);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.c[0][0], ecs_id(Position));
|
|
test_int(ctx.s[0][0], 0);
|
|
test_int(ctx.c[0][1], ecs_id(Velocity));
|
|
test_int(ctx.s[0][1], Prefab);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_match_entity_prefab_w_system_optional(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Velocity, Mass);
|
|
ECS_SYSTEM(world, Prefab_w_shared, EcsOnUpdate,
|
|
Position,
|
|
Velocity(self|up),
|
|
?Mass(self|up));
|
|
|
|
ecs_set(world, Prefab, Velocity, {1, 2});
|
|
ecs_set(world, Prefab, Mass, {3});
|
|
|
|
ECS_ENTITY(world, e1, (IsA, Prefab), Position);
|
|
test_assert(e1 != 0);
|
|
ecs_set(world, e1, Position, {0, 0});
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 1);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Prefab_w_shared);
|
|
test_int(ctx.term_count, 3);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.c[0][0], ecs_id(Position));
|
|
test_int(ctx.s[0][0], 0);
|
|
test_int(ctx.c[0][1], ecs_id(Velocity));
|
|
test_int(ctx.s[0][1], Prefab);
|
|
test_int(ctx.c[0][2], ecs_id(Mass));
|
|
test_int(ctx.s[0][2], Prefab);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 4);
|
|
test_int(p->y, 5);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_in_system_expr(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab1, Velocity);
|
|
ECS_PREFAB(world, Prefab2, Velocity);
|
|
ECS_SYSTEM(world, Prefab_w_shared, EcsOnUpdate, Position, Velocity(self|up), Mass, (IsA, Prefab1));
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Prefab_w_shared,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_set(world, Prefab1, Velocity, {1, 2});
|
|
ecs_set(world, Prefab2, Velocity, {1, 2});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab1);
|
|
ecs_entity_t e2 = ecs_new_w_pair(world, EcsIsA, Prefab1);
|
|
ecs_entity_t e3 = ecs_new_w_pair(world, EcsIsA, Prefab2);
|
|
|
|
test_assert(e1 != 0);
|
|
test_assert(e2 != 0);
|
|
test_assert(e3 != 0);
|
|
|
|
ecs_set(world, e1, Position, {0, 0});
|
|
ecs_set(world, e2, Position, {0, 0});
|
|
ecs_set(world, e3, Position, {0, 0});
|
|
|
|
ecs_set(world, e1, Mass, {0});
|
|
ecs_set(world, e2, Mass, {0});
|
|
ecs_set(world, e3, Mass, {0});
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 2);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Prefab_w_shared);
|
|
test_int(ctx.term_count, 4);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Position));
|
|
test_int(ctx.s[0][0], 0);
|
|
test_int(ctx.c[0][1], ecs_id(Velocity));
|
|
test_int(ctx.s[0][1], Prefab1);
|
|
test_int(ctx.c[0][2], ecs_id(Mass));
|
|
test_int(ctx.s[0][2], 0);
|
|
test_int(ctx.c[0][3], ecs_pair(EcsIsA, Prefab1));
|
|
test_int(ctx.s[0][3], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void Dummy(ecs_iter_t *it) {
|
|
probe_iter(it);
|
|
}
|
|
|
|
void Prefab_dont_match_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ECS_SYSTEM(world, Dummy, EcsOnUpdate, Position);
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 0);
|
|
test_int(ctx.invoked, 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_new_w_count_w_override(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Prefab, Position, Velocity, OVERRIDE | Velocity);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
ecs_set(world, Prefab, Velocity, {30, 40});
|
|
|
|
const ecs_entity_t *ids = ecs_bulk_new_w_id(
|
|
world, ecs_pair(EcsIsA, Prefab), 100);
|
|
test_assert(ids != NULL);
|
|
|
|
const Position *prefab_p = ecs_get(world, Prefab, Position);
|
|
const Velocity *prefab_v = ecs_get(world, Prefab, Velocity);
|
|
|
|
int i;
|
|
for (i = 0; i < 100; i ++) {
|
|
ecs_entity_t e = ids[i];
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( ecs_has(world, e, Velocity));
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, Prefab));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == prefab_p);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
const Velocity *v = ecs_get(world, e, Velocity);
|
|
test_assert(v != NULL);
|
|
test_assert(v != prefab_v);
|
|
test_int(v->x, 30);
|
|
test_int(v->y, 40);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_2_components_different_size(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Color);
|
|
ECS_PREFAB(world, Prefab, Position, Velocity, Color, OVERRIDE | Velocity, OVERRIDE | Color);
|
|
|
|
ecs_set(world, Prefab, Position, {10, 20});
|
|
ecs_set(world, Prefab, Velocity, {30, 40});
|
|
ecs_set(world, Prefab, Color, {1, 2, 3, 4});
|
|
|
|
const ecs_entity_t *ids = ecs_bulk_new_w_id(world, ecs_pair(EcsIsA, Prefab), 100);
|
|
test_assert(ids != NULL);
|
|
|
|
const Position *prefab_p = ecs_get(world, Prefab, Position);
|
|
const Velocity *prefab_v = ecs_get(world, Prefab, Velocity);
|
|
const Color *prefab_c = ecs_get(world, Prefab, Color);
|
|
|
|
test_assert(prefab_p != NULL);
|
|
test_assert(prefab_v != NULL);
|
|
test_assert(prefab_c != NULL);
|
|
|
|
int i;
|
|
for (i = 0; i < 100; i ++) {
|
|
ecs_entity_t e = ids[i];
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( ecs_has(world, e, Velocity));
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, Prefab));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
test_assert(p == prefab_p);
|
|
|
|
const Velocity *v = ecs_get(world, e, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 30);
|
|
test_int(v->y, 40);
|
|
test_assert(v != prefab_v);
|
|
|
|
const Color *c = ecs_get(world, e, Color);
|
|
test_assert(c != NULL);
|
|
test_int(c->r, 1);
|
|
test_int(c->g, 2);
|
|
test_int(c->b, 3);
|
|
test_int(c->a, 4);
|
|
test_assert(c != prefab_c);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_ignore_prefab_parent_component(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_ENTITY(world, parent, Prefab, Position);
|
|
ECS_ENTITY(world, child, Prefab, (ChildOf, parent), Velocity);
|
|
|
|
test_assert( ecs_has_pair(world, child, EcsChildOf, parent));
|
|
test_assert( !ecs_has(world, child, Position));
|
|
test_assert( ecs_has(world, child, Velocity));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void Move(ecs_iter_t *it) {
|
|
Position *p = ecs_field(it, Position, 1);
|
|
Velocity *v = ecs_field(it, Velocity, 2);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
p[i].x += v[i].y;
|
|
p[i].y += v[i].y;
|
|
}
|
|
}
|
|
|
|
static
|
|
void AddVelocity(ecs_iter_t *it) {
|
|
ecs_id_t ecs_id(Velocity) = ecs_field_id(it, 2);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ecs_set(it->world, it->entities[i], Velocity, {1, 1});
|
|
}
|
|
}
|
|
|
|
void Prefab_match_table_created_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Mass);
|
|
ecs_set(world, Prefab, Mass, {10});
|
|
|
|
ECS_ENTITY(world, e, (IsA, Prefab), Position);
|
|
|
|
ECS_SYSTEM(world, AddVelocity, EcsOnUpdate, Position, [out] !Velocity);
|
|
ECS_SYSTEM(world, Move, EcsOnUpdate, Position, Velocity, Mass(self|up));
|
|
|
|
ecs_set(world, e, Position, {0, 0});
|
|
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( !ecs_has(world, e, Velocity));
|
|
test_assert( ecs_has(world, e, Mass));
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_assert( ecs_has(world, e, Velocity));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 1);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 2);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_1_child(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_PREFAB(world, Parent, Position);
|
|
ecs_set(world, Parent, Position, {1, 2});
|
|
|
|
ECS_PREFAB(world, Child, (ChildOf, Parent), Position);
|
|
ecs_set(world, Child, Position, {2, 3});
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
|
|
const Position *p_e = ecs_get(world, e, Position);
|
|
test_assert(p_e != NULL);
|
|
test_int(p_e->x, 1);
|
|
test_int(p_e->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "Child");
|
|
test_assert(e_child != 0);
|
|
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
const Position *p_child = ecs_get(world, e_child, Position);
|
|
test_assert(p_child != NULL);
|
|
test_int(p_child->x, 2);
|
|
test_int(p_child->y, 3);
|
|
|
|
ecs_entity_t e2 = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e2 != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( ecs_get(world, e2, Position) == p_e);
|
|
|
|
ecs_entity_t e_child2 = ecs_lookup_child(world, e2, "Child");
|
|
test_assert(e_child2 != 0);
|
|
test_assert(ecs_has(world, e_child2, Position));
|
|
test_assert(ecs_has_pair(world, e_child2, EcsChildOf, e2));
|
|
test_assert( ecs_get(world, e_child2, Position) != p_child);
|
|
|
|
p_child = ecs_get(world, e_child2, Position);
|
|
test_assert(p_child != NULL);
|
|
test_int(p_child->x, 2);
|
|
test_int(p_child->y, 3);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_2_children(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_ENTITY(world, Parent, Prefab, Position);
|
|
ecs_set(world, Parent, Position, {1, 2});
|
|
|
|
ECS_ENTITY(world, Child1, Prefab, (ChildOf, Parent), Position);
|
|
ecs_set(world, Child1, Position, {2, 3});
|
|
|
|
ECS_ENTITY(world, Child2, Prefab, (ChildOf, Parent), Position);
|
|
ecs_set(world, Child2, Position, {3, 4});
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "Child1");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
p = ecs_get(world, e_child, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 2);
|
|
test_int(p->y, 3);
|
|
|
|
e_child = ecs_lookup_child(world, e, "Child2");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
p = ecs_get(world, e_child, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 3);
|
|
test_int(p->y, 4);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_grandchild(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Rotation);
|
|
|
|
ECS_ENTITY(world, Parent, Prefab, Position);
|
|
ecs_set(world, Parent, Position, {1, 2});
|
|
|
|
ECS_ENTITY(world, Child, Prefab, (ChildOf, Parent), Position);
|
|
ecs_set(world, Child, Position, {2, 3});
|
|
|
|
ECS_ENTITY(world, GrandChild, Prefab, (ChildOf, Parent.Child), Position, Rotation);
|
|
ecs_set(world, GrandChild, Position, {3, 4});
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "Child");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
p = ecs_get(world, e_child, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 2);
|
|
test_int(p->y, 3);
|
|
|
|
ecs_entity_t e_grandchild = ecs_lookup_child(world, e_child, "GrandChild");
|
|
test_assert(e_grandchild != 0);
|
|
test_assert(ecs_has(world, e_grandchild, Position));
|
|
test_assert(ecs_has_pair(world, e_grandchild, EcsChildOf, e_child));
|
|
|
|
p = ecs_get(world, e_grandchild, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 3);
|
|
test_int(p->y, 4);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_tree_1_2_1(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Rotation);
|
|
|
|
ECS_ENTITY(world, parent, Prefab, Position);
|
|
ecs_set(world, parent, Position, {1, 2});
|
|
|
|
ECS_ENTITY(world, child_1, Prefab, (ChildOf, parent), Position);
|
|
ecs_set(world, child_1, Position, {2, 3});
|
|
|
|
ECS_ENTITY(world, child_2, Prefab, (ChildOf, parent), Position);
|
|
ecs_set(world, child_2, Position, {4, 5});
|
|
|
|
ECS_ENTITY(world, grandchild, Prefab, (ChildOf, parent.child_2), Position);
|
|
ecs_set(world, grandchild, Position, {6, 7});
|
|
|
|
test_assert(ecs_has_pair(world, child_1, EcsChildOf, parent));
|
|
test_assert(ecs_has_pair(world, child_2, EcsChildOf, parent));
|
|
test_assert(ecs_has_pair(world, grandchild, EcsChildOf, child_2));
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, parent);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "child_1");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
p = ecs_get(world, e_child, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 2);
|
|
test_int(p->y, 3);
|
|
|
|
e_child = ecs_lookup_child(world, e, "child_2");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
p = ecs_get(world, e_child, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 4);
|
|
test_int(p->y, 5);
|
|
|
|
ecs_entity_t e_grandchild = ecs_lookup_child(world, e_child, "grandchild");
|
|
test_assert(e_grandchild != 0);
|
|
test_assert(ecs_has(world, e_grandchild, Position));
|
|
test_assert(ecs_has_pair(world, e_grandchild, EcsChildOf, e_child));
|
|
|
|
p = ecs_get(world, e_grandchild, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 6);
|
|
test_int(p->y, 7);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_base_w_child(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_ENTITY(world, Base, Prefab, Velocity);
|
|
ecs_set(world, Base, Velocity, {3, 4});
|
|
|
|
ECS_ENTITY(world, Parent, Prefab, (IsA, Base), Position);
|
|
ecs_set(world, Parent, Position, {1, 2});
|
|
|
|
ECS_ENTITY(world, Child, Prefab, (ChildOf, Parent), Position);
|
|
ecs_set(world, Child, Position, {2, 3});
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( ecs_has(world, e, Velocity));
|
|
|
|
const Position *p_e = ecs_get(world, e, Position);
|
|
test_assert(p_e != NULL);
|
|
test_int(p_e->x, 1);
|
|
test_int(p_e->y, 2);
|
|
|
|
const Velocity *v_e = ecs_get(world, e, Velocity);
|
|
test_assert(v_e != NULL);
|
|
test_int(v_e->x, 3);
|
|
test_int(v_e->y, 4);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "Child");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(!ecs_has(world, e_child, Velocity));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
const Position *p_child = ecs_get(world, e_child, Position);
|
|
test_assert(p_child != NULL);
|
|
test_int(p_child->x, 2);
|
|
test_int(p_child->y, 3);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_child_w_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_ENTITY(world, Base, Prefab, Velocity);
|
|
ecs_set(world, Base, Velocity, {3, 4});
|
|
|
|
ECS_ENTITY(world, Parent, Prefab, Position);
|
|
ecs_set(world, Parent, Position, {1, 2});
|
|
|
|
ECS_ENTITY(world, Child, Prefab, (ChildOf, Parent), (IsA, Base), Position);
|
|
ecs_set(world, Child, Position, {2, 3});
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
|
|
const Position *p_e = ecs_get(world, e, Position);
|
|
test_assert(p_e != NULL);
|
|
test_int(p_e->x, 1);
|
|
test_int(p_e->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "Child");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has(world, e_child, Velocity));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
const Position *p_child = ecs_get(world, e_child, Position);
|
|
test_assert(p_child != NULL);
|
|
test_int(p_child->x, 2);
|
|
test_int(p_child->y, 3);
|
|
|
|
const Velocity *v_child = ecs_get(world, e_child, Velocity);
|
|
test_assert(v_child != NULL);
|
|
test_int(v_child->x, 3);
|
|
test_int(v_child->y, 4);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_child_w_base_w_children(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_ENTITY(world, Base, Prefab, Velocity);
|
|
ecs_set(world, Base, Velocity, {3, 4});
|
|
|
|
ECS_ENTITY(world, BaseChild, Prefab, (ChildOf, Base), Position);
|
|
ecs_set(world, BaseChild, Position, {4, 5});
|
|
|
|
ECS_ENTITY(world, Parent, Prefab, Position);
|
|
ecs_set(world, Parent, Position, {1, 2});
|
|
|
|
ECS_ENTITY(world, Child, Prefab, (ChildOf, Parent), (IsA, Base), Position);
|
|
ecs_set(world, Child, Position, {2, 3});
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
|
|
const Position *p_e = ecs_get(world, e, Position);
|
|
test_assert(p_e != NULL);
|
|
test_int(p_e->x, 1);
|
|
test_int(p_e->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "Child");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has(world, e_child, Velocity));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
const Position *p_child = ecs_get(world, e_child, Position);
|
|
test_assert(p_child != NULL);
|
|
test_int(p_child->x, 2);
|
|
test_int(p_child->y, 3);
|
|
|
|
const Velocity *v_child = ecs_get(world, e_child, Velocity);
|
|
test_assert(v_child != NULL);
|
|
test_int(v_child->x, 3);
|
|
test_int(v_child->y, 4);
|
|
|
|
ecs_entity_t e_base_child = ecs_lookup_child(world, e_child, "BaseChild");
|
|
test_assert(e_base_child != 0);
|
|
test_assert(ecs_has(world, e_base_child, Position));
|
|
test_assert(!ecs_has(world, e_base_child, Velocity));
|
|
test_assert(ecs_has_pair(world, e_base_child, EcsChildOf, e_child));
|
|
|
|
const Position *p_base_child = ecs_get(world, e_base_child, Position);
|
|
test_assert(p_base_child != NULL);
|
|
test_assert(p_base_child != p_child);
|
|
test_int(p_base_child->x, 4);
|
|
test_int(p_base_child->y, 5);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_child_new_w_count(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_ENTITY(world, Parent, Prefab, Position);
|
|
ecs_set(world, Parent, Position, {1, 2});
|
|
|
|
ECS_ENTITY(world, Child, Prefab, (ChildOf, Parent), Position);
|
|
ecs_set(world, Child, Position, {2, 3});
|
|
|
|
const ecs_entity_t *ids = ecs_bulk_new_w_id(world, ecs_pair(EcsIsA, Parent), 3);
|
|
test_assert(ids != NULL);
|
|
|
|
int i;
|
|
for (i = 0; i < 3; i ++) {
|
|
ecs_entity_t e = ids[i];
|
|
test_assert( ecs_has(world, e, Position));
|
|
|
|
const Position *p_e = ecs_get(world, e, Position);
|
|
test_assert(p_e != NULL);
|
|
test_int(p_e->x, 1);
|
|
test_int(p_e->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "Child");
|
|
test_assert(e_child != 0);
|
|
test_assert(ecs_has(world, e_child, Position));
|
|
test_assert(ecs_has_pair(world, e_child, EcsChildOf, e));
|
|
|
|
const Position *p_child = ecs_get(world, e_child, Position);
|
|
test_assert(p_child != NULL);
|
|
test_int(p_child->x, 2);
|
|
test_int(p_child->y, 3);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_auto_override_child_component(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_ENTITY(world, Parent, Prefab, Position);
|
|
ecs_set(world, Parent, Position, {1, 2});
|
|
|
|
ECS_ENTITY(world, ChildPrefab, Prefab, Position, Velocity);
|
|
ecs_set(world, ChildPrefab, Position, {2, 3});
|
|
ecs_set(world, ChildPrefab, Velocity, {4, 5});
|
|
|
|
ECS_ENTITY(world, Child, Prefab, (ChildOf, Parent), (IsA, ChildPrefab), Velocity);
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_has(world, e1, Position));
|
|
|
|
ecs_entity_t e2 = ecs_new_w_pair(world, EcsIsA, Parent);
|
|
test_assert(e2 != 0);
|
|
test_assert( ecs_has(world, e2, Position));
|
|
|
|
const Position *p1 = ecs_get(world, e1, Position);
|
|
test_assert(p1 != NULL);
|
|
test_int(p1->x, 1);
|
|
test_int(p1->y, 2);
|
|
|
|
const Position *p2 = ecs_get(world, e2, Position);
|
|
test_assert(p2 != NULL);
|
|
test_int(p2->x, 1);
|
|
test_int(p2->y, 2);
|
|
test_assert(p1 == p2);
|
|
|
|
ecs_entity_t child_1 = ecs_lookup_child(world, e1, "Child");
|
|
test_assert(child_1 != 0);
|
|
|
|
test_assert( ecs_has(world, child_1, Position));
|
|
test_assert( ecs_has(world, child_1, Velocity));
|
|
|
|
ecs_entity_t child_2 = ecs_lookup_child(world, e2, "Child");
|
|
test_assert(child_2 != 0);
|
|
test_assert( ecs_has(world, child_2, Position));
|
|
test_assert( ecs_has(world, child_2, Velocity));
|
|
|
|
const Position *child_p1 = ecs_get(world, child_1, Position);
|
|
test_assert(child_p1 != NULL);
|
|
test_int(child_p1->x, 2);
|
|
test_int(child_p1->y, 3);
|
|
|
|
const Position *child_p2 = ecs_get(world, child_2, Position);
|
|
test_assert(child_p2 != NULL);
|
|
test_int(child_p2->x, 2);
|
|
test_int(child_p2->y, 3);
|
|
test_assert(child_p1 == child_p2);
|
|
|
|
const Velocity *child_v1 = ecs_get(world, child_1, Velocity);
|
|
test_assert(child_v1 != NULL);
|
|
test_int(child_v1->x, 4);
|
|
test_int(child_v1->y, 5);
|
|
|
|
const Velocity *child_v2 = ecs_get(world, child_2, Velocity);
|
|
test_assert(child_v2 != NULL);
|
|
test_int(child_v2->x, 4);
|
|
test_int(child_v2->y, 5);
|
|
test_assert(child_v1 != child_v2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static int invoked;
|
|
|
|
void PrefabReactiveTest(ecs_iter_t *it) {
|
|
invoked ++;
|
|
}
|
|
|
|
void Prefab_ignore_on_add(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_OBSERVER(world, PrefabReactiveTest, EcsOnAdd, Position);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
test_int(invoked, 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_ignore_on_remove(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_OBSERVER(world, PrefabReactiveTest, EcsOnRemove, Position);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
test_int(invoked, 0);
|
|
|
|
ecs_remove(world, Prefab, Position);
|
|
|
|
test_int(invoked, 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_ignore_on_set(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_OBSERVER(world, PrefabReactiveTest, EcsOnSet, Position);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
test_int(invoked, 0);
|
|
|
|
ecs_set(world, Prefab, Position, {0, 0});
|
|
|
|
test_int(invoked, 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_on_set_on_instance(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_OBSERVER(world, PrefabReactiveTest, EcsOnSet, Position(self|up));
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
test_int(invoked, 0);
|
|
|
|
ecs_set(world, Prefab, Position, {1, 2});
|
|
|
|
test_int(invoked, 0);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_int(invoked, 1);
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void InstantiateInProgress(ecs_iter_t *it) {
|
|
ecs_id_t Prefab = ecs_field_id(it, 2);
|
|
ecs_entity_t *ids = ecs_get_ctx(it->world);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ids[i] = ecs_new_w_pair(it->world, EcsIsA, Prefab);
|
|
}
|
|
}
|
|
|
|
void Prefab_instantiate_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, Prefab, Velocity);
|
|
ecs_set(world, Prefab, Velocity, {1, 2});
|
|
|
|
ECS_SYSTEM(world, InstantiateInProgress, EcsOnUpdate, Position, Prefab());
|
|
|
|
const ecs_entity_t *dummy_ids = ecs_bulk_new(world, Position, 10);
|
|
test_assert(dummy_ids != NULL);
|
|
|
|
ecs_entity_t ids[10];
|
|
ecs_set_ctx(world, ids, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ecs_count_id(world, ecs_pair(EcsIsA, Prefab)), 10);
|
|
|
|
const Velocity *v_prefab = ecs_get(world, Prefab, Velocity);
|
|
|
|
int i;
|
|
for (i = 0; i < 10; i ++) {
|
|
const Velocity *v = ecs_get(world, ids[i], Velocity);
|
|
test_assert(v == v_prefab);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void NewInProgress(ecs_iter_t *it) {
|
|
ecs_id_t Prefab = ecs_field_id(it, 2);
|
|
|
|
ecs_entity_t *ids = ecs_get_ctx(it->world);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ids[i] = ecs_new_w_pair(it->world, EcsIsA, Prefab);
|
|
}
|
|
}
|
|
|
|
void Prefab_copy_from_prefab_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, Prefab, Velocity, OVERRIDE | Velocity);
|
|
ecs_set(world, Prefab, Velocity, {1, 2});
|
|
|
|
ECS_SYSTEM(world, NewInProgress, EcsOnUpdate, Position, Prefab());
|
|
|
|
ecs_entity_t ids[10];
|
|
ecs_set_ctx(world, ids, NULL);
|
|
|
|
const ecs_entity_t *dummy_ids = ecs_bulk_new(world, Position, 10);
|
|
test_assert(dummy_ids != NULL);
|
|
|
|
/* Create one prefab instance so table is already created (case where table
|
|
* is not created is tested in copy_from_prefab_first_instance_in_progress*/
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e != 0);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ecs_count_id(world, ecs_pair(EcsIsA, Prefab)), 11);
|
|
|
|
int i;
|
|
for (i = 0; i < 10; i ++) {
|
|
const Velocity *v = ecs_get(world, ids[i], Velocity);
|
|
test_int(v->x, 1);
|
|
test_int(v->y, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_copy_from_prefab_first_instance_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, Prefab, Velocity, OVERRIDE | Velocity);
|
|
ecs_set(world, Prefab, Velocity, {1, 2});
|
|
|
|
ECS_SYSTEM(world, NewInProgress, EcsOnUpdate, Position, Prefab());
|
|
|
|
ecs_entity_t ids[10];
|
|
ecs_set_ctx(world, ids, NULL);
|
|
|
|
const ecs_entity_t *dummy_ids = ecs_bulk_new(world, Position, 10);
|
|
test_assert(dummy_ids != NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ecs_count_id(world, ecs_pair(EcsIsA, Prefab)), 10);
|
|
|
|
int i;
|
|
for (i = 0; i < 10; i ++) {
|
|
const Velocity *v = ecs_get(world, ids[i], Velocity);
|
|
test_int(v->x, 1);
|
|
test_int(v->y, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_ref_after_realloc(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Mass);
|
|
ecs_set(world, Prefab, Mass, {2});
|
|
|
|
ECS_ENTITY(world, e1, Position, Mass);
|
|
ecs_set(world, e1, Mass, {3});
|
|
|
|
ECS_ENTITY(world, e2, Position, (IsA, Prefab));
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(self|up), Position);
|
|
|
|
/* Trigger a realloc of the table in which the prefab is stored. This should
|
|
* cause systems with refs to re-resolve their cached ref ptrs */
|
|
for (int i = 0; i < 1000; i ++) {
|
|
ecs_clone(world, 0, Prefab, false);
|
|
}
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 30);
|
|
test_int(p->y, 60);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_revalidate_ref_w_mixed_table_refs(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Mass);
|
|
ecs_set(world, Prefab, Mass, {1});
|
|
|
|
ECS_ENTITY(world, e1, Position, (IsA, Prefab));
|
|
ECS_ENTITY(world, e2, Position, Mass);
|
|
ecs_set(world, e2, Mass, {3});
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(self|up), Position);
|
|
|
|
/* Trigger a realloc of the table in which the prefab is stored. This should
|
|
* cause systems with refs to re-resolve their cached ref ptrs */
|
|
for (int i = 0; i < 1000; i ++) {
|
|
ecs_clone(world, 0, Prefab, false);
|
|
}
|
|
|
|
ecs_set(world, Prefab, Mass, {2});
|
|
ecs_progress(world, 1);
|
|
|
|
const Position *p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 30);
|
|
test_int(p->y, 60);
|
|
|
|
p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_no_overwrite_on_2nd_add(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Mass);
|
|
ecs_set(world, Prefab, Mass, {1});
|
|
|
|
ECS_ENTITY(world, e1, Position, (IsA, Prefab));
|
|
|
|
ecs_add(world, e1, Mass);
|
|
test_int( *ecs_get(world, e1, Mass), 1);
|
|
|
|
ecs_set(world, e1, Mass, {2});
|
|
test_int( *ecs_get(world, e1, Mass), 2);
|
|
|
|
ecs_add(world, e1, Mass);
|
|
test_int( *ecs_get(world, e1, Mass), 2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void AddPrefab(ecs_iter_t *it) {
|
|
ecs_id_t Prefab = ecs_field_id(it, 2);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ecs_add_pair(it->world, it->entities[i], EcsIsA, Prefab);
|
|
}
|
|
}
|
|
|
|
void Prefab_no_overwrite_on_2nd_add_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Mass);
|
|
ecs_set(world, Prefab, Mass, {1});
|
|
|
|
ECS_SYSTEM(world, AddPrefab, EcsOnUpdate, Position, Prefab());
|
|
|
|
ECS_ENTITY(world, e1, Position, (IsA, Prefab));
|
|
ecs_add(world, e1, Mass);
|
|
test_int( *ecs_get(world, e1, Mass), 1);
|
|
|
|
ecs_set(world, e1, Mass, {2});
|
|
test_int( *ecs_get(world, e1, Mass), 2);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int( *ecs_get(world, e1, Mass), 2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_no_instantiate_on_2nd_add(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ecs_set(world, Prefab, Position, {1, 2});
|
|
|
|
ECS_PREFAB(world, ChildPrefab, (ChildOf, Prefab), Velocity);
|
|
ecs_set(world, ChildPrefab, Velocity, {3, 4});
|
|
|
|
ECS_SYSTEM(world, AddPrefab, EcsOnUpdate, Position, Prefab());
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, Prefab));
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "ChildPrefab");
|
|
test_assert(e_child != 0);
|
|
const Velocity *v = ecs_get(world, e_child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 3);
|
|
test_int(v->y, 4);
|
|
|
|
ecs_set(world, e_child, Velocity, {4, 5});
|
|
v = ecs_get(world, e_child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 4);
|
|
test_int(v->y, 5);
|
|
|
|
ecs_add_pair(world, e, EcsIsA, Prefab);
|
|
|
|
ecs_entity_t e_child_2 = ecs_lookup_child(world, e, "ChildPrefab");
|
|
test_assert(e_child == e_child_2);
|
|
v = ecs_get(world, e_child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 4);
|
|
test_int(v->y, 5);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_no_instantiate_on_2nd_add_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ecs_set(world, Prefab, Position, {1, 2});
|
|
|
|
ECS_PREFAB(world, ChildPrefab, (ChildOf, Prefab), Velocity);
|
|
ecs_set(world, ChildPrefab, Velocity, {3, 4});
|
|
|
|
ECS_SYSTEM(world, AddPrefab, EcsOnUpdate, Position, Prefab());
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, Prefab));
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_entity_t e_child = ecs_lookup_child(world, e, "ChildPrefab");
|
|
test_assert(e_child != 0);
|
|
const Velocity *v = ecs_get(world, e_child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 3);
|
|
test_int(v->y, 4);
|
|
|
|
ecs_set(world, e_child, Velocity, {4, 5});
|
|
v = ecs_get(world, e_child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 4);
|
|
test_int(v->y, 5);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
ecs_entity_t e_child_2 = ecs_lookup_child(world, e, "ChildPrefab");
|
|
test_assert(e_child == e_child_2);
|
|
v = ecs_get(world, e_child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 4);
|
|
test_int(v->y, 5);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void NewPrefab_w_count(ecs_iter_t *it) {
|
|
ecs_entity_t *ids = ecs_get_ctx(it->world);
|
|
ecs_id_t Prefab = ecs_field_id(it, 1);
|
|
|
|
const ecs_entity_t *new_ids = ecs_bulk_new_w_id(it->world, ecs_pair(EcsIsA, Prefab), 3);
|
|
test_assert(new_ids != NULL);
|
|
memcpy(ids, new_ids, sizeof(ecs_entity_t) * 3);
|
|
}
|
|
|
|
void Prefab_nested_prefab_in_progress_w_count(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ecs_set(world, Prefab, Position, {1, 2});
|
|
|
|
ECS_PREFAB(world, ChildPrefab, (ChildOf, Prefab), Velocity);
|
|
ecs_set(world, ChildPrefab, Velocity, {3, 4});
|
|
|
|
ECS_SYSTEM(world, NewPrefab_w_count, EcsOnUpdate, Prefab());
|
|
|
|
ecs_entity_t ids[3] = {0};
|
|
ecs_set_ctx(world, ids, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
int i;
|
|
for (i = 0; i < 3; i ++) {
|
|
ecs_has_pair(world, ids[i], EcsIsA, Prefab);
|
|
|
|
const Position *p = ecs_get(world, ids[i], Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_entity_t child = ecs_lookup_child(world, ids[i], "ChildPrefab");
|
|
test_assert(child != 0);
|
|
|
|
const Velocity *v = ecs_get(world, child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 3);
|
|
test_int(v->y, 4);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static int on_set_velocity_invoked;
|
|
|
|
static
|
|
void OnSetVelocity(ecs_iter_t *it) {
|
|
Velocity *v = ecs_field(it, Velocity, 1);
|
|
ecs_id_t ecs_id(Velocity) = ecs_field_id(it, 1);
|
|
|
|
on_set_velocity_invoked ++;
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ecs_add(it->world, it->entities[i], Velocity);
|
|
|
|
if (ecs_field_is_self(it, 1)) {
|
|
v[i].x ++;
|
|
v[i].y ++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Prefab_nested_prefab_in_progress_w_count_set_after_override(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ecs_set(world, Prefab, Position, {1, 2});
|
|
|
|
ECS_PREFAB(world, ChildPrefab, (ChildOf, Prefab), Velocity);
|
|
ecs_set(world, ChildPrefab, Velocity, {3, 4});
|
|
|
|
ECS_SYSTEM(world, NewPrefab_w_count, EcsOnUpdate, Prefab());
|
|
ECS_OBSERVER(world, OnSetVelocity, EcsOnSet, Velocity);
|
|
|
|
test_int(on_set_velocity_invoked, 0);
|
|
|
|
ecs_entity_t ids[3] = {0};
|
|
ecs_set_ctx(world, ids, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_assert(ids != NULL);
|
|
test_int(on_set_velocity_invoked, 3);
|
|
|
|
int i;
|
|
for (i = 0; i < 3; i ++) {
|
|
ecs_has_pair(world, ids[i], EcsIsA, Prefab);
|
|
|
|
const Position *p = ecs_get(world, ids[i], Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 1);
|
|
test_int(p->y, 2);
|
|
|
|
ecs_entity_t child = ecs_lookup_child(world, ids[i], "ChildPrefab");
|
|
test_assert(child != 0);
|
|
|
|
const Velocity *v = ecs_get(world, child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 3 + 1);
|
|
test_int(v->y, 4 + 1);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void AddPrefabInProgress(ecs_iter_t *it) {
|
|
ecs_id_t Prefab = ecs_field_id(it, 2);
|
|
ecs_id_t ecs_id(Velocity) = ecs_field_id(it, 3);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ecs_add_pair(it->world, it->entities[i], EcsIsA, Prefab);
|
|
test_assert( ecs_has_id(it->world, it->entities[i], Prefab));
|
|
test_assert( ecs_has(it->world, it->entities[i], Velocity));
|
|
|
|
const Velocity *v = ecs_get(it->world, it->entities[i], Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 1);
|
|
test_int(v->y, 2);
|
|
|
|
test_assert( ecs_get(it->world, Prefab, Velocity) == v);
|
|
}
|
|
}
|
|
|
|
void Prefab_get_ptr_from_prefab_from_new_table_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Prefab, Velocity);
|
|
ecs_set(world, Prefab, Velocity, {1, 2});
|
|
|
|
ECS_SYSTEM(world, AddPrefabInProgress, EcsOnUpdate, Position, Prefab(), Velocity());
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, Prefab));
|
|
test_assert( ecs_has(world, e, Velocity));
|
|
|
|
const Velocity *v = ecs_get(world, e, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 1);
|
|
test_int(v->y, 2);
|
|
|
|
test_assert( ecs_get(world, Prefab, Velocity) == v);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void TestBase(ecs_iter_t *it) {
|
|
Position *p = ecs_field(it, Position, 1);
|
|
Velocity *v = ecs_field(it, Velocity, 2);
|
|
|
|
test_assert(!ecs_field_is_self(it, 2));
|
|
|
|
test_assert(p != NULL);
|
|
test_assert(v != NULL);
|
|
test_int(it->count, 1);
|
|
}
|
|
|
|
void Prefab_match_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_PREFAB(world, Base, Velocity);
|
|
ecs_set(world, Base, Velocity, {1, 2});
|
|
|
|
ECS_PREFAB(world, Child, (IsA, Base));
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Child);
|
|
ecs_add(world, e, Position);
|
|
|
|
ECS_SYSTEM(world, TestBase, EcsOnUpdate, Position, Velocity(self|up));
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void AddMass(ecs_iter_t *it) {
|
|
ecs_id_t ecs_id(Mass) = ecs_field_id(it, 2);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ecs_add(it->world, it->entities[i], Mass);
|
|
}
|
|
}
|
|
|
|
void Prefab_match_base_after_add_in_prev_phase(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
ECS_PREFAB(world, Base, Velocity);
|
|
ecs_set(world, Base, Velocity, {1, 2});
|
|
|
|
ECS_PREFAB(world, Child, (IsA, Base));
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Child);
|
|
ecs_add(world, e, Position);
|
|
|
|
ECS_SYSTEM(world, AddMass, EcsPreUpdate, Position, !Mass);
|
|
ECS_SYSTEM(world, TestBase, EcsOnUpdate, Position, Velocity(self|up));
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_watched_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
/* Create a system that listens for Position */
|
|
ECS_SYSTEM(world, Dummy, EcsOnUpdate, Position(self|up));
|
|
|
|
/* Create a prefab with Position */
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
|
|
/* Create an instance of Prefab, this will cause Prefab to be watched since
|
|
* it will be matched as reference with the system */
|
|
ECS_ENTITY(world, Entity1, (IsA, Prefab));
|
|
|
|
/* Another instance of Prefab is created, prefab data is resolved to check
|
|
* if components need to be overridden. Index will be negative, so code
|
|
* needs to flip sign on the index, or this will fail. */
|
|
ECS_ENTITY(world, Entity2, (IsA, Prefab), Position);
|
|
|
|
const Position *p1 = ecs_get(world, Prefab, Position);
|
|
const Position *p2 = ecs_get(world, Entity1, Position);
|
|
const Position *p3 = ecs_get(world, Entity2, Position);
|
|
|
|
test_assert(p1 == p2);
|
|
test_assert(p2 != p3);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_rematch_twice(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_SYSTEM(world, Dummy, EcsOnUpdate, Position(self|up), Velocity(self|up), Mass(self|up));
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ECS_ENTITY(world, Entity, (IsA, Prefab));
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
test_int(ctx.count, 0);
|
|
ctx.count = 0;
|
|
|
|
ecs_add(world, Prefab, Velocity);
|
|
|
|
ecs_progress(world, 1);
|
|
test_int(ctx.count, 0);
|
|
ctx.count = 0;
|
|
|
|
ecs_add(world, Prefab, Mass);
|
|
|
|
ecs_progress(world, 1);
|
|
test_int(ctx.count, 1);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void AddPosition(ecs_iter_t *it) {
|
|
ecs_id_t ecs_id(Position) = ecs_field_id(it, 1);
|
|
|
|
ecs_entity_t *base = ecs_get_ctx(it->world);
|
|
|
|
ecs_add(it->world, *base, Position);
|
|
}
|
|
|
|
void Prefab_add_to_empty_base_in_system(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
ecs_entity_t e1 = ecs_new(world, Position);
|
|
ecs_add_pair(world, e1, EcsIsA, base);
|
|
|
|
ECS_SYSTEM(world, AddPosition, EcsOnUpdate, Position());
|
|
|
|
ecs_set_ctx(world, &base, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_assert( ecs_has(world, base, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_inherit_disabled(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ecs_entity_t e1 = ecs_new(world, Position);
|
|
ecs_entity_t e2 = ecs_new(world, Velocity);
|
|
|
|
ecs_add_id(world, e2, EcsDisabled);
|
|
ecs_add_pair(world, e1, EcsIsA, e2);
|
|
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has(world, e1, Velocity));
|
|
test_assert( ecs_has_id(world, e1, EcsDisabled));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, e2));
|
|
test_assert( !ecs_has(world, e2, Position));
|
|
test_assert( ecs_has(world, e2, Velocity));
|
|
test_assert( ecs_has_id(world, e2, EcsDisabled));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static bool has_cloned = false;
|
|
|
|
static
|
|
void CloneInOnAdd(ecs_iter_t *it)
|
|
{
|
|
Position *p = ecs_field(it, Position, 1);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
bool has_cloned_test = has_cloned;
|
|
|
|
/* Prevent recursive OnAdd calls */
|
|
has_cloned = true;
|
|
|
|
p[i].x = 10;
|
|
p[i].y = 20;
|
|
|
|
if (!has_cloned_test) {
|
|
ecs_entity_t e = it->entities[i];
|
|
ecs_entity_t clone = ecs_clone(it->world, 0, e, true);
|
|
ecs_add_pair(it->world, e, EcsIsA, clone);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Prefab_clone_after_inherit_in_on_add(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_OBSERVER(world, CloneInOnAdd, EcsOnAdd, Position);
|
|
|
|
ecs_entity_t e = ecs_new(world, Position);
|
|
test_assert(e != 0);
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
test_assert(has_cloned == true);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_from_nested(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, BasePrefab, Position);
|
|
ecs_set(world, BasePrefab, Position, {10, 20});
|
|
|
|
ECS_PREFAB(world, SubPrefab, (IsA, BasePrefab), Velocity, OVERRIDE | Position, OVERRIDE | Velocity);
|
|
ecs_set(world, SubPrefab, Velocity, {30, 40});
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, SubPrefab);
|
|
test_assert(e1 != 0);
|
|
test_assert( ecs_owns(world, e1, Position));
|
|
test_assert( ecs_owns(world, e1, Velocity));
|
|
test_assert( ecs_owns(world, e1, Position));
|
|
test_assert( ecs_owns(world, e1, Velocity));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, SubPrefab));
|
|
test_assert( ecs_has_pair(world, e1, EcsIsA, BasePrefab));
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
const Velocity *v = ecs_get(world, e1, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 30);
|
|
test_int(v->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void OnAddEntity(ecs_iter_t *it) {
|
|
ecs_entity_t *e = ecs_field(it, ecs_entity_t, 1);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
e[i] = it->entities[i];
|
|
}
|
|
}
|
|
|
|
void Prefab_create_multiple_nested_w_on_set(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
ECS_COMPONENT(world, ecs_entity_t);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ecs_set(world, Prefab, Position, {1, 2});
|
|
|
|
ECS_PREFAB(world, Child, (ChildOf, Prefab), Velocity, ecs_entity_t);
|
|
ecs_set(world, Child, Velocity, {3, 4});
|
|
|
|
ECS_OBSERVER(world, OnAddEntity, EcsOnSet, ecs_entity_t);
|
|
ECS_OBSERVER(world, OnSetVelocity, EcsOnSet, Velocity);
|
|
|
|
test_int(on_set_velocity_invoked, 0);
|
|
|
|
/* Create two entities with separate calls */
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
ecs_entity_t e2 = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
|
|
test_int(on_set_velocity_invoked, 2);
|
|
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has(world, e2, Position));
|
|
|
|
ecs_entity_t child1 = ecs_lookup_child(world, e1, "Child");
|
|
test_assert(child1 != 0);
|
|
|
|
ecs_entity_t child2 = ecs_lookup_child(world, e2, "Child");
|
|
test_assert(child2 != 0);
|
|
test_assert(child1 != child2);
|
|
|
|
const ecs_entity_t *self1 = ecs_get(world, child1, ecs_entity_t);
|
|
test_assert(self1 != NULL);
|
|
test_assert(*self1 == child1);
|
|
|
|
const ecs_entity_t *self2 = ecs_get(world, child2, ecs_entity_t);
|
|
test_assert(self2 != NULL);
|
|
test_assert(self1 != self2);
|
|
test_assert(*self2 == child2);
|
|
|
|
test_assert( ecs_has(world, child1, Velocity));
|
|
test_assert( ecs_has(world, child2, Velocity));
|
|
test_assert( ecs_owns(world, child1, Velocity));
|
|
test_assert( ecs_owns(world, child2, Velocity));
|
|
|
|
const Velocity *v1 = ecs_get(world, child1, Velocity);
|
|
test_assert(v1 != NULL);
|
|
test_int(v1->x, 4);
|
|
test_int(v1->y, 5);
|
|
|
|
const Velocity *v2 = ecs_get(world, child2, Velocity);
|
|
test_assert(v2 != NULL);
|
|
test_assert(v1 != v2);
|
|
test_int(v2->x, 4);
|
|
test_int(v2->y, 5);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static ecs_entity_t new_instance_1, new_instance_2;
|
|
|
|
static
|
|
void CreateInstances(ecs_iter_t *it) {
|
|
ecs_id_t Prefab = ecs_field_id(it, 1);
|
|
|
|
new_instance_1 = ecs_new_w_pair(it->world, EcsIsA, Prefab);
|
|
new_instance_2 = ecs_new_w_pair(it->world, EcsIsA, Prefab);
|
|
}
|
|
|
|
void Prefab_create_multiple_nested_w_on_set_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
ECS_COMPONENT(world, ecs_entity_t);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ecs_set(world, Prefab, Position, {1, 2});
|
|
|
|
ECS_PREFAB(world, ChildPrefab, Velocity);
|
|
ecs_set(world, ChildPrefab, Velocity, {3, 4});
|
|
|
|
ECS_PREFAB(world, Child, (ChildOf, Prefab), (IsA, ChildPrefab), ecs_entity_t);
|
|
|
|
ECS_SYSTEM(world, CreateInstances, EcsOnUpdate, Prefab());
|
|
ECS_OBSERVER(world, OnAddEntity, EcsOnSet, ecs_entity_t);
|
|
ECS_OBSERVER(world, OnSetVelocity, EcsOnSet, Velocity(self|up));
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(on_set_velocity_invoked, 2);
|
|
|
|
ecs_entity_t e1 = new_instance_1;
|
|
ecs_entity_t e2 = new_instance_2;
|
|
|
|
test_assert( ecs_has(world, e1, Position));
|
|
test_assert( ecs_has(world, e2, Position));
|
|
|
|
ecs_entity_t child1 = ecs_lookup_child(world, e1, "Child");
|
|
test_assert(child1 != 0);
|
|
|
|
ecs_entity_t child2 = ecs_lookup_child(world, e2, "Child");
|
|
test_assert(child2 != 0);
|
|
test_assert(child1 != child2);
|
|
|
|
const ecs_entity_t *self1 = ecs_get(world, child1, ecs_entity_t);
|
|
test_assert(self1 != NULL);
|
|
test_assert(*self1 == child1);
|
|
|
|
const ecs_entity_t *self2 = ecs_get(world, child2, ecs_entity_t);
|
|
test_assert(self2 != NULL);
|
|
test_assert(self1 != self2);
|
|
test_assert(*self2 == child2);
|
|
|
|
test_assert( ecs_has(world, child1, Velocity));
|
|
test_assert( ecs_has(world, child2, Velocity));
|
|
test_assert( ecs_owns(world, child1, Velocity));
|
|
test_assert( ecs_owns(world, child2, Velocity));
|
|
|
|
const Velocity *v1 = ecs_get(world, child1, Velocity);
|
|
test_assert(v1 != NULL);
|
|
test_int(v1->x, 3);
|
|
test_int(v1->y, 4);
|
|
|
|
const Velocity *v2 = ecs_get(world, child2, Velocity);
|
|
test_assert(v2 != NULL);
|
|
test_assert(v1 != v2);
|
|
test_int(v2->x, 3);
|
|
test_int(v2->y, 4);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_single_on_set_on_child_w_override(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
ECS_COMPONENT(world, ecs_entity_t);
|
|
|
|
ECS_PREFAB(world, Prefab, Position);
|
|
ecs_set(world, Prefab, Position, {1, 2});
|
|
|
|
ECS_PREFAB(world, ChildPrefab, Velocity);
|
|
ecs_set(world, ChildPrefab, Velocity, {3, 4});
|
|
|
|
ECS_PREFAB(world, Child, (ChildOf, Prefab), (IsA, ChildPrefab), Velocity);
|
|
|
|
ECS_OBSERVER(world, OnSetVelocity, EcsOnSet, Velocity);
|
|
|
|
test_int(on_set_velocity_invoked, 0);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
|
|
/* Make sure OnSet is invoked only once, even though Child overrides a
|
|
* component from a ChildPrefab. Velocity is already overridden for Child,
|
|
* and while it would technically not be incorrect to issue an OnSet for the
|
|
* override, we don't want to spam the application with redundant triggers. */
|
|
test_int(on_set_velocity_invoked, 1);
|
|
|
|
test_assert( ecs_has(world, e, Position));
|
|
|
|
ecs_entity_t child = ecs_lookup_child(world, e, "Child");
|
|
test_assert(child != 0);
|
|
|
|
test_assert( ecs_has(world, child, Velocity));
|
|
test_assert( ecs_owns(world, child, Velocity));
|
|
|
|
const Velocity *v = ecs_get(world, child, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 4);
|
|
test_int(v->y, 5);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_auto_override(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, Prefab, Position, Velocity, OVERRIDE | Position);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(ecs_has(world, e, Position));
|
|
test_assert(ecs_owns(world, e, Position));
|
|
test_assert(ecs_has(world, e, Velocity));
|
|
test_assert(!ecs_owns(world, e, Velocity));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_auto_override_2(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, Prefab, Position, Velocity, OVERRIDE | Position, OVERRIDE | Velocity);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(ecs_has(world, e, Position));
|
|
test_assert(ecs_owns(world, e, Position));
|
|
test_assert(ecs_has(world, e, Velocity));
|
|
test_assert(ecs_owns(world, e, Velocity));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_auto_override_nested(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, Prefab, Position, Velocity, OVERRIDE | Position);
|
|
ECS_PREFAB(world, Prefab_2, (IsA, Prefab));
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab_2);
|
|
test_assert(ecs_has(world, e, Position));
|
|
test_assert(ecs_owns(world, e, Position));
|
|
test_assert(ecs_has(world, e, Velocity));
|
|
test_assert(!ecs_owns(world, e, Velocity));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_auto_override_pair(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_TAG(world, TgtA);
|
|
ECS_TAG(world, TgtB);
|
|
ECS_TAG(world, Rel);
|
|
|
|
ecs_entity_t base = ecs_new_id(world);
|
|
ecs_add_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtA));
|
|
test_assert(!ecs_has_pair(world, base, Rel, TgtA));
|
|
test_assert(!ecs_has_pair(world, base, Rel, TgtB));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtA)));
|
|
|
|
ecs_add_pair(world, base, Rel, TgtA);
|
|
ecs_add_pair(world, base, Rel, TgtB);
|
|
|
|
test_assert(ecs_has_pair(world, base, Rel, TgtA));
|
|
test_assert(ecs_has_pair(world, base, Rel, TgtB));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtA)));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(ecs_has_pair(world, inst, Rel, TgtA));
|
|
test_assert(ecs_has_pair(world, inst, Rel, TgtB));
|
|
|
|
test_assert(ecs_owns_pair(world, inst, Rel, TgtA));
|
|
test_assert(!ecs_owns_pair(world, inst, Rel, TgtB));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_auto_override_pair_w_component(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_TAG(world, TgtA);
|
|
ECS_TAG(world, TgtB);
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new_id(world);
|
|
ecs_add_id(world, base, ECS_OVERRIDE | ecs_pair(ecs_id(Position), TgtA));
|
|
test_assert(ecs_get_pair(world, base, Position, TgtA) == NULL);
|
|
|
|
ecs_set_pair(world, base, Position, TgtA, {10, 20});
|
|
ecs_set_pair(world, base, Position, TgtB, {20, 30});
|
|
|
|
const Position *pa = ecs_get_pair(world, base, Position, TgtA);
|
|
const Position *pb = ecs_get_pair(world, base, Position, TgtB);
|
|
test_assert(pa != NULL);
|
|
test_assert(pb != NULL);
|
|
test_int(pa->x, 10);
|
|
test_int(pa->y, 20);
|
|
test_int(pb->x, 20);
|
|
test_int(pb->y, 30);
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
|
|
const Position *pia = ecs_get_pair(world, inst, Position, TgtA);
|
|
const Position *pib = ecs_get_pair(world, inst, Position, TgtB);
|
|
test_assert(pia != pa);
|
|
test_assert(pib == pb);
|
|
test_int(pia->x, 10);
|
|
test_int(pia->y, 20);
|
|
|
|
test_assert(ecs_owns_pair(world, inst, ecs_id(Position), TgtA));
|
|
test_assert(!ecs_owns_pair(world, inst, ecs_id(Position), TgtB));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_auto_override_2_pairs(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_TAG(world, TgtA);
|
|
ECS_TAG(world, TgtB);
|
|
ECS_TAG(world, Rel);
|
|
|
|
ecs_entity_t base = ecs_new_id(world);
|
|
ecs_add_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtA));
|
|
ecs_add_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtB));
|
|
test_assert(!ecs_has_pair(world, base, Rel, TgtA));
|
|
test_assert(!ecs_has_pair(world, base, Rel, TgtB));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtA)));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtB)));
|
|
|
|
ecs_add_pair(world, base, Rel, TgtA);
|
|
ecs_add_pair(world, base, Rel, TgtB);
|
|
|
|
test_assert(ecs_has_pair(world, base, Rel, TgtA));
|
|
test_assert(ecs_has_pair(world, base, Rel, TgtB));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtA)));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(Rel, TgtB)));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(ecs_has_pair(world, inst, Rel, TgtA));
|
|
test_assert(ecs_has_pair(world, inst, Rel, TgtB));
|
|
|
|
test_assert(ecs_owns_pair(world, inst, Rel, TgtA));
|
|
test_assert(ecs_owns_pair(world, inst, Rel, TgtB));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_auto_override_2_pairs_w_component(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_TAG(world, TgtA);
|
|
ECS_TAG(world, TgtB);
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new_id(world);
|
|
ecs_add_id(world, base, ECS_OVERRIDE | ecs_pair(ecs_id(Position), TgtA));
|
|
ecs_add_id(world, base, ECS_OVERRIDE | ecs_pair(ecs_id(Position), TgtB));
|
|
test_assert(ecs_get_pair(world, base, Position, TgtA) == NULL);
|
|
test_assert(ecs_get_pair(world, base, Position, TgtB) == NULL);
|
|
|
|
ecs_set_pair(world, base, Position, TgtA, {10, 20});
|
|
ecs_set_pair(world, base, Position, TgtB, {20, 30});
|
|
|
|
const Position *pa = ecs_get_pair(world, base, Position, TgtA);
|
|
const Position *pb = ecs_get_pair(world, base, Position, TgtB);
|
|
test_assert(pa != NULL);
|
|
test_assert(pb != NULL);
|
|
test_int(pa->x, 10);
|
|
test_int(pa->y, 20);
|
|
test_int(pb->x, 20);
|
|
test_int(pb->y, 30);
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
|
|
const Position *pia = ecs_get_pair(world, inst, Position, TgtA);
|
|
const Position *pib = ecs_get_pair(world, inst, Position, TgtB);
|
|
test_assert(pia != pa);
|
|
test_assert(pib != pb);
|
|
test_int(pia->x, 10);
|
|
test_int(pia->y, 20);
|
|
test_int(pib->x, 20);
|
|
test_int(pib->y, 30);
|
|
|
|
test_assert(ecs_owns_pair(world, inst, ecs_id(Position), TgtA));
|
|
test_assert(ecs_owns_pair(world, inst, ecs_id(Position), TgtB));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_auto_override_2_pairs_same_obj(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_TAG(world, Tgt);
|
|
ECS_TAG(world, RelA);
|
|
ECS_TAG(world, RelB);
|
|
|
|
ecs_entity_t base = ecs_new_id(world);
|
|
ecs_add_id(world, base, ECS_OVERRIDE | ecs_pair(RelA, Tgt));
|
|
ecs_add_id(world, base, ECS_OVERRIDE | ecs_pair(RelB, Tgt));
|
|
test_assert(!ecs_has_pair(world, base, RelA, Tgt));
|
|
test_assert(!ecs_has_pair(world, base, RelB, Tgt));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(RelA, Tgt)));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(RelB, Tgt)));
|
|
|
|
ecs_add_pair(world, base, RelA, Tgt);
|
|
ecs_add_pair(world, base, RelB, Tgt);
|
|
|
|
test_assert(ecs_has_pair(world, base, RelA, Tgt));
|
|
test_assert(ecs_has_pair(world, base, RelB, Tgt));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(RelA, Tgt)));
|
|
test_assert(ecs_has_id(world, base, ECS_OVERRIDE | ecs_pair(RelB, Tgt)));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(ecs_has_pair(world, inst, RelA, Tgt));
|
|
test_assert(ecs_has_pair(world, inst, RelB, Tgt));
|
|
|
|
test_assert(ecs_owns_pair(world, inst, RelA, Tgt));
|
|
test_assert(ecs_owns_pair(world, inst, RelB, Tgt));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_instanceof_hierarchy(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, Base, Position);
|
|
ECS_PREFAB(world, BaseChild, Position, (ChildOf, Base));
|
|
|
|
ECS_PREFAB(world, ThePrefab, (IsA, Base));
|
|
|
|
/* Ensure that child has not been instantiated by making
|
|
* sure there are no matching entities for Position up to this point */
|
|
ecs_query_t *q = ecs_query_new(world, "Position(self|up)");
|
|
|
|
ecs_iter_t qit = ecs_query_iter(world, q);
|
|
test_assert(!ecs_query_next(&qit));
|
|
|
|
/* Instantiate the prefab */
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, ThePrefab);
|
|
test_assert(e != 0);
|
|
|
|
ecs_entity_t child = ecs_lookup_child(world, e, "BaseChild");
|
|
test_assert(child != 0);
|
|
|
|
qit = ecs_query_iter(world, q);
|
|
test_assert(ecs_query_next(&qit) == true);
|
|
test_int(qit.count, 1);
|
|
test_assert(ecs_query_next(&qit) == true);
|
|
test_int(qit.count, 1);
|
|
test_assert(ecs_query_next(&qit) == false);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_tag(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_TAG(world, Tag);
|
|
|
|
ecs_entity_t base = ecs_new(world, Tag);
|
|
ecs_set(world, base, Position, {10, 20});
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(ecs_has(world, e, Position));
|
|
test_assert(ecs_has(world, e, Tag));
|
|
|
|
ecs_add(world, e, Tag);
|
|
test_assert(ecs_has(world, e, Tag));
|
|
test_assert(ecs_owns(world, e, Tag));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_empty_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
ecs_add(world, e, Position);
|
|
test_assert(ecs_has(world, e, Position));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_instanceof_0(void) {
|
|
install_test_abort();
|
|
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
test_expect_abort();
|
|
|
|
/* Not allowed */
|
|
ecs_new_w_pair(world, EcsIsA, 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_instantiate_empty_child_table(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_PREFAB(world, Prefab, 0);
|
|
|
|
/* Forces creation of child table without children */
|
|
ecs_table_t *table = ecs_table_add_id(world, 0, ecs_childof(Prefab));
|
|
test_assert(table != NULL);
|
|
|
|
/* Main goal of this test is to ensure this doesn't crash */
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e != 0);
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, Prefab));
|
|
|
|
/* This shouldn't crash either */
|
|
ecs_delete(world, Prefab);
|
|
test_assert(!ecs_is_alive(world, Prefab));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_instantiate_emptied_child_table(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_PREFAB(world, Prefab, 0);
|
|
|
|
/* Create & remove prefab child */
|
|
ecs_entity_t child = ecs_new_w_pair(world, EcsChildOf, Prefab);
|
|
test_assert(child != 0);
|
|
|
|
/* Deleting the child will leave an initialized but empty table */
|
|
ecs_delete(world, child);
|
|
test_assert(!ecs_is_alive(world, child));
|
|
|
|
/* Main goal of this test is to ensure this doesn't crash */
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Prefab);
|
|
test_assert(e != 0);
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, Prefab));
|
|
|
|
/* This shouldn't crash either */
|
|
ecs_delete(world, Prefab);
|
|
test_assert(!ecs_is_alive(world, Prefab));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_2_prefabs(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ECS_PREFAB(world, PrefabA, Position);
|
|
ECS_PREFAB(world, PrefabB, Velocity);
|
|
|
|
ecs_set(world, PrefabA, Position, {10, 20});
|
|
ecs_set(world, PrefabB, Velocity, {1, 2});
|
|
|
|
ecs_entity_t e = ecs_new(world, 0);
|
|
ecs_add_pair(world, e, EcsIsA, PrefabA);
|
|
ecs_add_pair(world, e, EcsIsA, PrefabB);
|
|
|
|
ecs_add(world, e, Position);
|
|
ecs_add(world, e, Velocity);
|
|
|
|
test_assert(ecs_owns(world, e, Position));
|
|
test_assert(ecs_owns(world, e, Velocity));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
const Velocity *v = ecs_get(world, e, Velocity);
|
|
test_int(v->x, 1);
|
|
test_int(v->y, 2);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_rematch_after_add_instanceof_to_parent(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_query_t *q = ecs_query_new(world, "Position(parent)");
|
|
test_assert(q != NULL);
|
|
|
|
ecs_entity_t base = ecs_set(world, 0, Position, {10, 20});
|
|
ecs_entity_t parent = ecs_new(world, 0);
|
|
ecs_entity_t child = ecs_new_w_pair(world, EcsChildOf, parent);
|
|
test_assert(base != 0);
|
|
test_assert(parent != 0);
|
|
test_assert(child != 0);
|
|
|
|
ecs_add_pair(world, parent, EcsIsA, base);
|
|
|
|
ecs_iter_t it = ecs_query_iter(world, q);
|
|
test_bool(ecs_query_next(&it), true);
|
|
test_int(it.count, 1);
|
|
test_int(it.entities[0], child);
|
|
|
|
Position *p = ecs_field(&it, Position, 1);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
test_bool(ecs_query_next(&it), false);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_child_of_instance(void) {
|
|
install_test_abort();
|
|
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_entity_t base = ecs_new_w_id(world, EcsPrefab);
|
|
ecs_entity_t e = ecs_new_id(world);
|
|
|
|
ecs_add_pair(world, e, EcsChildOf, base);
|
|
|
|
test_expect_abort();
|
|
|
|
/* Should trigger an assert */
|
|
ecs_add_pair(world, e, EcsIsA, base);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_rematch_after_prefab_delete(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_set(world, 0, Position, {10, 20});
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
|
|
ecs_query_t *q = ecs_query_new(world, "Position(up)");
|
|
|
|
ecs_iter_t it = ecs_query_iter(world, q);
|
|
test_assert(ecs_query_next(&it));
|
|
test_int(it.count, 1);
|
|
test_int(it.entities[0], e);
|
|
Position *p = ecs_field(&it, Position, 1);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
test_assert(!ecs_query_next(&it));
|
|
|
|
ecs_delete(world, base);
|
|
|
|
it = ecs_query_iter(world, q);
|
|
test_assert(!ecs_query_next(&it));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_add_tag_w_low_id_to_instance(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_entity_t Tag = ecs_new_low_id(world);
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_set(world, 0, Position, {10, 20});
|
|
ecs_add_id(world, base, Tag);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
ecs_add(world, e, Position);
|
|
ecs_add_id(world, e, Tag);
|
|
|
|
test_assert(ecs_has_id(world, e, Tag));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_type_after_base_add(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new(world, Position);
|
|
test_assert(base != 0);
|
|
test_assert( ecs_get_type(world, base) != NULL);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_get_type(world, base) != NULL);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_type_after_recycled_base_add(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
test_assert( ecs_get_type(world, base) == NULL);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_new(world, Position);
|
|
test_assert(base != 0);
|
|
test_assert(ecs_entity_t_lo(base) != base); // Ensure recycled
|
|
test_assert( ecs_get_type(world, base) != NULL);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_get_type(world, base) != NULL);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_new_w_recycled_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
test_assert(ecs_entity_t_lo(base) != base); // Ensure recycled
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, base));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_add_recycled_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
test_assert(ecs_entity_t_lo(base) != base); // Ensure recycled
|
|
|
|
ecs_entity_t e = ecs_new(world, 0);
|
|
test_assert(e != 0);
|
|
ecs_add_pair(world, e, EcsIsA, base);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, base));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_remove_recycled_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
test_assert(ecs_entity_t_lo(base) != base); // Ensure recycled
|
|
|
|
ecs_entity_t e = ecs_new(world, 0);
|
|
test_assert(e != 0);
|
|
ecs_add_pair(world, e, EcsIsA, base);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, base));
|
|
|
|
ecs_remove_pair(world, e, EcsIsA, base);
|
|
test_assert( !ecs_has_pair(world, e, EcsIsA, base));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_from_recycled_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_set(world, 0, Position, {10, 20});
|
|
test_assert(base != 0);
|
|
test_assert(ecs_entity_t_lo(base) != base); // Ensure recycled
|
|
test_assert( ecs_get_type(world, base) != NULL);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, base));
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( !ecs_owns(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
test_assert(p == ecs_get(world, base, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_from_recycled_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_set(world, 0, Position, {10, 20});
|
|
test_assert(base != 0);
|
|
test_assert(ecs_entity_t_lo(base) != base); // Ensure recycled
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, base));
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( !ecs_owns(world, e, Position));
|
|
|
|
ecs_add(world, e, Position);
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( ecs_owns(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_remove_override_from_recycled_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_set(world, 0, Position, {10, 20});
|
|
test_assert(base != 0);
|
|
test_assert(ecs_entity_t_lo(base) != base); // Ensure recycled
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, base));
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( !ecs_owns(world, e, Position));
|
|
|
|
ecs_add(world, e, Position);
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( ecs_owns(world, e, Position));
|
|
|
|
ecs_remove(world, e, Position);
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( !ecs_owns(world, e, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_instantiate_tree_from_recycled_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new_w_id(world, EcsPrefab);
|
|
test_assert(base != 0);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_set(world, 0, Position, {10, 20});
|
|
test_assert(base != 0);
|
|
ecs_add_id(world, base, EcsPrefab);
|
|
|
|
ecs_entity_t base_child = ecs_new_w_pair(world, EcsChildOf, base);
|
|
test_assert(base_child != 0);
|
|
|
|
ecs_set_name(world, base_child, "Child");
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, base));
|
|
test_assert( ecs_has(world, e, Position));
|
|
test_assert( !ecs_owns(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
test_assert(p == ecs_get(world, base, Position));
|
|
|
|
ecs_entity_t instance_child = ecs_lookup_child(world, e, "Child");
|
|
test_assert(instance_child != 0);
|
|
test_assert( ecs_has_pair(world, instance_child, EcsChildOf, e));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_rematch_after_add_to_recycled_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_TAG(world, Tag);
|
|
|
|
ecs_query_t *q = ecs_query_new(world, "Tag, Position(up)");
|
|
|
|
ecs_entity_t base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
|
|
ecs_delete(world, base);
|
|
test_assert( !ecs_is_alive(world, base));
|
|
|
|
base = ecs_new(world, 0);
|
|
test_assert(base != 0);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(e != 0);
|
|
test_assert( ecs_has_pair(world, e, EcsIsA, base));
|
|
ecs_add(world, e, Tag);
|
|
|
|
ecs_iter_t it = ecs_query_iter(world, q);
|
|
test_bool(ecs_query_next(&it), false);
|
|
|
|
ecs_set(world, base, Position, {10, 20});
|
|
|
|
ecs_progress(world, 0);
|
|
|
|
it = ecs_query_iter(world, q);
|
|
test_bool(ecs_query_next(&it), true);
|
|
test_int(it.count, 1);
|
|
|
|
const Position *p = ecs_field(&it, Position, 2);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
test_assert(ecs_field_src(&it, 2) == base);
|
|
test_bool(ecs_query_next(&it), false);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_tag_from_2nd_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_TAG(world, Tag);
|
|
|
|
ecs_entity_t base_1 = ecs_new_id(world);
|
|
ecs_entity_t base_2 = ecs_new_w_id(world, Tag);
|
|
|
|
ecs_entity_t e = ecs_new_id(world);
|
|
ecs_add_pair(world, e, EcsIsA, base_1);
|
|
ecs_add_pair(world, e, EcsIsA, base_2);
|
|
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
|
|
test_assert(ecs_has_id(world, e, Tag));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_from_2nd_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base_1 = ecs_new_id(world);
|
|
ecs_entity_t base_2 = ecs_new(world, Position);
|
|
|
|
ecs_entity_t e = ecs_new_id(world);
|
|
ecs_add_pair(world, e, EcsIsA, base_1);
|
|
ecs_add_pair(world, e, EcsIsA, base_2);
|
|
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
test_assert(ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == ecs_get(world, base_2, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_from_1st_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base_1 = ecs_new(world, Position);
|
|
ecs_entity_t base_2 = ecs_new(world, Position);
|
|
|
|
ecs_entity_t e = ecs_new_id(world);
|
|
ecs_add_pair(world, e, EcsIsA, base_1);
|
|
ecs_add_pair(world, e, EcsIsA, base_2);
|
|
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
|
|
test_assert(ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == ecs_get(world, base_1, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_from_2nd_base_of_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base_1 = ecs_new_id(world);
|
|
ecs_entity_t base_2 = ecs_new(world, Position);
|
|
|
|
ecs_entity_t base_3 = ecs_new_id(world);
|
|
ecs_add_pair(world, base_3, EcsIsA, base_1);
|
|
ecs_add_pair(world, base_3, EcsIsA, base_2);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base_3);
|
|
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
|
|
test_assert(ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == ecs_get(world, base_2, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_from_1st_base_of_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base_1 = ecs_new(world, Position);
|
|
ecs_entity_t base_2 = ecs_new(world, Position);
|
|
|
|
ecs_entity_t base_3 = ecs_new_id(world);
|
|
ecs_add_pair(world, base_3, EcsIsA, base_1);
|
|
ecs_add_pair(world, base_3, EcsIsA, base_2);
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base_3);
|
|
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
|
|
test_assert(ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == ecs_get(world, base_1, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_from_2nd_base_prefab_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_PREFAB(world, base_1, 0);
|
|
ECS_PREFAB(world, base_2, Position);
|
|
|
|
ecs_entity_t e = ecs_new_id(world);
|
|
ecs_add_pair(world, e, EcsIsA, base_1);
|
|
ecs_add_pair(world, e, EcsIsA, base_2);
|
|
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
|
|
test_assert(ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == ecs_get(world, base_2, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_from_1st_base_prefab_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_PREFAB(world, base_1, Position);
|
|
ECS_PREFAB(world, base_2, Position);
|
|
|
|
ecs_entity_t e = ecs_new_id(world);
|
|
ecs_add_pair(world, e, EcsIsA, base_1);
|
|
ecs_add_pair(world, e, EcsIsA, base_2);
|
|
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
|
|
test_assert(ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == ecs_get(world, base_1, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_from_2nd_base_of_base_prefab_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_PREFAB(world, base_1, 0);
|
|
ECS_PREFAB(world, base_2, Position);
|
|
ECS_PREFAB(world, base_3, (IsA, base_1), (IsA, base_2));
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base_3);
|
|
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
|
|
test_assert(ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == ecs_get(world, base_2, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_from_1st_base_of_base_prefab_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_PREFAB(world, base_1, Position);
|
|
ECS_PREFAB(world, base_2, Position);
|
|
ECS_PREFAB(world, base_3, (IsA, base_1), (IsA, base_2));
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, base_3);
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_1));
|
|
test_assert(ecs_has_pair(world, e, EcsIsA, base_2));
|
|
|
|
test_assert(ecs_has(world, e, Position));
|
|
|
|
const Position *p = ecs_get(world, e, Position);
|
|
test_assert(p != NULL);
|
|
test_assert(p == ecs_get(world, base_1, Position));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_fail_on_override_final(void) {
|
|
install_test_abort();
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ecs_entity_t base = ecs_new_w_id(world, EcsFinal);
|
|
|
|
test_expect_abort();
|
|
ecs_new_w_pair(world, EcsIsA, base);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
int child_count(ecs_world_t *world, ecs_entity_t e) {
|
|
int32_t count = 0;
|
|
ecs_iter_t it = ecs_term_iter(world, &(ecs_term_t){
|
|
ecs_pair(EcsChildOf, e
|
|
)});
|
|
|
|
while (ecs_term_next(&it)) {
|
|
count += it.count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
void Prefab_instantiate_tree_once(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_PREFAB(world, Cannon, 0);
|
|
ECS_PREFAB(world, Turret, 0);
|
|
ECS_PREFAB(world, CannonA, (IsA, Cannon), (ChildOf, Turret));
|
|
ECS_PREFAB(world, CannonB, (IsA, Cannon), (ChildOf, Turret));
|
|
|
|
ECS_PREFAB(world, SpaceShip, 0);
|
|
ECS_PREFAB(world, TurretA, (IsA, Turret), (ChildOf, SpaceShip));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, SpaceShip);
|
|
test_assert(inst != 0);
|
|
test_int(1, child_count(world, inst));
|
|
|
|
ecs_entity_t turret_a = ecs_lookup_child(world, inst, "TurretA");
|
|
test_assert(turret_a != 0);
|
|
test_int(2, child_count(world, turret_a));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_nested_prefab_w_named_children(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_PREFAB(world, Cannon, 0);
|
|
|
|
ECS_PREFAB(world, Turret, 0);
|
|
ecs_set_scope(world, Turret);
|
|
ECS_ENTITY(world, CannonA, (IsA, Cannon));
|
|
ecs_set_scope(world, 0);
|
|
|
|
ECS_PREFAB(world, SpaceShip, 0);
|
|
ecs_set_scope(world, SpaceShip);
|
|
ECS_PREFAB(world, TurretA, (IsA, Turret));
|
|
ecs_set_scope(world, 0);
|
|
|
|
test_assert( ecs_has_pair(world, CannonA, EcsChildOf, Turret));
|
|
test_assert( ecs_has_pair(world, CannonA, EcsIsA, Cannon));
|
|
test_str("CannonA", ecs_get_name(world, CannonA));
|
|
|
|
test_assert( ecs_has_pair(world, TurretA, EcsChildOf, SpaceShip));
|
|
test_assert( ecs_has_pair(world, TurretA, EcsIsA, Turret));
|
|
test_str("TurretA", ecs_get_name(world, TurretA));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_dont_copy_children_for_non_prefab_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ECS_ENTITY(world, Base, Position);
|
|
ECS_ENTITY(world, Child, (ChildOf, Base));
|
|
|
|
ecs_entity_t e = ecs_new_w_pair(world, EcsIsA, Base);
|
|
test_assert(e != 0);
|
|
test_assert(ecs_get(world, e, Position) != NULL);
|
|
|
|
test_assert(ecs_lookup_child(world, e, "Child") == 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_pair_from_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_TAG(world, Obj);
|
|
|
|
ecs_entity_t base = ecs_set_pair(world, 0, Position, Obj, {10, 20});
|
|
test_assert(ecs_has_pair(world, base, ecs_id(Position), Obj));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(ecs_has_pair(world, inst, ecs_id(Position), Obj));
|
|
|
|
const Position *p = ecs_get_pair(world, inst, Position, Obj);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
test_assert(p == ecs_get_pair(world, base, Position, Obj));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_get_component_pair_from_prefab_base(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_TAG(world, Obj);
|
|
|
|
ecs_entity_t base = ecs_new_w_id(world, EcsPrefab);
|
|
ecs_set_pair(world, base, Position, Obj, {10, 20});
|
|
test_assert(ecs_has_pair(world, base, ecs_id(Position), Obj));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(ecs_has_pair(world, inst, ecs_id(Position), Obj));
|
|
|
|
const Position *p = ecs_get_pair(world, inst, Position, Obj);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
test_assert(p == ecs_get_pair(world, base, Position, Obj));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_dont_inherit(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_add_id(world, ecs_id(Position), EcsDontInherit);
|
|
|
|
ecs_set_hooks(world, Position, {
|
|
.ctor = ecs_default_ctor
|
|
});
|
|
|
|
ecs_entity_t base = ecs_set(world, 0, Position, {10, 20});
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert( !ecs_has(world, inst, Position));
|
|
|
|
ecs_add(world, inst, Position);
|
|
test_assert( ecs_has(world, inst, Position));
|
|
const Position *p = ecs_get(world, inst, Position);
|
|
test_int(p->x, 0);
|
|
test_int(p->y, 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_switch(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_ENTITY(world, Movement, Union);
|
|
ECS_TAG(world, Walking);
|
|
ECS_TAG(world, Running);
|
|
|
|
ecs_entity_t p = ecs_new_w_pair(world, Movement, Running);
|
|
test_assert( ecs_has_pair(world, p, Movement, Running));
|
|
|
|
ecs_entity_t i = ecs_new_w_pair(world, EcsIsA, p);
|
|
test_assert( ecs_has_pair(world, i, Movement, Running));
|
|
test_assert( !ecs_has_pair(world, i, Movement, Walking));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_child_w_dont_inherit_component(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_ENTITY(world, TagA, DontInherit);
|
|
ECS_TAG(world, TagB);
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_child = ecs_new_prefab(world, "Base.Child");
|
|
ecs_add(world, base_child, TagA);
|
|
ecs_add(world, base_child, TagB);
|
|
test_assert(base != 0);
|
|
test_assert(base_child != 0);
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_child = ecs_lookup_child(world, inst, "Child");
|
|
test_assert(inst_child != 0);
|
|
test_assert(!ecs_has(world, inst_child, TagA));
|
|
test_assert(ecs_has(world, inst_child, TagB));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_child_override(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_TAG(world, Foo);
|
|
ECS_TAG(world, Bar);
|
|
|
|
ecs_entity_t turret = ecs_new_prefab(world, "Turret");
|
|
ecs_entity_t turret_head = ecs_new_prefab(world, "Turret.Head");
|
|
ecs_add(world, turret_head, Foo);
|
|
|
|
ecs_entity_t railgun = ecs_new_prefab(world, "Railgun");
|
|
ecs_add_pair(world, railgun, EcsIsA, turret);
|
|
ecs_entity_t railgun_head = ecs_new_prefab(world, "Railgun.Head");
|
|
ecs_add(world, railgun_head, Bar);
|
|
|
|
ecs_entity_t inst = ecs_new_entity(world, "inst");
|
|
ecs_add_pair(world, inst, EcsIsA, railgun);
|
|
|
|
ecs_entity_t head = ecs_lookup_child(world, inst, "Head");
|
|
test_assert(head != 0);
|
|
test_assert(ecs_has(world, head, Foo));
|
|
test_assert(ecs_has(world, head, Bar));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_child_override_w_exclusive_pair(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_ENTITY(world, Rel, Exclusive);
|
|
ECS_TAG(world, ObjA);
|
|
ECS_TAG(world, ObjB);
|
|
|
|
ecs_entity_t turret = ecs_new_prefab(world, "Turret");
|
|
ecs_entity_t turret_head = ecs_new_prefab(world, "Turret.Head");
|
|
ecs_add_pair(world, turret_head, Rel, ObjA);
|
|
test_assert(ecs_has_pair(world, turret_head, Rel, ObjA));
|
|
|
|
ecs_entity_t railgun = ecs_new_prefab(world, "Railgun");
|
|
ecs_add_pair(world, railgun, EcsIsA, turret);
|
|
ecs_entity_t railgun_head = ecs_new_prefab(world, "Railgun.Head");
|
|
ecs_add_pair(world, railgun_head, Rel, ObjB);
|
|
test_assert(!ecs_has_pair(world, railgun_head, Rel, ObjA));
|
|
test_assert(ecs_has_pair(world, railgun_head, Rel, ObjB));
|
|
|
|
ecs_entity_t inst = ecs_new_entity(world, "inst");
|
|
ecs_add_pair(world, inst, EcsIsA, railgun);
|
|
|
|
ecs_entity_t head = ecs_lookup_child(world, inst, "Head");
|
|
test_assert(head != 0);
|
|
test_assert(!ecs_has_pair(world, head, Rel, ObjA));
|
|
test_assert(ecs_has_pair(world, head, Rel, ObjB));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_1_slot(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot = ecs_new_prefab(world, "Base.Slot");
|
|
ecs_add_pair(world, base_slot, EcsSlotOf, base);
|
|
test_assert(ecs_has_pair(world, base_slot, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot, EcsSlotOf, base));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_slot = ecs_get_target(world, inst, base_slot, 0);
|
|
test_assert(inst_slot != 0);
|
|
test_str(ecs_get_name(world, inst_slot), "Slot");
|
|
test_assert(!ecs_has_pair(world, inst_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot, EcsChildOf, inst));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_2_slots(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot_a = ecs_new_prefab(world, "Base.SlotA");
|
|
ecs_entity_t base_slot_b = ecs_new_prefab(world, "Base.SlotB");
|
|
ecs_add_pair(world, base_slot_a, EcsSlotOf, base);
|
|
ecs_add_pair(world, base_slot_b, EcsSlotOf, base);
|
|
test_assert(ecs_has_pair(world, base_slot_a, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot_a, EcsSlotOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot_b, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot_b, EcsSlotOf, base));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_slot_a = ecs_get_target(world, inst, base_slot_a, 0);
|
|
test_assert(inst_slot_a != 0);
|
|
test_str(ecs_get_name(world, inst_slot_a), "SlotA");
|
|
test_assert(!ecs_has_pair(world, inst_slot_a, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot_a, EcsChildOf, inst));
|
|
|
|
ecs_entity_t inst_slot_b = ecs_get_target(world, inst, base_slot_b, 0);
|
|
test_assert(inst_slot_b != 0);
|
|
test_str(ecs_get_name(world, inst_slot_b), "SlotB");
|
|
test_assert(!ecs_has_pair(world, inst_slot_b, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot_b, EcsChildOf, inst));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_nested_slot(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot = ecs_new_prefab(world, "Base.Slot");
|
|
ecs_entity_t base_slot_slot = ecs_new_prefab(world, "Base.Slot.Slot");
|
|
ecs_add_pair(world, base_slot, EcsSlotOf, base);
|
|
ecs_add_pair(world, base_slot_slot, EcsSlotOf, base);
|
|
test_assert(ecs_has_pair(world, base_slot, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot, EcsSlotOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot_slot, EcsChildOf, base_slot));
|
|
test_assert(ecs_has_pair(world, base_slot_slot, EcsSlotOf, base));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_slot = ecs_get_target(world, inst, base_slot, 0);
|
|
test_assert(inst_slot != 0);
|
|
test_str(ecs_get_name(world, inst_slot), "Slot");
|
|
test_assert(!ecs_has_pair(world, inst_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot, EcsChildOf, inst));
|
|
|
|
ecs_entity_t inst_slot_slot = ecs_get_target(world, inst, base_slot_slot, 0);
|
|
test_assert(inst_slot_slot != 0);
|
|
test_assert(inst_slot_slot != inst_slot);
|
|
test_str(ecs_get_name(world, inst_slot_slot), "Slot");
|
|
test_assert(!ecs_has_pair(world, inst_slot_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot_slot, EcsChildOf, inst_slot));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_w_mixed_slots(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot = ecs_new_prefab(world, "Base.Slot");
|
|
ecs_entity_t base_slot_slot = ecs_new_prefab(world, "Base.Slot.Slot");
|
|
ecs_add_pair(world, base_slot, EcsSlotOf, base);
|
|
ecs_add_pair(world, base_slot_slot, EcsSlotOf, base_slot);
|
|
test_assert(ecs_has_pair(world, base_slot, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot, EcsSlotOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot_slot, EcsChildOf, base_slot));
|
|
test_assert(ecs_has_pair(world, base_slot_slot, EcsSlotOf, base_slot));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_slot = ecs_get_target(world, inst, base_slot, 0);
|
|
test_assert(inst_slot != 0);
|
|
test_str(ecs_get_name(world, inst_slot), "Slot");
|
|
test_assert(!ecs_has_pair(world, inst_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot, EcsChildOf, inst));
|
|
|
|
ecs_entity_t inst_slot_slot = ecs_get_target(world, inst, base_slot_slot, 0);
|
|
test_assert(inst_slot_slot == 0);
|
|
|
|
inst_slot_slot = ecs_get_target(world, inst_slot, base_slot_slot, 0);
|
|
test_assert(inst_slot_slot != 0);
|
|
test_assert(inst_slot_slot != inst_slot);
|
|
test_str(ecs_get_name(world, inst_slot_slot), "Slot");
|
|
test_assert(!ecs_has_pair(world, inst_slot_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot_slot, EcsChildOf, inst_slot));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_variant_w_slot(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t variant = ecs_new_prefab(world, "Variant");
|
|
ecs_entity_t variant_slot = ecs_new_prefab(world, "Variant.Slot");
|
|
ecs_add_pair(world, variant, EcsIsA, base);
|
|
ecs_add_pair(world, variant_slot, EcsSlotOf, variant);
|
|
test_assert(ecs_has_pair(world, variant_slot, EcsChildOf, variant));
|
|
test_assert(ecs_has_pair(world, variant_slot, EcsSlotOf, variant));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, variant);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_slot = ecs_get_target(world, inst, variant_slot, 0);
|
|
test_assert(inst_slot != 0);
|
|
test_str(ecs_get_name(world, inst_slot), "Slot");
|
|
test_assert(!ecs_has_pair(world, inst_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot, EcsChildOf, inst));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_variant_w_base_slot(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot = ecs_new_prefab(world, "Base.Slot");
|
|
ecs_add_pair(world, base_slot, EcsSlotOf, base);
|
|
test_assert(ecs_has_pair(world, base_slot, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot, EcsSlotOf, base));
|
|
|
|
ecs_entity_t variant = ecs_new_prefab(world, "Variant");
|
|
ecs_add_pair(world, variant, EcsIsA, base);
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, variant);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_slot = ecs_get_target(world, inst, base_slot, 0);
|
|
test_assert(inst_slot != 0);
|
|
test_str(ecs_get_name(world, inst_slot), "Slot");
|
|
test_assert(!ecs_has_pair(world, inst_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot, EcsChildOf, inst));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_variant_w_mixed_slots(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot = ecs_new_prefab(world, "Base.BaseSlot");
|
|
ecs_add_pair(world, base_slot, EcsSlotOf, base);
|
|
test_assert(ecs_has_pair(world, base_slot, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot, EcsSlotOf, base));
|
|
|
|
ecs_entity_t variant = ecs_new_prefab(world, "Variant");
|
|
ecs_add_pair(world, variant, EcsIsA, base);
|
|
ecs_entity_t variant_slot = ecs_new_prefab(world, "Variant.VariantSlot");
|
|
ecs_add_pair(world, variant, EcsIsA, base);
|
|
ecs_add_pair(world, variant_slot, EcsSlotOf, variant);
|
|
test_assert(ecs_has_pair(world, variant_slot, EcsChildOf, variant));
|
|
test_assert(ecs_has_pair(world, variant_slot, EcsSlotOf, variant));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, variant);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_base_slot = ecs_get_target(world, inst, base_slot, 0);
|
|
test_assert(inst_base_slot != 0);
|
|
test_str(ecs_get_name(world, inst_base_slot), "BaseSlot");
|
|
test_assert(!ecs_has_pair(world, inst_base_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_base_slot, EcsChildOf, inst));
|
|
|
|
ecs_entity_t inst_variant_slot = ecs_get_target(world, inst, variant_slot, 0);
|
|
test_assert(inst_variant_slot != 0);
|
|
test_assert(inst_variant_slot != inst_base_slot);
|
|
test_str(ecs_get_name(world, inst_variant_slot), "VariantSlot");
|
|
test_assert(!ecs_has_pair(world, inst_variant_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_variant_slot, EcsChildOf, inst));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_slot(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot = ecs_new_prefab(world, "Base.Slot");
|
|
ecs_add_pair(world, base_slot, EcsSlotOf, base);
|
|
test_assert(ecs_has_pair(world, base_slot, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot, EcsSlotOf, base));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_slot = ecs_get_target(world, inst, base_slot, 0);
|
|
test_assert(inst_slot != 0);
|
|
test_str(ecs_get_name(world, inst_slot), "Slot");
|
|
test_assert(!ecs_has_pair(world, inst_slot, EcsSlotOf, EcsWildcard));
|
|
test_assert(ecs_has_pair(world, inst_slot, EcsChildOf, inst));
|
|
|
|
ecs_entity_t slot_override = ecs_new_id(world);
|
|
ecs_add_pair(world, inst, base_slot, slot_override);
|
|
|
|
test_assert(ecs_has_pair(world, inst, base_slot, slot_override));
|
|
test_assert(!ecs_has_pair(world, inst, base_slot, inst_slot));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_2_instances_w_slots_same_table(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot = ecs_new_prefab(world, "Base.Slot");
|
|
ecs_add_pair(world, base_slot, EcsSlotOf, base);
|
|
test_assert(ecs_has_pair(world, base_slot, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot, EcsSlotOf, base));
|
|
|
|
ecs_entity_t inst_1 = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst_1 != 0);
|
|
ecs_entity_t inst_2 = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst_2 != 0);
|
|
|
|
ecs_entity_t slot_1 = ecs_get_target(world, inst_1, base_slot, 0);
|
|
test_assert(slot_1 != 0);
|
|
ecs_entity_t slot_2 = ecs_get_target(world, inst_2, base_slot, 0);
|
|
test_assert(slot_2 != 0);
|
|
test_assert(slot_1 != slot_2);
|
|
|
|
/* Make sure slots don't fragment */
|
|
test_assert(ecs_get_table(world, inst_1) == ecs_get_table(world, inst_2));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_slot_has_union(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_slot = ecs_new_prefab(world, "Base.Slot");
|
|
ecs_add_pair(world, base_slot, EcsSlotOf, base);
|
|
test_assert(ecs_has_pair(world, base_slot, EcsChildOf, base));
|
|
test_assert(ecs_has_pair(world, base_slot, EcsSlotOf, base));
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t inst_slot = ecs_get_target(world, inst, base_slot, 0);
|
|
test_assert(inst_slot != 0);
|
|
test_assert(base_slot != 0);
|
|
|
|
test_assert( ecs_has_id(world, base_slot, EcsUnion));
|
|
test_assert( !ecs_has_id(world, inst_slot, EcsUnion));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_slot_override(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t turret = ecs_new_prefab(world, "Turret");
|
|
ecs_entity_t turret_base = ecs_new_prefab(world, "Turret.Base");
|
|
ecs_add_pair(world, turret_base, EcsSlotOf, turret);
|
|
ecs_entity_t turret_head = ecs_new_prefab(world, "Turret.Head");
|
|
ecs_add_pair(world, turret_head, EcsSlotOf, turret);
|
|
|
|
ecs_entity_t railgun = ecs_new_prefab(world, "Railgun");
|
|
ecs_add_pair(world, railgun, EcsIsA, turret);
|
|
ecs_entity_t railgun_head = ecs_new_prefab(world, "Railgun.Head");
|
|
|
|
test_assert(ecs_has_pair(world, railgun_head, EcsSlotOf, turret));
|
|
ecs_add_pair(world, railgun_head, EcsSlotOf, railgun);
|
|
test_assert(ecs_has_pair(world, railgun_head, EcsSlotOf, railgun));
|
|
test_assert(!ecs_has_pair(world, railgun_head, EcsSlotOf, turret));
|
|
|
|
ecs_entity_t railgun_beam = ecs_new_prefab(world, "Railgun.Beam");
|
|
ecs_add_pair(world, railgun_beam, EcsSlotOf, railgun);
|
|
|
|
ecs_entity_t inst = ecs_new_entity(world, "inst");
|
|
ecs_add_pair(world, inst, EcsIsA, railgun);
|
|
|
|
ecs_entity_t head = ecs_get_target(world, inst, turret_head, 0);
|
|
ecs_entity_t head_r = ecs_get_target(world, inst, railgun_head, 0);
|
|
ecs_entity_t base = ecs_get_target(world, inst, turret_base, 0);
|
|
ecs_entity_t beam = ecs_get_target(world, inst, railgun_beam, 0);
|
|
|
|
test_assert(head == 0);
|
|
test_assert(head_r != 0);
|
|
test_assert(base != 0);
|
|
test_assert(beam != 0);
|
|
|
|
char *path = ecs_get_fullpath(world, head_r);
|
|
test_str(path, "inst.Head");
|
|
ecs_os_free(path);
|
|
|
|
path = ecs_get_fullpath(world, base);
|
|
test_str(path, "inst.Base");
|
|
ecs_os_free(path);
|
|
|
|
path = ecs_get_fullpath(world, beam);
|
|
test_str(path, "inst.Beam");
|
|
ecs_os_free(path);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_base_slot_override(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t turret = ecs_new_prefab(world, "Turret");
|
|
ecs_entity_t turret_base = ecs_new_prefab(world, "Turret.Base");
|
|
ecs_add_pair(world, turret_base, EcsSlotOf, turret);
|
|
ecs_entity_t turret_head = ecs_new_prefab(world, "Turret.Head");
|
|
ecs_add_pair(world, turret_head, EcsSlotOf, turret);
|
|
|
|
ecs_entity_t railgun = ecs_new_prefab(world, "Railgun");
|
|
ecs_add_pair(world, railgun, EcsIsA, turret);
|
|
ecs_entity_t railgun_head = ecs_new_prefab(world, "Railgun.Head");
|
|
test_assert(ecs_has_pair(world, railgun_head, EcsSlotOf, turret));
|
|
|
|
ecs_entity_t railgun_beam = ecs_new_prefab(world, "Railgun.Beam");
|
|
ecs_add_pair(world, railgun_beam, EcsSlotOf, railgun);
|
|
|
|
ecs_entity_t inst = ecs_new_entity(world, "inst");
|
|
ecs_add_pair(world, inst, EcsIsA, railgun);
|
|
|
|
ecs_entity_t head = ecs_get_target(world, inst, turret_head, 0);
|
|
ecs_entity_t head_r = ecs_get_target(world, inst, railgun_head, 0);
|
|
ecs_entity_t base = ecs_get_target(world, inst, turret_base, 0);
|
|
ecs_entity_t beam = ecs_get_target(world, inst, railgun_beam, 0);
|
|
|
|
test_assert(head != 0);
|
|
test_assert(head_r == 0);
|
|
test_assert(base != 0);
|
|
test_assert(beam != 0);
|
|
|
|
char *path = ecs_get_fullpath(world, head);
|
|
test_str(path, "inst.Head");
|
|
ecs_os_free(path);
|
|
|
|
path = ecs_get_fullpath(world, base);
|
|
test_str(path, "inst.Base");
|
|
ecs_os_free(path);
|
|
|
|
path = ecs_get_fullpath(world, beam);
|
|
test_str(path, "inst.Beam");
|
|
ecs_os_free(path);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_prefab_child_w_union(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_ENTITY(world, Rel, Union);
|
|
ECS_TAG(world, TgtA);
|
|
ECS_TAG(world, TgtB);
|
|
ECS_TAG(world, TgtC);
|
|
|
|
ecs_entity_t base = ecs_new_prefab(world, "Base");
|
|
ecs_entity_t base_child_a = ecs_new_prefab(world, "Base.ChildA");
|
|
ecs_entity_t base_child_b = ecs_new_prefab(world, "Base.ChildB");
|
|
ecs_entity_t base_child_c = ecs_new_prefab(world, "Base.ChildC");
|
|
ecs_add_pair(world, base_child_a, Rel, TgtA);
|
|
ecs_add_pair(world, base_child_b, Rel, TgtB);
|
|
ecs_add_pair(world, base_child_c, Rel, TgtC);
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
test_assert(inst != 0);
|
|
|
|
ecs_entity_t child_a = ecs_lookup_child(world, inst, "ChildA");
|
|
ecs_entity_t child_b = ecs_lookup_child(world, inst, "ChildB");
|
|
ecs_entity_t child_c = ecs_lookup_child(world, inst, "ChildC");
|
|
test_assert(child_a != 0);
|
|
test_assert(child_b != 0);
|
|
test_assert(child_c != 0);
|
|
|
|
test_assert(ecs_has_pair(world, child_a, Rel, TgtA));
|
|
test_assert(ecs_has_pair(world, child_b, Rel, TgtB));
|
|
test_assert(ecs_has_pair(world, child_c, Rel, TgtC));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_twice_w_add(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new_id(world);
|
|
ecs_set(world, base, Position, {10});
|
|
ecs_override(world, base, Position);
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, base);
|
|
ecs_set(world, e1, Position, { 20 });
|
|
|
|
ecs_entity_t e2 = ecs_new_w_pair(world, EcsIsA, base);
|
|
ecs_add(world, e2, Position);
|
|
|
|
const Position *ptr = ecs_get(world, e1, Position);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 20);
|
|
|
|
ptr = ecs_get(world, e2, Position);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 10);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_twice_w_set(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_entity_t base = ecs_new_id(world);
|
|
ecs_set(world, base, Position, {10});
|
|
ecs_override(world, base, Position);
|
|
|
|
ecs_entity_t e1 = ecs_new_w_pair(world, EcsIsA, base);
|
|
ecs_set(world, e1, Position, { 20 });
|
|
|
|
ecs_entity_t e2 = ecs_new_w_pair(world, EcsIsA, base);
|
|
ecs_set(world, e2, Position, {30});
|
|
|
|
const Position *ptr = ecs_get(world, e1, Position);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 20);
|
|
|
|
ptr = ecs_get(world, e2, Position);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 30);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static int position_copy_invoked = 0;
|
|
|
|
static ECS_COPY(Position, dst, src, {
|
|
dst->x = src->x;
|
|
dst->y = src->y;
|
|
position_copy_invoked ++;
|
|
})
|
|
|
|
void Prefab_auto_override_copy_once(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
|
|
ecs_set_hooks(world, Position, {
|
|
.copy = ecs_copy(Position)
|
|
});
|
|
|
|
ecs_entity_t base = ecs_new_id(world);
|
|
ecs_set(world, base, Position, {10, 20});
|
|
ecs_override(world, base, Position);
|
|
|
|
test_int(position_copy_invoked, 1);
|
|
position_copy_invoked = 0;
|
|
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsIsA, base);
|
|
const Position *ptr = ecs_get(world, inst, Position);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 10);
|
|
test_int(ptr->y, 20);
|
|
|
|
test_int(position_copy_invoked, 1);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_always_override(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ecs_add_id(world, ecs_id(Position), EcsAlwaysOverride);
|
|
|
|
ecs_entity_t b = ecs_new_id(world);
|
|
ecs_set(world, b, Position, {10, 20});
|
|
ecs_set(world, b, Velocity, {1, 2});
|
|
|
|
ecs_entity_t i = ecs_new_w_pair(world, EcsIsA, b);
|
|
test_assert(ecs_has(world, i, Position));
|
|
test_assert(ecs_has(world, i, Velocity));
|
|
test_assert(ecs_owns(world, i, Position));
|
|
test_assert(!ecs_owns(world, i, Velocity));
|
|
|
|
{
|
|
const Position *ptr = ecs_get(world, i, Position);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 10);
|
|
test_int(ptr->y, 20);
|
|
}
|
|
|
|
{
|
|
const Velocity *ptr = ecs_get(world, i, Velocity);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 1);
|
|
test_int(ptr->y, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_always_override_pair(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ECS_TAG(world, RelA);
|
|
ECS_TAG(world, RelB);
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
|
|
ecs_add_id(world, RelA, EcsAlwaysOverride);
|
|
|
|
ecs_entity_t b = ecs_new_id(world);
|
|
ecs_set_pair_second(world, b, RelA, Position, {10, 20});
|
|
ecs_set_pair_second(world, b, RelB, Velocity, {1, 2});
|
|
|
|
ecs_entity_t i = ecs_new_w_pair(world, EcsIsA, b);
|
|
test_assert(ecs_has_pair(world, i, RelA, ecs_id(Position)));
|
|
test_assert(ecs_has_pair(world, i, RelB, ecs_id(Velocity)));
|
|
test_assert(ecs_owns_pair(world, i, RelA, ecs_id(Position)));
|
|
test_assert(!ecs_owns_pair(world, i, RelB, ecs_id(Velocity)));
|
|
|
|
{
|
|
const Position *ptr = ecs_get_pair_second(world, i, RelA, Position);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 10);
|
|
test_int(ptr->y, 20);
|
|
}
|
|
|
|
{
|
|
const Velocity *ptr = ecs_get_pair_second(world, i, RelB, Velocity);
|
|
test_assert(ptr != NULL);
|
|
test_int(ptr->x, 1);
|
|
test_int(ptr->y, 2);
|
|
}
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_child_of_prefab_is_prefab(void) {
|
|
ecs_world_t *world = ecs_mini();
|
|
|
|
ecs_entity_t base = ecs_new_w_id(world, EcsPrefab);
|
|
ecs_entity_t inst = ecs_new_w_pair(world, EcsChildOf, base);
|
|
test_assert(ecs_has_id(world, inst, EcsPrefab));
|
|
ecs_entity_t inst_child = ecs_new_w_pair(world, EcsChildOf, inst);
|
|
test_assert(ecs_has_id(world, inst_child, EcsPrefab));
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void Prefab_override_exclusive(void) {
|
|
ecs_world_t* ecs = ecs_mini();
|
|
|
|
ECS_ENTITY(ecs, Rel, Exclusive);
|
|
|
|
ecs_entity_t t1 = ecs_new_id(ecs);
|
|
ecs_entity_t t2 = ecs_new_id(ecs);
|
|
|
|
ecs_entity_t e = ecs_new_id(ecs);
|
|
ecs_add_pair(ecs, e, Rel, t1);
|
|
|
|
ecs_entity_t p = ecs_new_id(ecs);
|
|
ecs_override_pair(ecs, p, Rel, t2);
|
|
|
|
ecs_add_pair(ecs, e, EcsIsA, p);
|
|
|
|
test_assert(ecs_has_pair(ecs, e, Rel, t2));
|
|
test_assert(!ecs_has_pair(ecs, e, Rel, t1));
|
|
|
|
ecs_fini(ecs);
|
|
}
|
|
|
|
void Prefab_override_exclusive_2_lvls(void) {
|
|
ecs_world_t* ecs = ecs_mini();
|
|
|
|
ECS_ENTITY(ecs, Rel, Exclusive);
|
|
|
|
ecs_entity_t t1 = ecs_new_id(ecs);
|
|
ecs_entity_t t2 = ecs_new_id(ecs);
|
|
ecs_entity_t t3 = ecs_new_id(ecs);
|
|
|
|
ecs_entity_t e = ecs_new_id(ecs);
|
|
ecs_add_pair(ecs, e, Rel, t1);
|
|
|
|
ecs_entity_t p = ecs_new_id(ecs);
|
|
ecs_override_pair(ecs, p, Rel, t2);
|
|
|
|
ecs_entity_t p2 = ecs_new_id(ecs);
|
|
ecs_override_pair(ecs, p2, Rel, t3);
|
|
ecs_add_pair(ecs, p2, EcsIsA, p);
|
|
|
|
ecs_add_pair(ecs, e, EcsIsA, p2);
|
|
|
|
test_assert(ecs_has_pair(ecs, e, Rel, t2));
|
|
test_assert(!ecs_has_pair(ecs, e, Rel, t1));
|
|
test_assert(!ecs_has_pair(ecs, e, Rel, t3));
|
|
|
|
ecs_fini(ecs);
|
|
}
|
|
|
|
static
|
|
ecs_entity_t make_prefabs(ecs_world_t *ecs) {
|
|
ecs_entity_t root = ecs_new_w_id(ecs, EcsPrefab);
|
|
ecs_entity_t parent = ecs_new_w_pair(ecs, EcsChildOf, root);
|
|
ecs_new_w_pair(ecs, EcsChildOf, parent);
|
|
return root;
|
|
}
|
|
|
|
void Prefab_hierarchy_w_recycled_id(void) {
|
|
ecs_world_t* ecs = ecs_mini();
|
|
|
|
{
|
|
ecs_entity_t p = make_prefabs(ecs);
|
|
test_assert(p != 0);
|
|
ecs_entity_t i = ecs_new_w_pair(ecs, EcsIsA, p);
|
|
test_assert(i != 0);
|
|
ecs_delete(ecs, i);
|
|
}
|
|
|
|
{
|
|
ecs_entity_t p = make_prefabs(ecs);
|
|
test_assert(p != 0);
|
|
ecs_entity_t i = ecs_new_w_pair(ecs, EcsIsA, p);
|
|
test_assert(i != 0);
|
|
}
|
|
|
|
ecs_fini(ecs);
|
|
}
|