#include void Iter_page_iter_0_0(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 0, 0); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.frame_offset, 0); test_int(pit.entities[0], e1); test_int(pit.entities[1], e2); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); test_int(ptr[1].value, e2); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.frame_offset, 2); test_int(pit.entities[0], e3); test_int(pit.entities[1], e4); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); test_int(ptr[1].value, e4); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.frame_offset, 4); test_int(pit.entities[0], e5); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_page_iter_1_0(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 1, 0); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e2); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e2); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e3); test_int(pit.entities[1], e4); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); test_int(ptr[1].value, e4); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e5); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_page_iter_0_1(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 0, 1); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e1); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_page_iter_n_0(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 2, 0); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e3); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e4); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e4); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e5); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_page_iter_0_n(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 0, 2); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e1); test_int(pit.entities[1], e2); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); test_int(ptr[1].value, e2); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_page_iter_m_n(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_entity_t e6 = ecs_new_id(world); ecs_set(world, e6, Self, {e6}); ecs_add(world, e4, TagA); ecs_add(world, e5, TagA); ecs_add(world, e6, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 2, 3); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e3); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e4); test_int(pit.entities[1], e5); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e4); test_int(ptr[1].value, e5); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_page_iter_skip_1_table(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 2, 0); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e3); test_int(pit.entities[1], e4); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); test_int(ptr[1].value, e4); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e5); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_page_iter_skip_2_tables(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagB); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 3, 0); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e4); test_int(pit.entities[1], e5); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e4); test_int(ptr[1].value, e5); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_worker_iter_1(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_worker_iter(&it, 0, 1); { test_bool(ecs_worker_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e1); test_int(pit.entities[1], e2); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); test_int(ptr[1].value, e2); } { test_bool(ecs_worker_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e3); test_int(pit.entities[1], e4); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); test_int(ptr[1].value, e4); } { test_bool(ecs_worker_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e5); test_int(pit.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); } test_bool(ecs_worker_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_worker_iter_2(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it_1 = ecs_filter_iter(world, &f); ecs_iter_t pit_1 = ecs_worker_iter(&it_1, 0, 2); ecs_iter_t it_2 = ecs_filter_iter(world, &f); ecs_iter_t pit_2 = ecs_worker_iter(&it_2, 1, 2); /* Iter 1 */ { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e1); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); } { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e3); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); } { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e5); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); } test_bool(ecs_worker_next(&pit_1), false); /* Iter 2 */ { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e2); test_int(pit_2.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e2); } { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e4); test_int(pit_2.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e4); } test_bool(ecs_worker_next(&pit_2), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_worker_iter_3(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_entity_t e6 = ecs_new_id(world); ecs_set(world, e6, Self, {e6}); ecs_add(world, e4, TagA); ecs_add(world, e5, TagA); ecs_add(world, e6, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it_1 = ecs_filter_iter(world, &f); ecs_iter_t pit_1 = ecs_worker_iter(&it_1, 0, 3); ecs_iter_t it_2 = ecs_filter_iter(world, &f); ecs_iter_t pit_2 = ecs_worker_iter(&it_2, 1, 3); ecs_iter_t it_3 = ecs_filter_iter(world, &f); ecs_iter_t pit_3 = ecs_worker_iter(&it_3, 2, 3); /* Iter 1 */ { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e1); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); } { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e4); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e4); } { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e6); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e6); } test_bool(ecs_worker_next(&pit_1), false); /* Iter 2 */ { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e2); test_int(pit_2.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e2); } { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e5); test_int(pit_2.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); } test_bool(ecs_worker_next(&pit_2), false); /* Iter 3 */ { test_bool(ecs_worker_next(&pit_3), true); test_int(pit_3.count, 1); test_int(pit_3.entities[0], e3); test_int(pit_3.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_3, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); } test_bool(ecs_worker_next(&pit_3), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_worker_iter_4(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_entity_t e6 = ecs_new_id(world); ecs_set(world, e6, Self, {e6}); ecs_entity_t e7 = ecs_new_id(world); ecs_set(world, e7, Self, {e7}); ecs_entity_t e8 = ecs_new_id(world); ecs_set(world, e8, Self, {e8}); ecs_entity_t e9 = ecs_new_id(world); ecs_set(world, e9, Self, {e9}); ecs_add(world, e5, TagA); ecs_add(world, e6, TagA); ecs_add(world, e7, TagA); ecs_add(world, e8, TagB); ecs_add(world, e9, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }} }); ecs_iter_t it_1 = ecs_filter_iter(world, &f); ecs_iter_t pit_1 = ecs_worker_iter(&it_1, 0, 4); ecs_iter_t it_2 = ecs_filter_iter(world, &f); ecs_iter_t pit_2 = ecs_worker_iter(&it_2, 1, 4); ecs_iter_t it_3 = ecs_filter_iter(world, &f); ecs_iter_t pit_3 = ecs_worker_iter(&it_3, 2, 4); ecs_iter_t it_4 = ecs_filter_iter(world, &f); ecs_iter_t pit_4 = ecs_worker_iter(&it_4, 3, 4); /* Iter 1 */ { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e1); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); } { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e5); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); } { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e8); test_int(pit_1.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e8); } test_bool(ecs_worker_next(&pit_1), false); /* Iter 2 */ { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e2); test_int(pit_2.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e2); } { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e6); test_int(pit_2.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e6); } { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e9); test_int(pit_2.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e9); } test_bool(ecs_worker_next(&pit_2), false); /* Iter 3 */ { test_bool(ecs_worker_next(&pit_3), true); test_int(pit_3.count, 1); test_int(pit_3.entities[0], e3); test_int(pit_3.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_3, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); } { test_bool(ecs_worker_next(&pit_3), true); test_int(pit_3.count, 1); test_int(pit_3.entities[0], e7); test_int(pit_3.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_3, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e7); } test_bool(ecs_worker_next(&pit_3), false); /* Iter 4 */ { test_bool(ecs_worker_next(&pit_4), true); test_int(pit_4.count, 1); test_int(pit_4.entities[0], e4); test_int(pit_4.ids[0], ecs_id(Self)); Self *ptr = ecs_field(&pit_4, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e4); } test_bool(ecs_worker_next(&pit_4), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_paged_iter_w_shared_comp(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Self); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t foo = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }, { ecs_id(Position), .src.id = foo} }, .instanced = true }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 0, 0); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e1); test_int(pit.entities[1], e2); test_int(pit.ids[0], ecs_id(Self)); test_int(pit.ids[1], ecs_id(Position)); test_int(pit.sources[0], 0); test_int(pit.sources[1], foo); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); test_int(ptr[1].value, e2); Position *pptr = ecs_field(&pit, Position, 2); test_int(pptr->x, 10); test_int(pptr->y, 20); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 2); test_int(pit.entities[0], e3); test_int(pit.entities[1], e4); test_int(pit.ids[0], ecs_id(Self)); test_int(pit.ids[1], ecs_id(Position)); test_int(pit.sources[0], 0); test_int(pit.sources[1], foo); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); test_int(ptr[1].value, e4); Position *pptr = ecs_field(&pit, Position, 2); test_int(pptr->x, 10); test_int(pptr->y, 20); } { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 1); test_int(pit.entities[0], e5); test_int(pit.ids[0], ecs_id(Self)); test_int(pit.ids[1], ecs_id(Position)); test_int(pit.sources[0], 0); test_int(pit.sources[1], foo); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); Position *pptr = ecs_field(&pit, Position, 2); test_int(pptr->x, 10); test_int(pptr->y, 20); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_worker_iter_w_shared_comp(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ECS_COMPONENT(world, Position); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t foo = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e1 = ecs_new_id(world); ecs_set(world, e1, Self, {e1}); ecs_entity_t e2 = ecs_new_id(world); ecs_set(world, e2, Self, {e2}); ecs_entity_t e3 = ecs_new_id(world); ecs_set(world, e3, Self, {e3}); ecs_entity_t e4 = ecs_new_id(world); ecs_set(world, e4, Self, {e4}); ecs_entity_t e5 = ecs_new_id(world); ecs_set(world, e5, Self, {e5}); ecs_add(world, e3, TagA); ecs_add(world, e4, TagA); ecs_add(world, e5, TagB); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self) }, { ecs_id(Position), .src.id = foo} }, .instanced = true }); ecs_iter_t it_1 = ecs_filter_iter(world, &f); ecs_iter_t pit_1 = ecs_worker_iter(&it_1, 0, 2); ecs_iter_t it_2 = ecs_filter_iter(world, &f); ecs_iter_t pit_2 = ecs_worker_iter(&it_2, 1, 2); /* Iter 1 */ { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e1); test_int(pit_1.ids[0], ecs_id(Self)); test_int(pit_1.ids[1], ecs_id(Position)); test_int(pit_1.sources[0], 0); test_int(pit_1.sources[1], foo); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e1); Position *pptr = ecs_field(&pit_1, Position, 2); test_int(pptr->x, 10); test_int(pptr->y, 20); } { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e3); test_int(pit_1.ids[0], ecs_id(Self)); test_int(pit_1.ids[1], ecs_id(Position)); test_int(pit_1.sources[0], 0); test_int(pit_1.sources[1], foo); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e3); Position *pptr = ecs_field(&pit_1, Position, 2); test_int(pptr->x, 10); test_int(pptr->y, 20); } { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e5); test_int(pit_1.ids[0], ecs_id(Self)); test_int(pit_1.ids[1], ecs_id(Position)); test_int(pit_1.sources[0], 0); test_int(pit_1.sources[1], foo); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e5); Position *pptr = ecs_field(&pit_1, Position, 2); test_int(pptr->x, 10); test_int(pptr->y, 20); } test_bool(ecs_worker_next(&pit_1), false); /* Iter 2 */ { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e2); test_int(pit_2.ids[0], ecs_id(Self)); test_int(pit_2.ids[1], ecs_id(Position)); test_int(pit_2.sources[0], 0); test_int(pit_2.sources[1], foo); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e2); Position *pptr = ecs_field(&pit_2, Position, 2); test_int(pptr->x, 10); test_int(pptr->y, 20); } { test_bool(ecs_worker_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e4); test_int(pit_2.ids[0], ecs_id(Self)); test_int(pit_2.ids[1], ecs_id(Position)); test_int(pit_2.sources[0], 0); test_int(pit_2.sources[1], foo); Self *ptr = ecs_field(&pit_2, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, e4); Position *pptr = ecs_field(&pit_2, Position, 2); test_int(pptr->x, 10); test_int(pptr->y, 20); } test_bool(ecs_worker_next(&pit_2), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_paged_iter_w_task_query(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ecs_entity_t foo = ecs_new_id(world); ecs_set(world, foo, Self, {foo}); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self), .src.id = foo }} }); ecs_iter_t it = ecs_filter_iter(world, &f); ecs_iter_t pit = ecs_page_iter(&it, 0, 0); { test_bool(ecs_page_next(&pit), true); test_int(pit.count, 0); test_int(pit.ids[0], ecs_id(Self)); test_int(pit.sources[0], foo); Self *ptr = ecs_field(&pit, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, foo); } test_bool(ecs_page_next(&pit), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_worker_iter_w_task_query(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Self); ecs_entity_t foo = ecs_new_id(world); ecs_set(world, foo, Self, {foo}); ecs_filter_t f = ECS_FILTER_INIT; ecs_filter_init(world, &(ecs_filter_desc_t){ .storage = &f, .terms = {{ ecs_id(Self), .src.id = foo }} }); ecs_iter_t it_1 = ecs_filter_iter(world, &f); ecs_iter_t pit_1 = ecs_worker_iter(&it_1, 0, 2); ecs_iter_t it_2 = ecs_filter_iter(world, &f); ecs_iter_t pit_2 = ecs_worker_iter(&it_2, 1, 2); /* Iter 1 */ { test_bool(ecs_worker_next(&pit_1), true); test_int(pit_1.count, 0); test_int(pit_1.ids[0], ecs_id(Self)); test_int(pit_1.sources[0], foo); Self *ptr = ecs_field(&pit_1, Self, 1); test_assert(ptr != NULL); test_int(ptr[0].value, foo); } test_bool(ecs_worker_next(&pit_1), false); /* Iter 2 */ test_bool(ecs_worker_next(&pit_2), false); ecs_filter_fini(&f); ecs_fini(world); } void Iter_worker_iter_w_singleton(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Singleton); ECS_COMPONENT(world, Position); ecs_singleton_add(world, Singleton); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_entity_t e3 = ecs_set(world, 0, Position, {30, 40}); ecs_entity_t e4 = ecs_set(world, 0, Position, {40, 50}); ecs_query_t *q = ecs_query_new(world, "Position, Singleton($)"); Position *p; ecs_iter_t it_1 = ecs_query_iter(world, q); ecs_iter_t wit_1 = ecs_worker_iter(&it_1, 0, 2); test_bool(ecs_worker_next(&wit_1), true); test_int(wit_1.count, 2); test_int(wit_1.entities[0], e1); test_int(wit_1.entities[1], e2); p = ecs_field(&wit_1, Position, 1); test_int(p[0].x, 10); test_int(p[0].y, 20); test_int(p[1].x, 20); test_int(p[1].y, 30); ecs_iter_t it_2 = ecs_query_iter(world, q); ecs_iter_t wit_2 = ecs_worker_iter(&it_2, 1, 2); test_bool(ecs_worker_next(&wit_2), true); test_int(wit_2.count, 2); test_int(wit_2.entities[0], e3); test_int(wit_2.entities[1], e4); p = ecs_field(&wit_2, Position, 1); test_int(p[0].x, 30); test_int(p[0].y, 40); test_int(p[1].x, 40); test_int(p[1].y, 50); test_bool(ecs_worker_next(&wit_2), false); test_bool(ecs_worker_next(&wit_1), false); ecs_fini(world); } void Iter_worker_iter_w_singleton_component(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_singleton_set(world, Velocity, {1, 2}); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_entity_t e3 = ecs_set(world, 0, Position, {30, 40}); ecs_entity_t e4 = ecs_set(world, 0, Position, {40, 50}); ecs_query_t *q = ecs_query_new(world, "Position, Velocity($)"); Position *p; Velocity *v; ecs_iter_t it_1 = ecs_query_iter(world, q); ecs_iter_t wit_1 = ecs_worker_iter(&it_1, 0, 2); test_bool(ecs_worker_next(&wit_1), true); test_int(wit_1.count, 1); test_int(wit_1.entities[0], e1); p = ecs_field(&wit_1, Position, 1); test_int(p[0].x, 10); test_int(p[0].y, 20); v = ecs_field(&wit_1, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_worker_next(&wit_1), true); test_int(wit_1.count, 1); test_int(wit_1.entities[0], e2); p = ecs_field(&wit_1, Position, 1); test_int(p[0].x, 20); test_int(p[0].y, 30); v = ecs_field(&wit_1, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_worker_next(&wit_1), false); ecs_iter_t it_2 = ecs_query_iter(world, q); ecs_iter_t wit_2 = ecs_worker_iter(&it_2, 1, 2); test_bool(ecs_worker_next(&wit_2), true); test_int(wit_2.count, 1); test_int(wit_2.entities[0], e3); p = ecs_field(&wit_2, Position, 1); test_int(p[0].x, 30); test_int(p[0].y, 40); v = ecs_field(&wit_2, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_worker_next(&wit_2), true); test_int(wit_2.count, 1); test_int(wit_2.entities[0], e4); p = ecs_field(&wit_2, Position, 1); test_int(p[0].x, 40); test_int(p[0].y, 50); v = ecs_field(&wit_2, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_worker_next(&wit_2), false); ecs_fini(world); } void Iter_worker_iter_w_singleton_instanced(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Singleton); ECS_COMPONENT(world, Position); ecs_singleton_add(world, Singleton); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_entity_t e3 = ecs_set(world, 0, Position, {30, 40}); ecs_entity_t e4 = ecs_set(world, 0, Position, {40, 50}); ecs_query_t *q = ecs_query_init(world, &(ecs_query_desc_t){ .filter = { .expr = "Position, Singleton($)", .instanced = true } }); Position *p; ecs_iter_t it_1 = ecs_query_iter(world, q); ecs_iter_t wit_1 = ecs_worker_iter(&it_1, 0, 2); test_bool(ecs_worker_next(&wit_1), true); test_int(wit_1.count, 2); test_int(wit_1.entities[0], e1); test_int(wit_1.entities[1], e2); p = ecs_field(&wit_1, Position, 1); test_int(p[0].x, 10); test_int(p[0].y, 20); test_int(p[1].x, 20); test_int(p[1].y, 30); test_bool(ecs_worker_next(&wit_1), false); ecs_iter_t it_2 = ecs_query_iter(world, q); ecs_iter_t wit_2 = ecs_worker_iter(&it_2, 1, 2); test_bool(ecs_worker_next(&wit_2), true); test_int(wit_2.count, 2); test_int(wit_2.entities[0], e3); test_int(wit_2.entities[1], e4); p = ecs_field(&wit_2, Position, 1); test_int(p[0].x, 30); test_int(p[0].y, 40); test_int(p[1].x, 40); test_int(p[1].y, 50); test_bool(ecs_worker_next(&wit_2), false); ecs_fini(world); } void Iter_worker_iter_w_singleton_component_instanced(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_singleton_set(world, Velocity, {1, 2}); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_entity_t e3 = ecs_set(world, 0, Position, {30, 40}); ecs_entity_t e4 = ecs_set(world, 0, Position, {40, 50}); ecs_query_t *q = ecs_query_init(world, &(ecs_query_desc_t){ .filter = { .expr = "Position, Velocity($)", .instanced = true } }); Position *p; Velocity *v; ecs_iter_t it_1 = ecs_query_iter(world, q); ecs_iter_t wit_1 = ecs_worker_iter(&it_1, 0, 2); test_bool(ecs_worker_next(&wit_1), true); test_int(wit_1.count, 2); test_int(wit_1.entities[0], e1); test_int(wit_1.entities[1], e2); p = ecs_field(&wit_1, Position, 1); test_int(p[0].x, 10); test_int(p[0].y, 20); test_int(p[1].x, 20); test_int(p[1].y, 30); v = ecs_field(&wit_1, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_worker_next(&wit_1), false); ecs_iter_t it_2 = ecs_query_iter(world, q); ecs_iter_t wit_2 = ecs_worker_iter(&it_2, 1, 2); test_bool(ecs_worker_next(&wit_2), true); test_int(wit_2.count, 2); test_int(wit_2.entities[0], e3); test_int(wit_2.entities[1], e4); p = ecs_field(&wit_2, Position, 1); test_int(p[0].x, 30); test_int(p[0].y, 40); test_int(p[1].x, 40); test_int(p[1].y, 50); v = ecs_field(&wit_2, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_worker_next(&wit_2), false); ecs_fini(world); } void Iter_paged_iter_w_singleton(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Singleton); ECS_COMPONENT(world, Position); ecs_singleton_add(world, Singleton); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_entity_t e3 = ecs_set(world, 0, Position, {30, 40}); ecs_entity_t e4 = ecs_set(world, 0, Position, {40, 50}); ecs_query_t *q = ecs_query_new(world, "Position, Singleton($)"); Position *p; ecs_iter_t it_1 = ecs_query_iter(world, q); ecs_iter_t pit_1 = ecs_page_iter(&it_1, 0, 2); test_bool(ecs_page_next(&pit_1), true); test_int(pit_1.count, 2); test_int(pit_1.entities[0], e1); test_int(pit_1.entities[1], e2); p = ecs_field(&pit_1, Position, 1); test_int(p[0].x, 10); test_int(p[0].y, 20); test_int(p[1].x, 20); test_int(p[1].y, 30); test_bool(ecs_page_next(&pit_1), false); ecs_iter_t it_2 = ecs_query_iter(world, q); ecs_iter_t pit_2 = ecs_page_iter(&it_2, 2, 2); test_bool(ecs_page_next(&pit_2), true); test_int(pit_2.count, 2); test_int(pit_2.entities[0], e3); test_int(pit_2.entities[1], e4); p = ecs_field(&pit_2, Position, 1); test_int(p[0].x, 30); test_int(p[0].y, 40); test_int(p[1].x, 40); test_int(p[1].y, 50); test_bool(ecs_page_next(&pit_2), false); ecs_fini(world); } void Iter_paged_iter_w_singleton_component(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_singleton_set(world, Velocity, {1, 2}); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_entity_t e3 = ecs_set(world, 0, Position, {30, 40}); ecs_entity_t e4 = ecs_set(world, 0, Position, {40, 50}); ecs_query_t *q = ecs_query_new(world, "Position, Velocity($)"); Position *p; Velocity *v; ecs_iter_t it_1 = ecs_query_iter(world, q); ecs_iter_t pit_1 = ecs_page_iter(&it_1, 0, 2); test_bool(ecs_page_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e1); p = ecs_field(&pit_1, Position, 1); test_int(p[0].x, 10); test_int(p[0].y, 20); v = ecs_field(&pit_1, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_page_next(&pit_1), true); test_int(pit_1.count, 1); test_int(pit_1.entities[0], e2); p = ecs_field(&pit_1, Position, 1); test_int(p[0].x, 20); test_int(p[0].y, 30); v = ecs_field(&pit_1, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_page_next(&pit_1), false); ecs_iter_t it_2 = ecs_query_iter(world, q); ecs_iter_t pit_2 = ecs_page_iter(&it_2, 2, 2); test_bool(ecs_page_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e3); p = ecs_field(&pit_2, Position, 1); test_int(p[0].x, 30); test_int(p[0].y, 40); v = ecs_field(&pit_2, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_page_next(&pit_2), true); test_int(pit_2.count, 1); test_int(pit_2.entities[0], e4); p = ecs_field(&pit_2, Position, 1); test_int(p[0].x, 40); test_int(p[0].y, 50); v = ecs_field(&pit_2, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_page_next(&pit_2), false); ecs_fini(world); } void Iter_paged_iter_w_singleton_instanced(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Singleton); ECS_COMPONENT(world, Position); ecs_singleton_add(world, Singleton); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_entity_t e3 = ecs_set(world, 0, Position, {30, 40}); ecs_entity_t e4 = ecs_set(world, 0, Position, {40, 50}); ecs_query_t *q = ecs_query_init(world, &(ecs_query_desc_t){ .filter = { .expr = "Position, Singleton($)", .instanced = true } }); Position *p; ecs_iter_t it_1 = ecs_query_iter(world, q); ecs_iter_t pit_1 = ecs_page_iter(&it_1, 0, 2); test_bool(ecs_page_next(&pit_1), true); test_int(pit_1.count, 2); test_int(pit_1.entities[0], e1); test_int(pit_1.entities[1], e2); p = ecs_field(&pit_1, Position, 1); test_int(p[0].x, 10); test_int(p[0].y, 20); test_int(p[1].x, 20); test_int(p[1].y, 30); test_bool(ecs_page_next(&pit_1), false); ecs_iter_t it_2 = ecs_query_iter(world, q); ecs_iter_t pit_2 = ecs_page_iter(&it_2, 2, 2); test_bool(ecs_page_next(&pit_2), true); test_int(pit_2.count, 2); test_int(pit_2.entities[0], e3); test_int(pit_2.entities[1], e4); p = ecs_field(&pit_2, Position, 1); test_int(p[0].x, 30); test_int(p[0].y, 40); test_int(p[1].x, 40); test_int(p[1].y, 50); test_bool(ecs_page_next(&pit_2), false); ecs_fini(world); } void Iter_paged_iter_w_singleton_component_instanced(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_singleton_set(world, Velocity, {1, 2}); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_entity_t e3 = ecs_set(world, 0, Position, {30, 40}); ecs_entity_t e4 = ecs_set(world, 0, Position, {40, 50}); ecs_query_t *q = ecs_query_init(world, &(ecs_query_desc_t){ .filter = { .expr = "Position, Velocity($)", .instanced = true } }); Position *p; Velocity *v; ecs_iter_t it_1 = ecs_query_iter(world, q); ecs_iter_t pit_1 = ecs_page_iter(&it_1, 0, 2); test_bool(ecs_page_next(&pit_1), true); test_int(pit_1.count, 2); test_int(pit_1.entities[0], e1); test_int(pit_1.entities[1], e2); p = ecs_field(&pit_1, Position, 1); test_int(p[0].x, 10); test_int(p[0].y, 20); test_int(p[1].x, 20); test_int(p[1].y, 30); v = ecs_field(&pit_1, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_page_next(&pit_1), false); ecs_iter_t it_2 = ecs_query_iter(world, q); ecs_iter_t pit_2 = ecs_page_iter(&it_2, 2, 2); test_bool(ecs_page_next(&pit_2), true); test_int(pit_2.count, 2); test_int(pit_2.entities[0], e3); test_int(pit_2.entities[1], e4); p = ecs_field(&pit_2, Position, 1); test_int(p[0].x, 30); test_int(p[0].y, 40); test_int(p[1].x, 40); test_int(p[1].y, 50); v = ecs_field(&pit_2, Velocity, 2); test_int(v[0].x, 1); test_int(v[0].y, 2); test_bool(ecs_page_next(&pit_2), false); ecs_fini(world); } void Iter_count(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ECS_TAG(world, TagC); for (int i = 0; i < 500; i ++) { ecs_entity_t e = ecs_new(world, TagA); if (!(i % 2)) { ecs_add(world, e, TagB); } if (!(i % 3)) { ecs_add(world, e, TagC); } } ecs_query_t *q = ecs_query_new(world, "TagA"); test_assert(q != NULL); ecs_iter_t it = ecs_query_iter(world, q); test_int(500, ecs_iter_count(&it)); ecs_fini(world); } void Iter_interleaved_iter(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_filter_t *f = ecs_filter(world, { .terms = {{ TagA }} }); ecs_entity_t e1 = ecs_new(world, TagA); ecs_entity_t e2 = ecs_new(world, TagA); ecs_add(world, e2, TagB); /* Bit of whitebox testing, check whether the stack cursor is restored to * its original position after the 2nd iterator is done */ ecs_iter_t it_1 = ecs_filter_iter(world, f); ecs_stack_cursor_t cursor = *it_1.priv.cache.stack_cursor; ecs_iter_t it_2 = ecs_filter_iter(world, f); test_bool(true, ecs_filter_next(&it_1)); test_bool(true, ecs_filter_next(&it_2)); test_int(e1, it_1.entities[0]); test_int(e1, it_2.entities[0]); test_bool(true, ecs_filter_next(&it_1)); test_bool(true, ecs_filter_next(&it_2)); test_int(e2, it_1.entities[0]); test_int(e2, it_2.entities[0]); test_bool(false, ecs_filter_next(&it_1)); test_bool(false, ecs_filter_next(&it_2)); it_1 = ecs_filter_iter(world, f); test_assert(it_1.priv.cache.stack_cursor->page == cursor.page); test_assert(it_1.priv.cache.stack_cursor->sp == cursor.sp); ecs_iter_fini(&it_1); ecs_filter_fini(f); ecs_fini(world); } void Iter_iter_restore_stack_iter(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_filter_t *f = ecs_filter(world, { .terms = {{ ecs_id(Position) }} }); ecs_iter_t it = ecs_filter_iter(world, f); ecs_stack_cursor_t cursor = *it.priv.cache.stack_cursor; ecs_iter_fini(&it); it = ecs_filter_iter(world, f); test_assert(it.priv.cache.stack_cursor->page == cursor.page); test_assert(it.priv.cache.stack_cursor->sp == cursor.sp); ecs_iter_fini(&it); ecs_filter_fini(f); ecs_fini(world); } void Iter_get_first(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Tag); ecs_entity_t e = ecs_new(world, Tag); ecs_new(world, Tag); ecs_new(world, Tag); ecs_filter_t *f = ecs_filter_init(world, &(ecs_filter_desc_t){ .terms = {{ Tag }} }); ecs_iter_t it = ecs_filter_iter(world, f); ecs_entity_t first = ecs_iter_first(&it); test_assert(first == e); ecs_filter_fini(f); ecs_fini(world); } void Iter_page_iter_w_only_tag(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Tag); ecs_filter_t *f = ecs_filter(world, { .terms = {{ Tag }} }); ecs_new(world, Tag); ecs_entity_t e2 = ecs_new(world, Tag); ecs_iter_t it = ecs_filter_iter(world, f); ecs_iter_t pit = ecs_page_iter(&it, 1, 0); test_assert(ecs_page_next(&pit)); test_int(pit.count, 1); test_uint(pit.entities[0], e2); test_assert(!ecs_page_next(&pit)); ecs_filter_fini(f); ecs_fini(world); } void Iter_worker_iter_w_only_tag(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Tag); ecs_filter_t *f = ecs_filter(world, { .terms = {{ Tag }} }); ecs_new(world, Tag); ecs_entity_t e2 = ecs_new(world, Tag); ecs_iter_t it = ecs_filter_iter(world, f); ecs_iter_t pit = ecs_worker_iter(&it, 1, 2); test_assert(ecs_worker_next(&pit)); test_int(pit.count, 1); test_uint(pit.entities[0], e2); test_assert(!ecs_worker_next(&pit)); ecs_filter_fini(f); ecs_fini(world); } void Iter_page_iter_w_inout_none(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_filter_t *f = ecs_filter(world, { .terms = {{ ecs_id(Position), .inout = EcsInOutNone }} }); ecs_new(world, Position); ecs_entity_t e2 = ecs_new(world, Position); ecs_iter_t it = ecs_filter_iter(world, f); ecs_iter_t pit = ecs_page_iter(&it, 1, 0); test_assert(ecs_page_next(&pit)); test_int(pit.count, 1); test_uint(pit.entities[0], e2); test_assert(!ecs_page_next(&pit)); ecs_filter_fini(f); ecs_fini(world); } void Iter_worker_iter_w_inout_none(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ecs_filter_t *f = ecs_filter(world, { .terms = {{ ecs_id(Position), .inout = EcsInOutNone }} }); ecs_new(world, Position); ecs_entity_t e2 = ecs_new(world, Position); ecs_iter_t it = ecs_filter_iter(world, f); ecs_iter_t pit = ecs_worker_iter(&it, 1, 2); test_assert(ecs_worker_next(&pit)); test_int(pit.count, 1); test_uint(pit.entities[0], e2); test_assert(!ecs_worker_next(&pit)); ecs_filter_fini(f); ecs_fini(world); } void Iter_page_iter_w_ctx(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, TagA); ecs_filter_t *f = ecs_filter(world, { .terms = {{ TagA }} }); ecs_new(world, TagA); int ctx; ecs_iter_t it = ecs_filter_iter(world, f); it.ctx = &ctx; ecs_iter_t pit = ecs_page_iter(&it, 0, 1); test_assert(pit.ctx == &ctx); test_assert(ecs_page_next(&pit)); test_assert(!ecs_page_next(&pit)); ecs_filter_fini(f); ecs_fini(world); } void Iter_page_iter_w_binding_ctx(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, TagA); ecs_filter_t *f = ecs_filter(world, { .terms = {{ TagA }} }); ecs_new(world, TagA); int ctx; ecs_iter_t it = ecs_filter_iter(world, f); it.binding_ctx = &ctx; ecs_iter_t pit = ecs_page_iter(&it, 0, 1); test_assert(pit.binding_ctx == &ctx); test_assert(ecs_page_next(&pit)); test_assert(!ecs_page_next(&pit)); ecs_filter_fini(f); ecs_fini(world); } void Iter_worker_iter_w_ctx(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, TagA); ecs_filter_t *f = ecs_filter(world, { .terms = {{ TagA }} }); ecs_new(world, TagA); int ctx; ecs_iter_t it = ecs_filter_iter(world, f); it.ctx = &ctx; ecs_iter_t pit = ecs_worker_iter(&it, 0, 2); test_assert(pit.ctx == &ctx); test_assert(ecs_worker_next(&pit)); test_assert(!ecs_worker_next(&pit)); ecs_filter_fini(f); ecs_fini(world); } void Iter_worker_iter_w_binding_ctx(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, TagA); ecs_filter_t *f = ecs_filter(world, { .terms = {{ TagA }} }); ecs_new(world, TagA); int ctx; ecs_iter_t it = ecs_filter_iter(world, f); it.binding_ctx = &ctx; ecs_iter_t pit = ecs_worker_iter(&it, 0, 2); test_assert(pit.binding_ctx == &ctx); test_assert(ecs_worker_next(&pit)); test_assert(!ecs_worker_next(&pit)); ecs_filter_fini(f); ecs_fini(world); } void Iter_column_index_owned(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ECS_TAG(world, TagC); ecs_filter_t *f = ecs_filter(world, { .terms = {{ TagB }, { TagC }, { TagA }} }); ecs_entity_t e1 = ecs_new_id(world); ecs_add(world, e1, TagA); ecs_add(world, e1, TagB); ecs_add(world, e1, TagC); ecs_entity_t e2 = ecs_new(world, Position); ecs_add(world, e2, TagA); ecs_add(world, e2, TagB); ecs_add(world, e2, TagC); ecs_iter_t it = ecs_filter_iter(world, f); test_bool(true, ecs_filter_next(&it)); test_int(1, it.count); test_uint(e1, it.entities[0]); test_int(1, ecs_field_column_index(&it, 1)); test_int(2, ecs_field_column_index(&it, 2)); test_int(0, ecs_field_column_index(&it, 3)); test_bool(true, ecs_filter_next(&it)); test_int(1, it.count); test_uint(e2, it.entities[0]); test_int(2, ecs_field_column_index(&it, 1)); test_int(3, ecs_field_column_index(&it, 2)); test_int(1, ecs_field_column_index(&it, 3)); test_bool(false, ecs_filter_next(&it)); ecs_filter_fini(f); ecs_fini(world); } void Iter_column_index_shared(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ECS_TAG(world, TagC); ecs_filter_t *f = ecs_filter(world, { .terms = {{ TagB }, { TagC }, { TagA }} }); ecs_entity_t base = ecs_new(world, TagA); ecs_entity_t e1 = ecs_new_id(world); ecs_add_pair(world, e1, EcsIsA, base); ecs_add(world, e1, TagB); ecs_add(world, e1, TagC); ecs_entity_t e2 = ecs_new(world, Position); ecs_add_pair(world, e2, EcsIsA, base); ecs_add(world, e2, TagB); ecs_add(world, e2, TagC); ecs_iter_t it = ecs_filter_iter(world, f); test_bool(true, ecs_filter_next(&it)); test_int(1, it.count); test_uint(e1, it.entities[0]); test_int(0, ecs_field_column_index(&it, 1)); test_int(1, ecs_field_column_index(&it, 2)); test_int(-1, ecs_field_column_index(&it, 3)); test_bool(true, ecs_filter_next(&it)); test_int(1, it.count); test_uint(e2, it.entities[0]); test_int(1, ecs_field_column_index(&it, 1)); test_int(2, ecs_field_column_index(&it, 2)); test_int(-1, ecs_field_column_index(&it, 3)); test_bool(false, ecs_filter_next(&it)); ecs_filter_fini(f); ecs_fini(world); } void Iter_column_index_not(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ECS_TAG(world, TagC); ecs_filter_t *f = ecs_filter(world, { .terms = {{ TagB }, { TagC }, { TagA, .oper = EcsNot }} }); ecs_entity_t e1 = ecs_new_id(world); ecs_add(world, e1, TagB); ecs_add(world, e1, TagC); ecs_entity_t e2 = ecs_new(world, Position); ecs_add(world, e2, TagB); ecs_add(world, e2, TagC); ecs_iter_t it = ecs_filter_iter(world, f); test_bool(true, ecs_filter_next(&it)); test_int(1, it.count); test_uint(e1, it.entities[0]); test_int(0, ecs_field_column_index(&it, 1)); test_int(1, ecs_field_column_index(&it, 2)); test_int(-1, ecs_field_column_index(&it, 3)); test_bool(true, ecs_filter_next(&it)); test_int(1, it.count); test_uint(e2, it.entities[0]); test_int(1, ecs_field_column_index(&it, 1)); test_int(2, ecs_field_column_index(&it, 2)); test_int(-1, ecs_field_column_index(&it, 3)); test_bool(false, ecs_filter_next(&it)); ecs_filter_fini(f); ecs_fini(world); } void Iter_page_iter_w_fini(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, Foo); ecs_filter_t *f = ecs_filter(world, { .terms = {{ ecs_id(Position) }} }); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_add(world, e2, Foo); ecs_iter_t it = ecs_filter_iter(world, f); ecs_iter_t pit = ecs_page_iter(&it, 0, 2); test_bool(true, ecs_page_next(&pit)); test_int(pit.count, 1); test_int(pit.entities[0], e1); ecs_iter_fini(&pit); ecs_filter_fini(f); ecs_fini(world); } void Iter_worker_iter_w_fini(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, Foo); ecs_filter_t *f = ecs_filter(world, { .terms = {{ ecs_id(Position) }} }); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_add(world, e2, Foo); ecs_iter_t it = ecs_filter_iter(world, f); ecs_iter_t pit = ecs_worker_iter(&it, 0, 2); test_bool(true, ecs_worker_next(&pit)); test_int(pit.count, 1); test_int(pit.entities[0], e1); ecs_iter_fini(&pit); ecs_filter_fini(f); ecs_fini(world); } void Iter_rule_page_iter_w_fini(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, Foo); ecs_rule_t *r = ecs_rule(world, { .terms = {{ ecs_id(Position) }} }); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_add(world, e2, Foo); ecs_iter_t it = ecs_rule_iter(world, r); ecs_iter_t pit = ecs_page_iter(&it, 0, 2); test_bool(true, ecs_page_next(&pit)); test_int(pit.count, 1); test_int(pit.entities[0], e1); ecs_iter_fini(&pit); ecs_rule_fini(r); ecs_fini(world); } void Iter_rule_worker_iter_w_fini(void) { ecs_world_t *world = ecs_mini(); ECS_COMPONENT(world, Position); ECS_TAG(world, Foo); ecs_rule_t *r = ecs_rule(world, { .terms = {{ ecs_id(Position) }} }); ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20}); ecs_entity_t e2 = ecs_set(world, 0, Position, {20, 30}); ecs_add(world, e2, Foo); ecs_iter_t it = ecs_rule_iter(world, r); ecs_iter_t pit = ecs_worker_iter(&it, 0, 2); test_bool(true, ecs_worker_next(&pit)); test_int(pit.count, 1); test_int(pit.entities[0], e1); ecs_iter_fini(&pit); ecs_rule_fini(r); ecs_fini(world); } void Iter_to_str_before_next(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Tag); ecs_query_t *q = ecs_query_new(world, "Tag"); test_assert(q != NULL); ecs_iter_t it = ecs_query_iter(world, q); char *str = ecs_iter_str(&it); test_assert(str == NULL); test_bool(false, ecs_query_next(&it)); ecs_fini(world); } void Iter_to_str(void) { ecs_world_t *world = ecs_mini(); ECS_TAG(world, Tag); ecs_entity_t e = ecs_new_entity(world, "foo"); ecs_add(world, e, Tag); ecs_query_t *q = ecs_query_new(world, "Tag"); test_assert(q != NULL); ecs_iter_t it = ecs_query_iter(world, q); test_bool(true, ecs_query_next(&it)); char *str = ecs_iter_str(&it); test_assert(str != NULL); test_str(str, "id: Tag\n" "src: 0\n" "set: true\n" "this:\n" " - foo\n" ); ecs_os_free(str); test_bool(false, ecs_query_next(&it)); ecs_fini(world); }