1295 lines
33 KiB
C
1295 lines
33 KiB
C
#include <addons.h>
|
|
|
|
void System_w_FromParent_setup(void) {
|
|
ecs_log_set_level(-3);
|
|
}
|
|
|
|
static
|
|
void Iter(ecs_iter_t *it) {
|
|
Mass *m_ptr = ecs_field(it, Mass, 1);
|
|
bool shared = false;
|
|
|
|
if (m_ptr) {
|
|
shared = !ecs_field_is_self(it, 1);
|
|
}
|
|
|
|
Position *p = NULL;
|
|
Velocity *v = NULL;
|
|
|
|
if (it->field_count >= 2) {
|
|
p = ecs_field(it, Position, 2);
|
|
}
|
|
|
|
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 System_w_FromParent_1_column_from_container(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_set(world, 0, Mass, {2});
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
ecs_add_pair(world, e3, EcsChildOf, parent);
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 3);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.e[2], e3);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e3, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_2_column_1_from_container(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position, Velocity);
|
|
ECS_ENTITY(world, e2, Position, Velocity);
|
|
ECS_ENTITY(world, e3, Position, Velocity);
|
|
ECS_ENTITY(world, e4, Position, Velocity);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position, Velocity);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_set(world, 0, Mass, {2});
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
ecs_add_pair(world, e3, EcsChildOf, parent);
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 3);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Iter);
|
|
test_int(ctx.term_count, 3);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.e[2], e3);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
test_int(ctx.c[0][2], ecs_id(Velocity));
|
|
test_int(ctx.s[0][2], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e3, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
const Velocity *v = ecs_get(world, e1, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 60);
|
|
test_int(v->y, 80);
|
|
|
|
v = ecs_get(world, e2, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 60);
|
|
test_int(v->y, 80);
|
|
|
|
v = ecs_get(world, e3, Velocity);
|
|
test_assert(v != NULL);
|
|
test_int(v->x, 60);
|
|
test_int(v->y, 80);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void Iter_2_shared(ecs_iter_t *it) {
|
|
Mass *m_ptr = ecs_field(it, Mass, 1);
|
|
|
|
Rotation *r_ptr = NULL;
|
|
Position *p = NULL;
|
|
Velocity *v = NULL;
|
|
|
|
if (it->field_count >= 2) {
|
|
r_ptr = ecs_field(it, Rotation, 2);
|
|
}
|
|
|
|
if (it->field_count >= 3) {
|
|
p = ecs_field(it, Position, 3);
|
|
}
|
|
|
|
if (it->field_count >= 4) {
|
|
v = ecs_field(it, Velocity, 4);
|
|
}
|
|
|
|
probe_iter(it);
|
|
|
|
Mass m = 1;
|
|
if (m_ptr) {
|
|
m = *m_ptr;
|
|
}
|
|
|
|
Rotation r = 0;
|
|
if (r_ptr) {
|
|
r = *r_ptr;
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
if (p) {
|
|
p[i].x = 10 * m + r;
|
|
p[i].y = 20 * m + r;
|
|
}
|
|
|
|
if (v) {
|
|
v[i].x = 30 * m + r;
|
|
v[i].y = 40 * m + r;
|
|
}
|
|
}
|
|
}
|
|
|
|
void System_w_FromParent_3_column_2_from_container(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Rotation);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
|
|
ECS_SYSTEM(world, Iter_2_shared, EcsOnUpdate, Mass(parent), Rotation(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter_2_shared,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_set(world, 0, Mass, {2});
|
|
ecs_set(world, parent, Rotation, {3});
|
|
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
ecs_add_pair(world, e4, EcsChildOf, parent);
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 3);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Iter_2_shared);
|
|
test_int(ctx.term_count, 3);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.e[2], e4);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Rotation));
|
|
test_int(ctx.s[0][1], parent);
|
|
test_int(ctx.c[0][2], ecs_id(Position));
|
|
test_int(ctx.s[0][2], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 23);
|
|
test_int(p->y, 43);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 23);
|
|
test_int(p->y, 43);
|
|
|
|
p = ecs_get(world, e4, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 23);
|
|
test_int(p->y, 43);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_2_column_1_from_container_w_not(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Rotation);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
ECS_ENTITY(world, e5, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, !Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent_1 = ecs_set(world, 0, Mass, {2});
|
|
ecs_entity_t parent_2 = ecs_set(world, 0, Rotation, {3});
|
|
|
|
ecs_add_pair(world, e1, EcsChildOf, parent_2);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent_2);
|
|
ecs_add_pair(world, e3, EcsChildOf, parent_2);
|
|
ecs_add_pair(world, e4, EcsChildOf, parent_1);
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 4);
|
|
test_int(ctx.invoked, 2);
|
|
test_int(ctx.system, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e5);
|
|
test_int(ctx.e[1], e1);
|
|
test_int(ctx.e[2], e2);
|
|
test_int(ctx.e[3], e3);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], 0);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
test_int(ctx.c[1][0], ecs_id(Mass));
|
|
test_int(ctx.s[1][0], 0);
|
|
test_int(ctx.c[1][1], ecs_id(Position));
|
|
test_int(ctx.s[1][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
p = ecs_get(world, e3, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
p = ecs_get(world, e5, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_3_column_1_from_comtainer_1_from_container_w_not(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Rotation);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
ECS_ENTITY(world, e5, Position);
|
|
ECS_ENTITY(world, e6, Position);
|
|
|
|
ECS_SYSTEM(world, Iter_2_shared, EcsOnUpdate, !Mass(parent), Rotation(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter_2_shared,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent_1 = ecs_set(world, 0, Mass, {2});
|
|
ecs_entity_t parent_2 = ecs_set(world, 0, Rotation, {3});
|
|
ecs_entity_t parent_3 = ecs_set(world, 0, Mass, {4});
|
|
ecs_set(world, parent_3, Rotation, {5});
|
|
|
|
ecs_add_pair(world, e1, EcsChildOf, parent_2);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent_2);
|
|
ecs_add_pair(world, e3, EcsChildOf, parent_2);
|
|
ecs_add_pair(world, e4, EcsChildOf, parent_1);
|
|
ecs_add_pair(world, e5, EcsChildOf, parent_3);
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 3);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Iter_2_shared);
|
|
test_int(ctx.term_count, 3);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.e[2], e3);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], 0);
|
|
test_int(ctx.c[0][1], ecs_id(Rotation));
|
|
test_int(ctx.s[0][1], parent_2);
|
|
test_int(ctx.c[0][2], ecs_id(Position));
|
|
test_int(ctx.s[0][2], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 13);
|
|
test_int(p->y, 23);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 13);
|
|
test_int(p->y, 23);
|
|
|
|
p = ecs_get(world, e3, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 13);
|
|
test_int(p->y, 23);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_2_column_1_from_container_w_not_prefab(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Rotation);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_PREFAB(world, Prefab, Rotation);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, !Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent_1 = ecs_set(world, 0, Mass, {2});
|
|
ecs_add_pair(world, e1, EcsIsA, Prefab);
|
|
|
|
ecs_add_pair(world, e1, EcsChildOf, parent_1);
|
|
ecs_set(world, e1, Position, {1, 2});
|
|
|
|
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, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], 0);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 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, 10);
|
|
test_int(p->y, 20);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_2_column_1_from_container_w_or(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Rotation);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
ECS_ENTITY(world, e5, Position);
|
|
ECS_ENTITY(world, e6, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent) || Rotation(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent_1 = ecs_set(world, 0, Mass, {2});
|
|
ecs_entity_t parent_2 = ecs_set(world, 0, Rotation, {3});
|
|
ecs_entity_t parent_3 = ecs_set(world, 0, Rotation, {4});
|
|
ecs_set(world, parent_3, Mass, {5});
|
|
ecs_entity_t parent_4 = ecs_set(world, 0, Velocity, {10, 20});
|
|
|
|
ecs_add_pair(world, e1, EcsChildOf, parent_1);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent_2);
|
|
ecs_add_pair(world, e3, EcsChildOf, parent_3);
|
|
ecs_add_pair(world, e4, EcsChildOf, parent_4);
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 3);
|
|
test_int(ctx.invoked, 3);
|
|
test_int(ctx.system, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.e[2], e3);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent_1);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
test_int(ctx.c[1][0], ecs_id(Rotation));
|
|
test_int(ctx.s[1][0], parent_2);
|
|
test_int(ctx.c[1][1], ecs_id(Position));
|
|
test_int(ctx.s[2][1], 0);
|
|
test_int(ctx.c[2][0], ecs_id(Mass));
|
|
test_int(ctx.s[2][0], parent_3);
|
|
test_int(ctx.c[2][1], ecs_id(Position));
|
|
test_int(ctx.s[2][1], 0);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void Dummy(ecs_iter_t *it) {
|
|
Mass *m_ptr = ecs_field(it, Mass, 1);
|
|
Position *p = ecs_field(it, Position, 2);
|
|
|
|
test_assert(!m_ptr || !ecs_field_is_self(it, 1));
|
|
|
|
probe_iter(it);
|
|
|
|
Mass m = 1;
|
|
if (m_ptr) {
|
|
m = *m_ptr;
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
p[i].x += m;
|
|
p[i].y += m;
|
|
}
|
|
}
|
|
|
|
void System_w_FromParent_add_component_after_match(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_new(world, 0);
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
|
|
ecs_set(world, parent, Mass, {2});
|
|
|
|
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, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_add_component_after_match_and_rematch(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_new(world, 0);
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
/* This will rematch tables, but not match Iter with e1 and e2 because the
|
|
* parent does not have Mass yet */
|
|
ecs_progress(world, 1);
|
|
test_int(ctx.count, 0);
|
|
|
|
ecs_set(world, parent, Mass, {2});
|
|
|
|
/* Now a rematch of tables need to happen again, since parent has changed */
|
|
ecs_os_zeromem(&ctx);
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 2);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_add_component_after_match_and_rematch_w_entity_type_expr(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ECS_ENTITY(world, Parent, 0);
|
|
ECS_ENTITY(world, e1, Position, (ChildOf, Parent));
|
|
ECS_ENTITY(world, e2, Position, (ChildOf, Parent));
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
/* This will rematch tables, but not match Iter with e1 and e2 because the
|
|
* Parent does not have Mass yet */
|
|
ecs_progress(world, 1);
|
|
test_int(ctx.count, 0);
|
|
|
|
ecs_set(world, Parent, Mass, {2});
|
|
|
|
/* Now a rematch of tables need to happen again, since parent has changed */
|
|
ecs_os_zeromem(&ctx);
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 2);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], Parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void SetMass(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_set(it->world, it->entities[i], Mass, {2});
|
|
}
|
|
}
|
|
|
|
void System_w_FromParent_add_component_after_match_and_rematch_w_entity_type_expr_in_progress(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Velocity);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
|
|
ECS_SYSTEM(world, SetMass, EcsOnUpdate, Velocity, Mass());
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ECS_ENTITY(world, Parent, Velocity);
|
|
ECS_ENTITY(world, e1, Position, (ChildOf, Parent));
|
|
ECS_ENTITY(world, e2, Position, (ChildOf, Parent));
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_os_zeromem(&ctx);
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 2);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], Parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_add_component_after_match_unmatch(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, !Mass(parent), Position);
|
|
|
|
ecs_entity_t parent = ecs_new(world, 0);
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
|
|
ecs_set(world, parent, Mass, {2});
|
|
|
|
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, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e3);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], 0);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e3, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_add_component_after_match_unmatch_match(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ECS_SYSTEM(world, Dummy, EcsOnUpdate, !Mass(parent), Position);
|
|
|
|
ecs_entity_t parent = ecs_new(world, 0);
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
|
|
ecs_set(world, parent, Mass, {2});
|
|
|
|
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, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_add_component_after_match_2_systems(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ECS_SYSTEM(world, Dummy, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Dummy,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_new(world, 0);
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
|
|
ecs_set(world, parent, Mass, {2});
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 4);
|
|
test_int(ctx.invoked, 2);
|
|
test_int(ctx.system, Dummy);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.e[2], e1);
|
|
test_int(ctx.e[3], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 22);
|
|
test_int(p->y, 42);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 22);
|
|
test_int(p->y, 42);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
static
|
|
void AddMass(ecs_iter_t *it) {
|
|
test_assert(it->ctx != NULL);
|
|
ecs_entity_t ecs_id(Mass) = *(ecs_entity_t*)it->ctx;
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ecs_set(it->world, it->entities[i], Mass, {2});
|
|
}
|
|
}
|
|
|
|
void System_w_FromParent_add_component_in_progress_after_match(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
ECS_ENTITY(world, Tag, 0);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ECS_OBSERVER(world, AddMass, EcsOnAdd, Tag);
|
|
|
|
ecs_observer_init(world, &(ecs_observer_desc_t){
|
|
.entity = AddMass,
|
|
.ctx = &ecs_id(Mass)
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_new(world, 0);
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
|
|
ecs_add_id(world, parent, Tag);
|
|
|
|
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, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_adopt_after_match(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_new(world, Mass);
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
|
|
ecs_set(world, parent, Mass, {2});
|
|
|
|
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, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_new_child_after_match(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e3, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = Iter,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ECS_ENTITY(world, parent, Mass);
|
|
ECS_ENTITY(world, e1, (ChildOf, parent), Position);
|
|
ECS_ENTITY(world, e2, (ChildOf, parent), Position);
|
|
|
|
ecs_set(world, parent, Mass, {2});
|
|
|
|
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, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void IterSame(ecs_iter_t *it) {
|
|
Position *p_parent = ecs_field(it, Position, 1);
|
|
Position *p = ecs_field(it, Position, 2);
|
|
|
|
test_assert(!ecs_field_is_self(it, 1));
|
|
|
|
probe_iter(it);
|
|
|
|
int i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
p[i].x += p_parent->x;
|
|
p[i].y += p_parent->y;
|
|
}
|
|
}
|
|
|
|
void System_w_FromParent_select_same_from_container(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
ECS_ENTITY(world, e2, Position);
|
|
ECS_ENTITY(world, e3, Position);
|
|
ECS_ENTITY(world, e4, Position);
|
|
|
|
ECS_SYSTEM(world, IterSame, EcsOnUpdate, Position(parent), Position);
|
|
ecs_system_init(world, &(ecs_system_desc_t){
|
|
.entity = IterSame,
|
|
.query.filter.instanced = true
|
|
});
|
|
|
|
ecs_entity_t parent = ecs_set(world, 0, Position, {1, 2});
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
ecs_add_pair(world, e2, EcsChildOf, parent);
|
|
ecs_add_pair(world, e3, EcsChildOf, parent);
|
|
|
|
ecs_set(world, e1, Position, {10, 20});
|
|
ecs_set(world, e2, Position, {20, 40});
|
|
ecs_set(world, e3, Position, {30, 60});
|
|
|
|
Probe ctx = {0};
|
|
ecs_set_ctx(world, &ctx, NULL);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 3);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, IterSame);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.e[1], e2);
|
|
test_int(ctx.e[2], e3);
|
|
test_int(ctx.c[0][0], ecs_id(Position));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 11);
|
|
test_int(p->y, 22);
|
|
|
|
p = ecs_get(world, e2, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 21);
|
|
test_int(p->y, 42);
|
|
|
|
p = ecs_get(world, e3, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 31);
|
|
test_int(p->y, 62);
|
|
|
|
ecs_fini(world);
|
|
}
|
|
|
|
void System_w_FromParent_realloc_after_match(void) {
|
|
ecs_world_t *world = ecs_init();
|
|
|
|
ECS_COMPONENT(world, Position);
|
|
ECS_COMPONENT(world, Mass);
|
|
|
|
ECS_ENTITY(world, e1, Position);
|
|
|
|
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(parent), Position);
|
|
|
|
ecs_entity_t parent = ecs_set(world, 0, Mass, {2});
|
|
ecs_add_pair(world, e1, EcsChildOf, parent);
|
|
|
|
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, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
const Position *p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 20);
|
|
test_int(p->y, 40);
|
|
|
|
/* Add 1000 entities to table of container, which will trigger realloc */
|
|
for (int i = 0; i < 1000; i ++) {
|
|
ecs_clone(world, 0, parent, false);
|
|
}
|
|
|
|
/* Change value of parent Mass. This will update the value in the new table.
|
|
* If the realloc would not be properly handled, the code could either crash
|
|
* or reference freed memory and use the old value. */
|
|
ecs_set(world, parent, Mass, {3});
|
|
|
|
ecs_os_zeromem(&ctx);
|
|
|
|
ecs_progress(world, 1);
|
|
|
|
test_int(ctx.count, 1);
|
|
test_int(ctx.invoked, 1);
|
|
test_int(ctx.system, Iter);
|
|
test_int(ctx.term_count, 2);
|
|
test_null(ctx.param);
|
|
|
|
test_int(ctx.e[0], e1);
|
|
test_int(ctx.c[0][0], ecs_id(Mass));
|
|
test_int(ctx.s[0][0], parent);
|
|
test_int(ctx.c[0][1], ecs_id(Position));
|
|
test_int(ctx.s[0][1], 0);
|
|
|
|
p = ecs_get(world, e1, Position);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 30);
|
|
test_int(p->y, 60);
|
|
|
|
ecs_fini(world);
|
|
}
|