From b0a4fe620c2896fc2a314761c7e8bff7d5490871 Mon Sep 17 00:00:00 2001 From: Sander Mertens Date: Tue, 16 Jul 2024 13:31:21 -0700 Subject: [PATCH] Don't insert query populate instructions for terms with #0 source --- flecs.c | 4 +- src/query/validator.c | 4 +- test/query/project.json | 14 ++- test/query/src/Plan.c | 245 ++++++++++++++++++++++++++++++++++++++++ test/query/src/Sparse.c | 58 ++++++++++ test/query/src/main.c | 54 ++++++++- 6 files changed, 373 insertions(+), 6 deletions(-) diff --git a/flecs.c b/flecs.c index 61d82387c..3f2b30f06 100644 --- a/flecs.c +++ b/flecs.c @@ -34164,7 +34164,9 @@ int flecs_query_finalize_terms( } } - if (term->inout == EcsInOutNone) { + if (term->src.id == EcsIsEntity) { + nodata_term = true; + } else if (term->inout == EcsInOutNone) { nodata_term = true; } else if (!ecs_get_type_info(world, term->id)) { nodata_term = true; diff --git a/src/query/validator.c b/src/query/validator.c index bbb450a09..b46e21c45 100644 --- a/src/query/validator.c +++ b/src/query/validator.c @@ -1190,7 +1190,9 @@ int flecs_query_finalize_terms( } } - if (term->inout == EcsInOutNone) { + if (term->src.id == EcsIsEntity) { + nodata_term = true; + } else if (term->inout == EcsInOutNone) { nodata_term = true; } else if (!ecs_get_type_info(world, term->id)) { nodata_term = true; diff --git a/test/query/project.json b/test/query/project.json index 252e69fae..5eba5ee59 100644 --- a/test/query/project.json +++ b/test/query/project.json @@ -751,7 +751,15 @@ "pair_first_wildcard", "pair_first_wildcard_cached", "pair_second_wildcard", - "pair_second_wildcard_cached" + "pair_second_wildcard_cached", + "0_src_tag", + "0_src_component", + "0_src_w_sparse", + "0_src_w_toggle", + "0_src_w_union", + "0_src_w_sparse_and_component", + "0_src_w_toggle_and_component", + "0_src_w_union_and_component" ] }, { "id": "Variables", @@ -1903,7 +1911,9 @@ "1_sparse_self_up", "1_sparse_written_self", "1_sparse_written_up", - "1_sparse_written_self_up" + "1_sparse_written_self_up", + "sparse_0_src_only_term", + "sparse_0_src" ] }, { "id": "Union", diff --git a/test/query/src/Plan.c b/test/query/src/Plan.c index 8f6ce9577..eb99de6e7 100644 --- a/test/query/src/Plan.c +++ b/test/query/src/Plan.c @@ -2317,3 +2317,248 @@ void Plan_pair_second_wildcard_cached(void) { ecs_fini(world); } + +void Plan_0_src_tag(void) { + ecs_world_t *world = ecs_mini(); + + ECS_TAG(world, Foo); + + ecs_query_t *q = ecs_query(world, { + .expr = "Foo(#0)" + }); + + test_assert(q != NULL); + + ecs_log_enable_colors(false); + + const char *expect = + HEAD " 0. [-1, 1] setfix " + LINE " 1. [ 0, 2] setids " + LINE " 2. [ 1, 3] yield " + LINE ""; + char *plan = ecs_query_plan(q); + + test_str(expect, plan); + ecs_os_free(plan); + + ecs_query_fini(q); + + ecs_fini(world); +} + +void Plan_0_src_component(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + + ecs_query_t *q = ecs_query(world, { + .expr = "Position(#0)" + }); + + test_assert(q != NULL); + + ecs_log_enable_colors(false); + + const char *expect = + HEAD " 0. [-1, 1] setfix " + LINE " 1. [ 0, 2] setids " + LINE " 2. [ 1, 3] yield " + LINE ""; + char *plan = ecs_query_plan(q); + + test_str(expect, plan); + ecs_os_free(plan); + + ecs_query_fini(q); + + ecs_fini(world); +} + +void Plan_0_src_w_sparse(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + + ecs_add_id(world, ecs_id(Position), EcsSparse); + + ecs_query_t *q = ecs_query(world, { + .expr = "Position(#0)" + }); + + test_assert(q != NULL); + + ecs_log_enable_colors(false); + + const char *expect = + HEAD " 0. [-1, 1] setfix " + LINE " 1. [ 0, 2] setids " + LINE " 2. [ 1, 3] yield " + LINE ""; + char *plan = ecs_query_plan(q); + + test_str(expect, plan); + ecs_os_free(plan); + + ecs_query_fini(q); + + ecs_fini(world); +} + +void Plan_0_src_w_toggle(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + + ecs_add_id(world, ecs_id(Position), EcsCanToggle); + + ecs_query_t *q = ecs_query(world, { + .expr = "Position(#0)" + }); + + test_assert(q != NULL); + + ecs_log_enable_colors(false); + + const char *expect = + HEAD " 0. [-1, 1] setfix " + LINE " 1. [ 0, 2] setids " + LINE " 2. [ 1, 3] yield " + LINE ""; + char *plan = ecs_query_plan(q); + + test_str(expect, plan); + ecs_os_free(plan); + + ecs_query_fini(q); + + ecs_fini(world); +} + +void Plan_0_src_w_union(void) { + ecs_world_t *world = ecs_mini(); + + ECS_TAG(world, Movement); + + ecs_add_id(world, ecs_id(Movement), EcsUnion); + + ecs_query_t *q = ecs_query(world, { + .expr = "Movement(#0, *)" + }); + + test_assert(q != NULL); + + ecs_log_enable_colors(false); + + const char *expect = + HEAD " 0. [-1, 1] setfix " + LINE " 1. [ 0, 2] setids " + LINE " 2. [ 1, 3] yield " + LINE ""; + char *plan = ecs_query_plan(q); + + test_str(expect, plan); + ecs_os_free(plan); + + ecs_query_fini(q); + + ecs_fini(world); +} + +void Plan_0_src_w_sparse_and_component(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + ECS_COMPONENT(world, Velocity); + + ecs_add_id(world, ecs_id(Position), EcsSparse); + + ecs_query_t *q = ecs_query(world, { + .expr = "Position(#0), Velocity" + }); + + test_assert(q != NULL); + + ecs_log_enable_colors(false); + + const char *expect = + HEAD " 0. [-1, 1] setfix " + LINE " 1. [ 0, 2] setids " + LINE " 2. [ 1, 3] andid $[this] (Velocity)" + LINE " 3. [ 2, 4] popself {1}" + LINE " 4. [ 3, 5] yield " + LINE ""; + char *plan = ecs_query_plan(q); + + test_str(expect, plan); + ecs_os_free(plan); + + ecs_query_fini(q); + + ecs_fini(world); +} + +void Plan_0_src_w_toggle_and_component(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + ECS_COMPONENT(world, Velocity); + + ecs_add_id(world, ecs_id(Position), EcsCanToggle); + + ecs_query_t *q = ecs_query(world, { + .expr = "Position(#0), Velocity" + }); + + test_assert(q != NULL); + + ecs_log_enable_colors(false); + + const char *expect = + HEAD " 0. [-1, 1] setfix " + LINE " 1. [ 0, 2] setids " + LINE " 2. [ 1, 3] andid $[this] (Velocity)" + LINE " 3. [ 2, 4] popself {1}" + LINE " 4. [ 3, 5] yield " + LINE ""; + char *plan = ecs_query_plan(q); + + test_str(expect, plan); + ecs_os_free(plan); + + ecs_query_fini(q); + + ecs_fini(world); +} + +void Plan_0_src_w_union_and_component(void) { + ecs_world_t *world = ecs_mini(); + + ECS_TAG(world, Movement); + ECS_COMPONENT(world, Velocity); + + ecs_add_id(world, ecs_id(Movement), EcsUnion); + + ecs_query_t *q = ecs_query(world, { + .expr = "Movement(#0, *), Velocity" + }); + + test_assert(q != NULL); + + ecs_log_enable_colors(false); + + const char *expect = + HEAD " 0. [-1, 1] setfix " + LINE " 1. [ 0, 2] setids " + LINE " 2. [ 1, 3] andid $[this] (Velocity)" + LINE " 3. [ 2, 4] popself {1}" + LINE " 4. [ 3, 5] yield " + LINE ""; + char *plan = ecs_query_plan(q); + + test_str(expect, plan); + ecs_os_free(plan); + + ecs_query_fini(q); + + ecs_fini(world); +} diff --git a/test/query/src/Sparse.c b/test/query/src/Sparse.c index 9633a812b..4eb4782b2 100644 --- a/test/query/src/Sparse.c +++ b/test/query/src/Sparse.c @@ -1007,3 +1007,61 @@ void Sparse_1_sparse_written_self_up(void) { ecs_fini(world); } + +void Sparse_sparse_0_src_only_term(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + + ecs_add_id(world, ecs_id(Position), EcsSparse); + + ecs_query_t *q = ecs_query(world, { + .expr = "Position(#0)", + .cache_kind = cache_kind + }); + + test_assert(q != NULL); + + ecs_iter_t it = ecs_query_iter(world, q); + test_bool(true, ecs_query_next(&it)); + test_int(0, it.count); + test_uint(ecs_id(Position), ecs_field_id(&it, 0)); + test_bool(false, ecs_field_is_set(&it, 0)); + test_bool(false, ecs_query_next(&it)); + + ecs_query_fini(q); + + ecs_fini(world); +} + +void Sparse_sparse_0_src(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + ECS_TAG(world, Foo); + + ecs_add_id(world, ecs_id(Position), EcsSparse); + + ecs_entity_t e = ecs_new_w(world, Foo); + + ecs_query_t *q = ecs_query(world, { + .expr = "Position(#0), Foo", + .cache_kind = cache_kind + }); + + test_assert(q != NULL); + + ecs_iter_t it = ecs_query_iter(world, q); + test_bool(true, ecs_query_next(&it)); + test_int(1, it.count); + test_uint(e, it.entities[0]); + test_uint(ecs_id(Position), ecs_field_id(&it, 0)); + test_uint(Foo, ecs_field_id(&it, 1)); + test_bool(false, ecs_field_is_set(&it, 0)); + test_bool(true, ecs_field_is_set(&it, 1)); + test_bool(false, ecs_query_next(&it)); + + ecs_query_fini(q); + + ecs_fini(world); +} diff --git a/test/query/src/main.c b/test/query/src/main.c index a843b2e0b..caf0ae6a9 100644 --- a/test/query/src/main.c +++ b/test/query/src/main.c @@ -732,6 +732,14 @@ void Plan_pair_first_wildcard(void); void Plan_pair_first_wildcard_cached(void); void Plan_pair_second_wildcard(void); void Plan_pair_second_wildcard_cached(void); +void Plan_0_src_tag(void); +void Plan_0_src_component(void); +void Plan_0_src_w_sparse(void); +void Plan_0_src_w_toggle(void); +void Plan_0_src_w_union(void); +void Plan_0_src_w_sparse_and_component(void); +void Plan_0_src_w_toggle_and_component(void); +void Plan_0_src_w_union_and_component(void); // Testsuite 'Variables' void Variables_setup(void); @@ -1826,6 +1834,8 @@ void Sparse_1_sparse_self_up(void); void Sparse_1_sparse_written_self(void); void Sparse_1_sparse_written_up(void); void Sparse_1_sparse_written_self_up(void); +void Sparse_sparse_0_src_only_term(void); +void Sparse_sparse_0_src(void); // Testsuite 'Union' void Union_setup(void); @@ -4883,6 +4893,38 @@ bake_test_case Plan_testcases[] = { { "pair_second_wildcard_cached", Plan_pair_second_wildcard_cached + }, + { + "0_src_tag", + Plan_0_src_tag + }, + { + "0_src_component", + Plan_0_src_component + }, + { + "0_src_w_sparse", + Plan_0_src_w_sparse + }, + { + "0_src_w_toggle", + Plan_0_src_w_toggle + }, + { + "0_src_w_union", + Plan_0_src_w_union + }, + { + "0_src_w_sparse_and_component", + Plan_0_src_w_sparse_and_component + }, + { + "0_src_w_toggle_and_component", + Plan_0_src_w_toggle_and_component + }, + { + "0_src_w_union_and_component", + Plan_0_src_w_union_and_component } }; @@ -9148,6 +9190,14 @@ bake_test_case Sparse_testcases[] = { { "1_sparse_written_self_up", Sparse_1_sparse_written_self_up + }, + { + "sparse_0_src_only_term", + Sparse_sparse_0_src_only_term + }, + { + "sparse_0_src", + Sparse_sparse_0_src } }; @@ -9985,7 +10035,7 @@ static bake_test_suite suites[] = { "Plan", NULL, NULL, - 64, + 72, Plan_testcases }, { @@ -10106,7 +10156,7 @@ static bake_test_suite suites[] = { "Sparse", Sparse_setup, NULL, - 19, + 21, Sparse_testcases, 1, Sparse_params