Properly link flecs library
This commit is contained in:
420
engine/libs/flecs/test/api/src/TriggerOnRemove.c
Normal file
420
engine/libs/flecs/test/api/src/TriggerOnRemove.c
Normal file
@@ -0,0 +1,420 @@
|
||||
#include <api.h>
|
||||
|
||||
void Deinit(ecs_iter_t *it) {
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
|
||||
Velocity *v = NULL;
|
||||
if (it->field_count >= 2) {
|
||||
v = ecs_field(it, Velocity, 2);
|
||||
}
|
||||
|
||||
probe_iter(it);
|
||||
|
||||
/* Write to validate columns point to valid memory */
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
p[i].x = 0;
|
||||
p[i].y = 0;
|
||||
|
||||
if (v) {
|
||||
v[i].x = 0;
|
||||
v[i].y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void Remove_from_current(ecs_iter_t *it) {
|
||||
IterData *ctx = ecs_get_ctx(it->world);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_entity_t e = it->entities[i];
|
||||
|
||||
if (ctx->component) {
|
||||
ecs_remove_id(it->world, e, ctx->component);
|
||||
}
|
||||
|
||||
if (ctx->component_2) {
|
||||
ecs_remove_id(it->world, e, ctx->component_2);
|
||||
}
|
||||
|
||||
ctx->entity_count ++;
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerOnRemove_remove(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_OBSERVER(world, Deinit, EcsOnRemove, Position);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
test_assert(e != 0);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
|
||||
ecs_remove(world, e, Position);
|
||||
|
||||
test_int(ctx.count, 1);
|
||||
test_int(ctx.term_count, 1);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void TriggerOnRemove_remove_no_match(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_OBSERVER(world, Deinit, EcsOnRemove, Position);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
test_assert(e != 0);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
|
||||
ecs_remove(world, e, Velocity);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void TriggerOnRemove_delete(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_OBSERVER(world, Deinit, EcsOnRemove, Position);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
test_assert(e != 0);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
|
||||
ecs_delete(world, e);
|
||||
|
||||
test_int(ctx.count, 1);
|
||||
test_int(ctx.term_count, 1);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void TriggerOnRemove_delete_no_match(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_OBSERVER(world, Deinit, EcsOnRemove, Position);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Velocity);
|
||||
test_assert(e != 0);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
|
||||
ecs_delete(world, e);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static Position old_position = {0};
|
||||
|
||||
static
|
||||
void RemovePosition(ecs_iter_t *it) {
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
|
||||
test_assert(it->count == 1);
|
||||
|
||||
old_position = p[0];
|
||||
}
|
||||
|
||||
void TriggerOnRemove_remove_watched(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_OBSERVER(world, RemovePosition, EcsOnRemove, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
|
||||
/* Make parent entity watched */
|
||||
ecs_new_w_pair(world, EcsChildOf, e);
|
||||
|
||||
ecs_remove(world, e, Position);
|
||||
|
||||
test_int(old_position.x, 10);
|
||||
test_int(old_position.y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
|
||||
void TriggerOnRemove_delete_watched(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_OBSERVER(world, RemovePosition, EcsOnRemove, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
|
||||
/* Make parent entity watched */
|
||||
ecs_new_w_pair(world, EcsChildOf, e);
|
||||
|
||||
ecs_delete(world, e);
|
||||
|
||||
test_int(old_position.x, 10);
|
||||
test_int(old_position.y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static bool dummy_called = false;
|
||||
|
||||
static
|
||||
void Dummy(ecs_iter_t *it) {
|
||||
dummy_called = true;
|
||||
}
|
||||
|
||||
void TriggerOnRemove_on_remove_in_on_update(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, Remove_from_current, EcsOnUpdate, Position);
|
||||
ECS_OBSERVER(world, Dummy, EcsOnRemove, Velocity);
|
||||
|
||||
IterData ctx = {.component = ecs_id(Velocity)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ECS_ENTITY(world, e1, Position, Velocity);
|
||||
ECS_ENTITY(world, e2, Position, Velocity);
|
||||
ECS_ENTITY(world, e3, Position, Velocity);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_assert( ecs_has(world, e1, Position));
|
||||
test_assert( ecs_has(world, e2, Position));
|
||||
test_assert( ecs_has(world, e3, Position));
|
||||
|
||||
test_assert( !ecs_has(world, e1, Velocity));
|
||||
test_assert( !ecs_has(world, e2, Velocity));
|
||||
test_assert( !ecs_has(world, e3, Velocity));
|
||||
|
||||
test_assert(dummy_called);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static int dummy_dtor_invoked = 0;
|
||||
|
||||
typedef struct DummyComp {
|
||||
int value;
|
||||
} DummyComp;
|
||||
|
||||
static
|
||||
void RemoveDummyComp(ecs_iter_t *it) {
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
test_assert(ecs_is_valid(it->world, it->entities[i]));
|
||||
test_assert(ecs_is_alive(it->world, it->entities[i]));
|
||||
}
|
||||
|
||||
dummy_dtor_invoked ++;
|
||||
}
|
||||
|
||||
void TriggerOnRemove_valid_entity_after_delete(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, DummyComp);
|
||||
ECS_OBSERVER(world, RemoveDummyComp, EcsOnRemove, DummyComp);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, DummyComp);
|
||||
test_assert(e != 0);
|
||||
|
||||
ecs_delete(world, e);
|
||||
test_assert(!ecs_is_valid(world, e));
|
||||
test_assert(!ecs_is_alive(world, e));
|
||||
|
||||
test_int(dummy_dtor_invoked, 1);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void TriggerOnRemove_remove_after_delete_trigger(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t trigger = ecs_observer_init(world, &(ecs_observer_desc_t){
|
||||
.filter.terms[0].id = ecs_id(Position),
|
||||
.events = {EcsOnRemove},
|
||||
.callback = Dummy
|
||||
});
|
||||
|
||||
ecs_entity_t e1 = ecs_new(world, Position);
|
||||
test_assert(e1 != 0);
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_int(dummy_called, 0);
|
||||
|
||||
ecs_remove(world, e1, Position);
|
||||
test_int(dummy_called, 1);
|
||||
|
||||
dummy_called = 0;
|
||||
|
||||
ecs_delete(world, trigger);
|
||||
test_int(dummy_called, 0);
|
||||
|
||||
ecs_entity_t e2 = ecs_new(world, Position);
|
||||
test_assert(e2 != 0);
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
test_int(dummy_called, 0);
|
||||
|
||||
ecs_remove(world, e2, Position);
|
||||
test_int(dummy_called, 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void TriggerOnRemove_remove_after_delete_wildcard_id_trigger(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t trigger = ecs_observer_init(world, &(ecs_observer_desc_t){
|
||||
.filter.terms[0].id = EcsWildcard,
|
||||
.events = {EcsOnRemove},
|
||||
.callback = Dummy
|
||||
});
|
||||
|
||||
ecs_entity_t e1 = ecs_new(world, Position);
|
||||
test_assert(e1 != 0);
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_int(dummy_called, 0);
|
||||
|
||||
ecs_remove(world, e1, Position);
|
||||
test_int(dummy_called, 1);
|
||||
|
||||
dummy_called = 0;
|
||||
|
||||
ecs_delete(world, trigger);
|
||||
|
||||
test_int(dummy_called, 1);
|
||||
|
||||
dummy_called = 0;
|
||||
|
||||
ecs_entity_t e2 = ecs_new(world, Position);
|
||||
test_assert(e2 != 0);
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
test_int(dummy_called, 0);
|
||||
|
||||
ecs_remove(world, e2, Position);
|
||||
test_int(dummy_called, 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
typedef struct on_remove_has_tag_t {
|
||||
ecs_entity_t ent;
|
||||
ecs_entity_t tag;
|
||||
} on_remove_has_tag_t;
|
||||
|
||||
static
|
||||
void OnRemoveHasTag(ecs_iter_t *it) {
|
||||
on_remove_has_tag_t *ctx = it->ctx;
|
||||
test_assert(ctx != NULL);
|
||||
|
||||
test_int(it->count, 1);
|
||||
test_assert(it->entities[0] == ctx->ent);
|
||||
test_assert(ecs_field_id(it, 1) == ctx->tag);
|
||||
test_bool(ecs_has_id(it->world, ctx->ent, ctx->tag), true);
|
||||
|
||||
dummy_called = true;
|
||||
}
|
||||
|
||||
void TriggerOnRemove_has_removed_tag_trigger_1_tag(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_TAG(world, Tag);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Tag);
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Tag));
|
||||
|
||||
on_remove_has_tag_t ctx = {
|
||||
.ent = e,
|
||||
.tag = Tag
|
||||
};
|
||||
|
||||
ecs_observer_init(world, &(ecs_observer_desc_t){
|
||||
.filter.terms[0].id = Tag,
|
||||
.events = {EcsOnRemove},
|
||||
.callback = OnRemoveHasTag,
|
||||
.ctx = &ctx
|
||||
});
|
||||
|
||||
ecs_remove(world, e, Tag);
|
||||
|
||||
test_int(dummy_called, 1);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void TriggerOnRemove_has_removed_tag_trigger_2_tags(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_TAG(world, TagA);
|
||||
ECS_TAG(world, TagB);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, TagA);
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, TagA));
|
||||
|
||||
ecs_add(world, e, TagB);
|
||||
test_assert(ecs_has(world, e, TagB));
|
||||
|
||||
on_remove_has_tag_t ctx = {
|
||||
.ent = e,
|
||||
.tag = TagA
|
||||
};
|
||||
|
||||
ecs_observer_init(world, &(ecs_observer_desc_t){
|
||||
.filter.terms[0].id = TagA,
|
||||
.events = {EcsOnRemove},
|
||||
.callback = OnRemoveHasTag,
|
||||
.ctx = &ctx
|
||||
});
|
||||
|
||||
ecs_remove(world, e, TagA);
|
||||
|
||||
test_int(dummy_called, 1);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
Reference in New Issue
Block a user