#include void Set_set_empty(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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 Set_set_nonempty(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_new(world, Position); test_assert(e != 0); ecs_set(world, e, Velocity, {10, 20}); test_assert(ecs_has(world, e, Position)); test_assert(ecs_has(world, e, Velocity)); const Velocity *v = ecs_get(world, e, Velocity); test_assert(v != NULL); test_int(v->x, 10); test_int(v->y, 20); ecs_fini(world); } void Set_set_non_empty_override(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, Position); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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 Set_set_again(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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_set(world, e, Position, {30, 40}); test_assert(ecs_has(world, e, Position)); p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); ecs_fini(world); } void Set_set_2(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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_set(world, e, Velocity, {30, 40}); test_assert(ecs_has(world, e, Position)); test_assert(ecs_has(world, e, Velocity)); p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); const Velocity *v = ecs_get(world, e, Velocity); test_assert(v != NULL); test_int(v->x, 30); test_int(v->y, 40); ecs_fini(world); } void Set_add_set(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); ecs_add(world, e, Position); test_assert(ecs_has(world, e, Position)); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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 Set_set_add(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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_add(world, e, Position); test_assert(ecs_has(world, e, 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 Set_set_add_other(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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_add(world, e, Velocity); test_assert(ecs_has(world, e, Position)); test_assert(ecs_has(world, e, Velocity)); p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Set_set_remove(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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_remove(world, e, Position); test_assert(!ecs_has(world, e, Position)); p = ecs_get(world, e, Position); test_assert(p == NULL); ecs_fini(world); } void Set_set_remove_other(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_new(world, Velocity); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(world, e, Position)); test_assert(ecs_has(world, e, Velocity)); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_remove(world, e, Velocity); test_assert(ecs_has(world, e, Position)); test_assert(!ecs_has(world, e, Velocity)); p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void Set_set_remove_twice(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(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_remove(world, e, Position); test_assert(!ecs_has(world, e, Position)); p = ecs_get(world, e, Position); test_assert(p == NULL); ecs_set(world, e, Position, {10, 20}); test_assert(ecs_has(world, e, 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 Set_set_and_new(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_set(world, 0, Position, {10, 20}); 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, 10); test_int(p->y, 20); ecs_fini(world); } void Set_set_null(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, 0); ecs_set_ptr(world, e, Position, NULL); 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, 0); test_int(p->y, 0); ecs_fini(world); } void Set_get_mut_new(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); Position *p = ecs_get_mut(world, e, Position); test_assert(p != NULL); test_assert( ecs_has(world, e, Position)); test_assert(p == ecs_get(world, e, Position)); ecs_fini(world); } void Set_get_mut_existing(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, Position); test_assert(e != 0); test_assert( ecs_has(world, e, Position)); const Position *p_prev = ecs_get(world, e, Position); Position *p = ecs_get_mut(world, e, Position); test_assert(p != NULL); test_assert( ecs_has(world, e, Position)); test_assert(p == p_prev); ecs_fini(world); } void Set_get_mut_tag_new(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_TAG(world, MyTag); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); test_expect_abort(); ecs_get_mut_id(world, e, MyTag); } void Set_get_mut_tag_existing(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_TAG(world, MyTag); ecs_entity_t e = ecs_new(world, MyTag); test_assert(e != 0); test_assert( ecs_has(world, e, MyTag)); test_expect_abort(); ecs_get_mut_id(world, e, MyTag); } void Set_get_mut_tag_new_w_comp(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, MyTag); ecs_entity_t e = ecs_new(world, Position); test_assert(e != 0); test_expect_abort(); ecs_get_mut_id(world, e, MyTag); } void Set_get_mut_tag_existing_w_comp(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, MyTag); ecs_entity_t e = ecs_new(world, MyTag); test_assert(e != 0); test_assert( ecs_has(world, e, MyTag)); ecs_add(world, e, Position); test_expect_abort(); ecs_get_mut_id(world, e, MyTag); } void Set_get_mut_tag_new_w_pair(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, Pair); ECS_TAG(world, MyTag); ecs_entity_t e = ecs_new_w_id(world, ecs_pair(ecs_id(Position), Pair)); test_assert(e != 0); test_expect_abort(); ecs_get_mut_id(world, e, MyTag); } void Set_get_mut_tag_existing_w_pair(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, Pair); ECS_TAG(world, MyTag); ecs_entity_t e = ecs_new(world, MyTag); test_assert(e != 0); test_assert( ecs_has(world, e, MyTag)); ecs_add_pair(world, e, Pair, ecs_id(Position)); test_expect_abort(); ecs_get_mut_id(world, e, MyTag); } static bool is_invoked = false; void OnSetPosition(ecs_iter_t *it) { is_invoked = true; } void Set_modified_w_on_set(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_OBSERVER(world, OnSetPosition, EcsOnSet, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); Position *p = ecs_get_mut(world, e, Position); test_assert(p != NULL); test_assert( ecs_has(world, e, Position)); test_assert(p == ecs_get(world, e, Position)); test_assert(is_invoked == false); ecs_modified(world, e, Position); test_assert(is_invoked == true); ecs_fini(world); } void Set_modified_no_component(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_OBSERVER(world, OnSetPosition, EcsOnSet, Position); ecs_entity_t e = ecs_new(world, 0); test_assert(e != 0); test_expect_abort(); /* This should trigger an assert */ ecs_modified(world, e, Position); ecs_fini(world); } static ECS_COMPONENT_DECLARE(Position); static ECS_COMPONENT_DECLARE(Velocity); static void OnAdd(ecs_iter_t *it) { int i; for (i = 0; i < it->count; i ++) { ecs_add(it->world, it->entities[i], Velocity); } } static void OnAddRemove(ecs_iter_t *it) { int i; for (i = 0; i < it->count; i ++) { ecs_remove(it->world, it->entities[i], Position); } } void Set_get_mut_w_add_in_on_add(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT_DEFINE(world, Position); ECS_COMPONENT_DEFINE(world, Velocity); ECS_OBSERVER(world, OnAdd, EcsOnAdd, Position); ecs_entity_t e = ecs_new_id(world); Position *p = ecs_get_mut(world, e, Position); test_assert(p != NULL); p->x = 10; p->y = 20; const Position *pc = ecs_get(world, e, Position); test_int(pc->x, 10); test_int(pc->y, 20); ecs_fini(world); } void Set_get_mut_w_remove_in_on_add(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_COMPONENT_DEFINE(world, Position); ECS_OBSERVER(world, OnAddRemove, EcsOnAdd, Position); ecs_entity_t e = ecs_new_id(world); test_expect_abort(); /* get_mut is guaranteed to always return a valid pointer, so removing the * component from the OnAdd trigger is not allowed */ ecs_get_mut(world, e, Position); } static void OnAddRealloc(ecs_iter_t *it) { ecs_entity_t *entities = it->ctx; int i; for (i = 0; i < 1000; i ++) { ecs_set(it->world, entities[i], Velocity, {i, i * 2}); } } void Set_get_mut_w_realloc_in_on_add(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT_DEFINE(world, Position); ECS_COMPONENT_DEFINE(world, Velocity); ecs_entity_t *entities = ecs_os_malloc_n(ecs_entity_t, 1000); for (int i = 0; i < 1000; i ++) { entities[i] = ecs_new(world, Position); } ecs_observer_init(world, &(ecs_observer_desc_t){ .callback = OnAddRealloc, .events = {EcsOnAdd}, .filter.terms[0].id = ecs_id(Position), .ctx = entities }); ecs_entity_t e = ecs_new(world, Velocity); const Position *ptr = ecs_get_mut(world, e, Position); test_assert(ptr == ecs_get(world, e, Position)); for (int i = 0; i < 1000; i ++) { test_assert( ecs_has(world, entities[i], Velocity)); const Velocity *vptr = ecs_get(world, entities[i], Velocity); test_assert(vptr != NULL); // printf("e = {%f, %f}\n", vptr->x, vptr->y); test_int(vptr->x, i); test_int(vptr->y, i * 2); test_assert(ecs_get_table(world, e) == ecs_get_table(world, entities[i])); } ecs_fini(world); ecs_os_free(entities); } void Set_emplace(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new_id(world); test_assert(e != 0); Position *p = ecs_emplace(world, e, Position); test_assert(p != NULL); test_assert(ecs_has(world, e, Position)); test_assert(p == ecs_get(world, e, Position)); ecs_fini(world); } void Set_emplace_2(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_entity_t e = ecs_new_id(world); test_assert(e != 0); Position *p = ecs_emplace(world, e, Position); test_assert(p != NULL); test_assert(ecs_has(world, e, Position)); test_assert(p == ecs_get(world, e, Position)); Velocity *v = ecs_emplace(world, e, Velocity); test_assert(v != NULL); test_assert(ecs_has(world, e, Velocity)); test_assert(v == ecs_get(world, e, Velocity)); ecs_fini(world); } void Set_emplace_existing(void) { install_test_abort(); ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world, Position); test_assert(ecs_has(world, e, Position)); test_assert(e != 0); test_expect_abort(); ecs_emplace(world, e, Position); } void Set_emplace_w_move(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); // Create entity with name, as name is component that is moved ecs_entity_t e = ecs_set_name(world, 0, "Foo"); test_assert(e != 0); test_str("Foo", ecs_get_name(world, e)); Position *p = ecs_emplace(world, e, Position); test_assert(p != NULL); test_assert(ecs_has(world, e, Position)); test_assert(p == ecs_get(world, e, Position)); test_str("Foo", ecs_get_name(world, e)); ecs_fini(world); } static void OnAddMove(ecs_iter_t *it) { int i; for (i = 0; i < it->count; i ++) { ecs_set(it->world, it->entities[i], Velocity, {1, 2}); } } void Set_emplace_w_observer_w_add(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT_DEFINE(world, Position); ECS_COMPONENT_DEFINE(world, Velocity); ecs_observer_init(world, &(ecs_observer_desc_t){ .callback = OnAddMove, .events = {EcsOnAdd}, .filter.terms[0].id = ecs_id(Position) }); ecs_entity_t e = ecs_new_id(world); test_assert(e != 0); Position *p = ecs_emplace(world, e, Position); test_assert(p != NULL); p->x = 10; p->y = 20; test_assert(ecs_has(world, e, Position)); { const Position *pc = ecs_get(world, e, Position); test_assert(p == pc); test_int(pc->x, 10); test_int(pc->y, 20); const Velocity *vc = ecs_get(world, e, Velocity); test_assert(vc != NULL); test_int(vc->x, 1); test_int(vc->y, 2); } ecs_fini(world); }