Properly link flecs library

This commit is contained in:
2023-11-09 11:38:29 +01:00
parent dc585396c3
commit 8edcf9305c
1392 changed files with 390081 additions and 164 deletions

View File

@@ -0,0 +1,517 @@
#include <api.h>
void Internals_setup(void) {
ecs_log_set_level(-3);
}
static
void Iter(ecs_iter_t *it) {
Position *p = ecs_field(it, Position, 1);
Velocity *v = ecs_field(it, Velocity, 2);
Mass *m = ecs_field(it, Mass, 3);
probe_iter(it);
int i;
for (i = 0; i < it->count; i ++) {
p[i].x = 10;
p[i].y = 20;
if (v) {
v[i].x = 30;
v[i].y = 40;
}
if (m) {
m[i] = 50;
}
}
}
void Internals_deactivate_table(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_ENTITY(world, e1, Position);
ECS_ENTITY(world, e2, Position);
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position);
/* System is now matched with archetype of entities. Delete entities to
* deactivate table for system */
ecs_delete(world, e1);
ecs_delete(world, e2);
test_assert(true);
ecs_fini(world);
}
void Internals_activate_table(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position);
/* Add entities after system definition to trigger table activation */
ECS_ENTITY(world, e1, Position);
ECS_ENTITY(world, e2, Position);
test_assert(true);
ecs_fini(world);
}
void Internals_activate_deactivate_table(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position);
/* Add entities after system definition to trigger table activation */
ECS_ENTITY(world, e1, Position);
ECS_ENTITY(world, e2, Position);
/* System is now matched with archetype of entities. Delete entities to
* deactivate table for system */
ecs_delete(world, e1);
ecs_delete(world, e2);
test_assert(true);
ecs_fini(world);
}
void Internals_activate_deactivate_reactive(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position);
/* Add entities after system definition to trigger table activation */
ECS_ENTITY(world, e1, Position);
ECS_ENTITY(world, e2, Position);
/* System is now matched with archetype of entities. Delete entities to
* deactivate table for system */
ecs_delete(world, e1);
ecs_delete(world, e2);
/* Add entities of same type to trigger table reactivation */
ECS_ENTITY(world, e3, Position);
ECS_ENTITY(world, e4, Position);
test_assert(true);
ecs_fini(world);
}
void Internals_activate_deactivate_activate_other(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position);
/* Add entities after system definition to trigger table activation */
ECS_ENTITY(world, e1, Position);
ECS_ENTITY(world, e2, Position);
/* System is now matched with archetype of entities. Delete entities to
* deactivate table for system */
ecs_delete(world, e1);
ecs_delete(world, e2);
/* Add entities of different type to trigger new table activation */
ECS_ENTITY(world, e3, Position, Velocity);
ECS_ENTITY(world, e4, Position, Velocity);
test_assert(true);
ecs_fini(world);
}
static int invoked = 0;
static
void CreateNewTable(ecs_iter_t *it) {
ecs_id_t ecs_id(Velocity) = ecs_field_id(it, 2);
int32_t i;
for (i = 0; i < it->count; i ++) {
ecs_add(it->world, it->entities[i], Velocity);
}
}
static
void ManualSystem(ecs_iter_t *it) {
invoked ++;
}
void Internals_no_double_system_table_after_merge(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ECS_ENTITY(world, e, Position);
ECS_SYSTEM(world, CreateNewTable, EcsOnUpdate, Position, Velocity());
ECS_SYSTEM(world, ManualSystem, 0, Position, Velocity);
/* CreateNewTable system created a new, non-empty table. This will be merged
* which will trigger activation of ManualSystem. This will cause the system
* to go from the inactive_systems array to the manual_systems array. This
* happens as systems are notified of new tables (during the merge). Because
* the manual_systems array was evaluated after the inactive_systems array,
* a table could be added to a system twice. */
ecs_progress(world, 0);
/* Validate that the CreateNewTable system has ran */
test_assert(ecs_has(world, e, Position));
test_assert(ecs_has(world, e, Velocity));
/* Now run the ManualSystem, and make sure it is only invoked once. If it is
* invoked twice, the table has been registered with the system twice, which
* is wrong. */
ecs_run(world, ManualSystem, 0, NULL);
test_int(invoked, 1);
ecs_fini(world);
}
void Internals_recreate_deleted_table(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_entity_t parent_A = ecs_new(world, 0);
ecs_entity_t child_A = ecs_new_w_pair(world, EcsChildOf, parent_A);
test_assert(parent_A != 0);
test_assert(child_A != 0);
ecs_delete(world, parent_A); // Deletes table
test_assert( !ecs_is_alive(world, parent_A));
test_assert( !ecs_is_alive(world, child_A));
ecs_entity_t parent_B = ecs_new(world, 0);
ecs_entity_t child_B = ecs_new_w_pair(world, EcsChildOf, parent_B);
test_assert(parent_B != 0);
test_assert(child_B != 0);
ecs_fini(world);
}
void Internals_create_65k_tables(void) {
ecs_world_t *world = ecs_init();
int32_t i;
for (i = 0; i <= 65536; i ++) {
ecs_entity_t e = ecs_new_id(world);
ecs_add_id(world, e, e);
test_assert(ecs_has_id(world, e, e));
test_int(ecs_get_type(world, e)->count, 1);
}
ecs_fini(world);
}
void Internals_no_duplicate_root_table_id(void) {
ecs_world_t *world = ecs_init();
/* This scenario triggered a bug where the first table registered in the
* world would get id 0, which is the same id as the root table. This caused
* the table cache to assert as it saw the wrong table for an id. */
int32_t i;
for (i = 0; i <= 50; i ++) {
ecs_entity_t e = ecs_new_id(world);
ecs_add_id(world, e, i + 1000);
test_assert(e != 0);
test_assert(ecs_has_id(world, e, i + 1000));
}
ecs_entity_t f = ecs_entity_init(world, &(ecs_entity_desc_t){
.name = "Foo"
});
test_assert(f != 0);
test_str(ecs_get_name(world, f), "Foo");
ecs_fini(world);
}
void Internals_override_os_api_w_addon(void) {
ecs_os_set_api_defaults();
ecs_os_api_t os_api = ecs_os_api;
ecs_os_set_api(&os_api);
test_assert(ecs_os_has_threading());
test_assert(ecs_os_has_time());
test_assert(ecs_os_has_logging());
test_assert(ecs_os_has_heap());
ecs_world_t *world = ecs_init();
ecs_fini(world);
}
void Internals_records_resize_on_override(void) {
ecs_world_t *world = ecs_mini();
ecs_entity_t TagA = ecs_new_id(world);
ecs_entity_t TagB = ecs_new_id(world);
ecs_entity_t TagC = ecs_new_id(world);
ecs_entity_t TagD = ecs_new_id(world);
ecs_entity_t TagE = ecs_new_id(world);
ecs_entity_t TagF = ecs_new_id(world);
ecs_entity_t TagG = ecs_new_id(world);
ecs_entity_t TagH = ecs_new_id(world);
ecs_entity_t RelA = ecs_new_id(world);
ecs_entity_t RelB = ecs_new_id(world);
ecs_entity_t RelC = ecs_new_id(world);
ecs_entity_t RelD = ecs_new_id(world);
ecs_entity_t RelE = ecs_new_id(world);
ecs_entity_t RelF = ecs_new_id(world);
ecs_entity_t RelG = ecs_new_id(world);
ecs_entity_t TgtA = ecs_new_id(world);
ecs_entity_t TgtB = ecs_new_id(world);
ecs_entity_t e = ecs_new_id(world);
ecs_add_id(world, e, TagA);
ecs_add_id(world, e, TagB);
ecs_add_id(world, e, TagC);
ecs_add_id(world, e, TagD);
ecs_add_id(world, e, TagE);
ecs_add_id(world, e, TagF);
ecs_add_id(world, e, TagG);
ecs_add_id(world, e, TagH);
ecs_add_pair(world, e, RelA, TgtA);
ecs_add_pair(world, e, RelB, TgtA);
ecs_add_pair(world, e, RelC, TgtA);
ecs_add_pair(world, e, RelD, TgtA);
ecs_add_pair(world, e, RelE, TgtA);
ecs_add_pair(world, e, RelF, TgtA);
ecs_override_pair(world, e, RelG, TgtB);
test_assert(ecs_has_id(world, e, TagA));
test_assert(ecs_has_id(world, e, TagB));
test_assert(ecs_has_id(world, e, TagC));
test_assert(ecs_has_id(world, e, TagD));
test_assert(ecs_has_id(world, e, TagE));
test_assert(ecs_has_id(world, e, TagF));
test_assert(ecs_has_id(world, e, TagG));
test_assert(ecs_has_id(world, e, TagH));
test_assert(ecs_has_pair(world, e, RelA, TgtA));
test_assert(ecs_has_pair(world, e, RelB, TgtA));
test_assert(ecs_has_pair(world, e, RelC, TgtA));
test_assert(ecs_has_pair(world, e, RelD, TgtA));
test_assert(ecs_has_pair(world, e, RelE, TgtA));
test_assert(ecs_has_pair(world, e, RelF, TgtA));
ecs_fini(world);
}
void Internals_table_observed_after_add(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, TagA);
ECS_TAG(world, TagB);
ecs_entity_t p = ecs_new_id(world);
ecs_entity_t c = ecs_new_w_pair(world, EcsChildOf, p);
ecs_table_t *pt = ecs_get_table(world, p);
ecs_table_t *ct = ecs_get_table(world, c);
test_assert(pt == NULL);
test_assert(ct != NULL);
test_int(flecs_table_observed_count(ct), 0);
ecs_add(world, p, TagA);
ecs_table_t *pt_a = ecs_get_table(world, p);
test_assert(pt_a != NULL);
test_int(flecs_table_observed_count(pt_a), 1);
ecs_add(world, p, TagB);
ecs_table_t *pt_b = ecs_get_table(world, p);
test_assert(pt_b != NULL);
test_int(flecs_table_observed_count(pt_a), 0);
test_int(flecs_table_observed_count(pt_b), 1);
ecs_fini(world);
}
void Internals_table_observed_after_remove(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, TagA);
ECS_TAG(world, TagB);
ecs_entity_t p = ecs_new_id(world);
ecs_entity_t c = ecs_new_w_pair(world, EcsChildOf, p);
ecs_table_t *pt = ecs_get_table(world, p);
ecs_table_t *ct = ecs_get_table(world, c);
test_assert(pt == NULL);
test_assert(ct != NULL);
test_int(flecs_table_observed_count(ct), 0);
ecs_add(world, p, TagA);
ecs_table_t *pt_a = ecs_get_table(world, p);
test_assert(pt_a != NULL);
test_int(flecs_table_observed_count(pt_a), 1);
ecs_add(world, p, TagB);
ecs_table_t *pt_b = ecs_get_table(world, p);
test_assert(pt_b != NULL);
test_int(flecs_table_observed_count(pt_a), 0);
test_int(flecs_table_observed_count(pt_b), 1);
ecs_remove(world, p, TagB);
test_int(flecs_table_observed_count(pt_a), 1);
test_int(flecs_table_observed_count(pt_b), 0);
ecs_remove(world, p, TagA);
test_int(flecs_table_observed_count(pt_a), 0);
test_int(flecs_table_observed_count(pt_b), 0);
ecs_fini(world);
}
void Internals_table_observed_after_clear(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, TagA);
ecs_entity_t p = ecs_new_id(world);
ecs_entity_t c = ecs_new_w_pair(world, EcsChildOf, p);
ecs_table_t *pt = ecs_get_table(world, p);
ecs_table_t *ct = ecs_get_table(world, c);
test_assert(pt == NULL);
test_assert(ct != NULL);
test_int(flecs_table_observed_count(ct), 0);
ecs_add(world, p, TagA);
ecs_table_t *pt_a = ecs_get_table(world, p);
test_assert(pt_a != NULL);
test_int(flecs_table_observed_count(pt_a), 1);
ecs_clear(world, p);
test_int(flecs_table_observed_count(pt_a), 0);
ecs_add(world, p, TagA);
test_int(flecs_table_observed_count(pt_a), 1);
ecs_fini(world);
}
void Internals_table_observed_after_delete(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, TagA);
ecs_entity_t p = ecs_new_id(world);
ecs_entity_t c = ecs_new_w_pair(world, EcsChildOf, p);
ecs_table_t *pt = ecs_get_table(world, p);
ecs_table_t *ct = ecs_get_table(world, c);
test_assert(pt == NULL);
test_assert(ct != NULL);
test_int(flecs_table_observed_count(ct), 0);
ecs_add(world, p, TagA);
ecs_table_t *pt_a = ecs_get_table(world, p);
test_assert(pt_a != NULL);
test_int(flecs_table_observed_count(pt_a), 1);
ecs_delete(world, p);
test_int(flecs_table_observed_count(pt_a), 0);
ecs_fini(world);
}
void Internals_table_observed_after_on_remove(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, TagA);
ecs_entity_t p = ecs_new_id(world);
ecs_entity_t c = ecs_new_w_pair(world, EcsChildOf, p);
ecs_table_t *pt = ecs_get_table(world, p);
ecs_table_t *ct = ecs_get_table(world, c);
test_assert(pt == NULL);
test_assert(ct != NULL);
test_int(flecs_table_observed_count(ct), 0);
ecs_entity_t t = ecs_new_id(world);
ecs_add_id(world, p, t);
ecs_table_t *pt_t = ecs_get_table(world, p);
test_assert(pt_t != NULL);
test_int(flecs_table_observed_count(pt_t), 1);
ecs_add(world, p, TagA);
ecs_table_t *pt_ta = ecs_get_table(world, p);
test_assert(pt_ta != NULL);
test_int(flecs_table_observed_count(pt_t), 0);
test_int(flecs_table_observed_count(pt_ta), 1);
ecs_delete(world, t);
test_assert(!ecs_has_id(world, p, t));
test_assert(ecs_has(world, p, TagA));
ecs_table_t *p_a = ecs_get_table(world, p);
test_assert(p_a != NULL);
test_int(flecs_table_observed_count(p_a), 1);
ecs_fini(world);
}
void Internals_table_observed_after_entity_flag(void) {
ecs_world_t *world = ecs_mini();
ECS_TAG(world, TagA);
ECS_TAG(world, TagB);
ecs_entity_t p = ecs_new_id(world);
ecs_add(world, p, TagA);
ecs_table_t *p_a = ecs_get_table(world, p);
test_assert(p_a != NULL);
test_int(flecs_table_observed_count(p_a), 0);
ecs_entity_t c = ecs_new_w_pair(world, EcsChildOf, p);
ecs_table_t *ct = ecs_get_table(world, c);
test_assert(ct != NULL);
test_int(flecs_table_observed_count(ct), 0);
test_int(flecs_table_observed_count(p_a), 1);
ecs_fini(world);
}
void Internals_table_create_leak_check(void) {
ecs_world_t *world = ecs_mini();
int64_t max_block_count;
ecs_entity_t tag = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_id(world, tag);
max_block_count = ecs_block_allocator_alloc_count -
ecs_block_allocator_free_count;
ecs_delete(world, tag);
for (int i = 0; i < 25000; i ++) {
tag = ecs_new_id(world);
ecs_add_id(world, e, tag);
ecs_delete(world, tag);
}
test_int(max_block_count, ecs_block_allocator_alloc_count -
ecs_block_allocator_free_count);
ecs_fini(world);
}