Skip to content

Commit

Permalink
#1169 Fix issue with overcounting the number of nodata terms in a que…
Browse files Browse the repository at this point in the history
…ry with OR terms
  • Loading branch information
SanderMertens committed Apr 23, 2024
1 parent bb65f68 commit 301243a
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 20 deletions.
22 changes: 15 additions & 7 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -11198,17 +11198,20 @@ ecs_term_t* flecs_filter_or_other_type(
if (f->terms[t].oper != EcsOr) {
break;
}

first = &f->terms[t];
}

if (first) {
ecs_world_t *world = f->world;
const ecs_type_info_t *first_type;

if (first->idr) {
first_type = first->idr->type_info;
} else {
first_type = ecs_get_type_info(world, first->id);
}

const ecs_type_info_t *term_type;
if (term->idr) {
term_type = term->idr->type_info;
Expand All @@ -11219,6 +11222,7 @@ ecs_term_t* flecs_filter_or_other_type(
if (first_type == term_type) {
return NULL;
}

return first;
} else {
return NULL;
Expand Down Expand Up @@ -11328,7 +11332,9 @@ int ecs_filter_finalize(
ecs_term_t *first = flecs_filter_or_other_type(f, i);
if (first) {
if (first == &term[-1]) {
filter_terms ++;
if (!(term[-1].flags & EcsTermNoData)) {
filter_terms ++;
}
}
filter_term = true;
}
Expand Down Expand Up @@ -13297,9 +13303,11 @@ bool ecs_filter_next_instanced(

/* Match the remainder of the terms */
int32_t skip_term = pivot_term;
if (ecs_id_is_wildcard(filter->terms[pivot_term].id)) {
skip_term = -1;
iter->matches_left = 1;
if (pivot_term != -1) {
if (ecs_id_is_wildcard(filter->terms[pivot_term].id)) {
skip_term = -1;
iter->matches_left = 1;
}
}

match = flecs_filter_match_table(world, filter, table,
Expand Down Expand Up @@ -13351,18 +13359,18 @@ bool ecs_filter_next_instanced(
}

int32_t t, term_count = filter->term_count;
ecs_term_t *term = NULL;
ecs_term_t *cur_term = NULL;
for (t = 0; t < term_count; t ++) {
if (filter->terms[t].field_index == i) {
term = &filter->terms[t];
cur_term = &filter->terms[t];
break;
}
}

ecs_assert(term != NULL, ECS_INTERNAL_ERROR, NULL);

it->columns[i] = column + 1;
flecs_term_match_table(world, term, table,
flecs_term_match_table(world, cur_term, table,
&it->ids[i], &it->columns[i], &it->sources[i],
&it->match_indices[i], false, it->flags);

Expand Down
22 changes: 15 additions & 7 deletions src/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1148,17 +1148,20 @@ ecs_term_t* flecs_filter_or_other_type(
if (f->terms[t].oper != EcsOr) {
break;
}

first = &f->terms[t];
}

if (first) {
ecs_world_t *world = f->world;
const ecs_type_info_t *first_type;

if (first->idr) {
first_type = first->idr->type_info;
} else {
first_type = ecs_get_type_info(world, first->id);
}

const ecs_type_info_t *term_type;
if (term->idr) {
term_type = term->idr->type_info;
Expand All @@ -1169,6 +1172,7 @@ ecs_term_t* flecs_filter_or_other_type(
if (first_type == term_type) {
return NULL;
}

return first;
} else {
return NULL;
Expand Down Expand Up @@ -1278,7 +1282,9 @@ int ecs_filter_finalize(
ecs_term_t *first = flecs_filter_or_other_type(f, i);
if (first) {
if (first == &term[-1]) {
filter_terms ++;
if (!(term[-1].flags & EcsTermNoData)) {
filter_terms ++;
}
}
filter_term = true;
}
Expand Down Expand Up @@ -3247,9 +3253,11 @@ bool ecs_filter_next_instanced(

/* Match the remainder of the terms */
int32_t skip_term = pivot_term;
if (ecs_id_is_wildcard(filter->terms[pivot_term].id)) {
skip_term = -1;
iter->matches_left = 1;
if (pivot_term != -1) {
if (ecs_id_is_wildcard(filter->terms[pivot_term].id)) {
skip_term = -1;
iter->matches_left = 1;
}
}

match = flecs_filter_match_table(world, filter, table,
Expand Down Expand Up @@ -3301,18 +3309,18 @@ bool ecs_filter_next_instanced(
}

int32_t t, term_count = filter->term_count;
ecs_term_t *term = NULL;
ecs_term_t *cur_term = NULL;
for (t = 0; t < term_count; t ++) {
if (filter->terms[t].field_index == i) {
term = &filter->terms[t];
cur_term = &filter->terms[t];
break;
}
}

ecs_assert(term != NULL, ECS_INTERNAL_ERROR, NULL);

it->columns[i] = column + 1;
flecs_term_match_table(world, term, table,
flecs_term_match_table(world, cur_term, table,
&it->ids[i], &it->columns[i], &it->sources[i],
&it->match_indices[i], false, it->flags);

Expand Down
4 changes: 3 additions & 1 deletion test/api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,9 @@
"filter_iter_3_or",
"filter_iter_2_or_other_type",
"filter_iter_2_or_same_type",
"filter_or_w_wildcard",
"filter_iter_or_w_wildcard",
"filer_iter_or_w_component_and_tag",
"filer_iter_or_w_tag_and_component",
"filter_iter_1_component",
"filter_iter_2_components",
"filter_iter_pair_id",
Expand Down
64 changes: 63 additions & 1 deletion test/api/src/Filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -4643,7 +4643,7 @@ void Filter_filter_iter_2_or_same_type(void) {
ecs_fini(world);
}

void Filter_filter_or_w_wildcard(void) {
void Filter_filter_iter_or_w_wildcard(void) {
ecs_world_t *world = ecs_mini();

ECS_TAG(world, Rel);
Expand Down Expand Up @@ -4687,6 +4687,68 @@ void Filter_filter_or_w_wildcard(void) {
ecs_fini(world);
}

void Filter_filer_iter_or_w_component_and_tag(void) {
ecs_world_t *world = ecs_mini();

ECS_COMPONENT(world, Position);
ECS_TAG(world, TagA);

ecs_filter_t *q = ecs_filter(world, {
.terms = {
{ ecs_id(Position), .oper = EcsOr },
{ TagA }
}
});

test_assert(q != NULL);

ecs_entity_t e = ecs_new_id(world);
ecs_set(world, e, Position, {10, 20});
ecs_add(world, e, TagA);

ecs_iter_t it = ecs_filter_iter(world, q);
test_bool(true, ecs_filter_next(&it));
test_int(1, it.count);
test_uint(e, it.entities[0]);
test_uint(ecs_id(Position), ecs_field_id(&it, 1));
test_bool(false, ecs_filter_next(&it));

ecs_filter_fini(q);

ecs_fini(world);
}

void Filter_filer_iter_or_w_tag_and_component(void) {
ecs_world_t *world = ecs_mini();

ECS_COMPONENT(world, Position);
ECS_TAG(world, TagA);

ecs_filter_t *q = ecs_filter(world, {
.terms = {
{ TagA, .oper = EcsOr },
{ ecs_id(Position) }
}
});

test_assert(q != NULL);

ecs_entity_t e = ecs_new_id(world);
ecs_set(world, e, Position, {10, 20});
ecs_add(world, e, TagA);

ecs_iter_t it = ecs_filter_iter(world, q);
test_bool(true, ecs_filter_next(&it));
test_int(1, it.count);
test_uint(e, it.entities[0]);
test_uint(TagA, ecs_field_id(&it, 1));
test_bool(false, ecs_filter_next(&it));

ecs_filter_fini(q);

ecs_fini(world);
}

void Filter_filter_iter_2_or(void) {
ecs_world_t *world = ecs_mini();

Expand Down
18 changes: 14 additions & 4 deletions test/api/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,9 @@ void Filter_filter_iter_2_or(void);
void Filter_filter_iter_3_or(void);
void Filter_filter_iter_2_or_other_type(void);
void Filter_filter_iter_2_or_same_type(void);
void Filter_filter_or_w_wildcard(void);
void Filter_filter_iter_or_w_wildcard(void);
void Filter_filer_iter_or_w_component_and_tag(void);
void Filter_filer_iter_or_w_tag_and_component(void);
void Filter_filter_iter_1_component(void);
void Filter_filter_iter_2_components(void);
void Filter_filter_iter_pair_id(void);
Expand Down Expand Up @@ -7568,8 +7570,16 @@ bake_test_case Filter_testcases[] = {
Filter_filter_iter_2_or_same_type
},
{
"filter_or_w_wildcard",
Filter_filter_or_w_wildcard
"filter_iter_or_w_wildcard",
Filter_filter_iter_or_w_wildcard
},
{
"filer_iter_or_w_component_and_tag",
Filter_filer_iter_or_w_component_and_tag
},
{
"filer_iter_or_w_tag_and_component",
Filter_filer_iter_or_w_tag_and_component
},
{
"filter_iter_1_component",
Expand Down Expand Up @@ -13653,7 +13663,7 @@ static bake_test_suite suites[] = {
"Filter",
NULL,
NULL,
305,
307,
Filter_testcases
},
{
Expand Down
1 change: 1 addition & 0 deletions test/meta/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5738,6 +5738,7 @@ bake_test_case Misc_testcases[] = {
}
};


static bake_test_suite suites[] = {
{
"PrimitiveTypes",
Expand Down

0 comments on commit 301243a

Please sign in to comment.