Skip to content

Commit

Permalink
Add tests for non-$this query variables in C++ API, and run bake
Browse files Browse the repository at this point in the history
  • Loading branch information
Gaspard-- authored and SanderMertens committed Sep 1, 2024
1 parent 86a8a51 commit 13fbc14
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 12 deletions.
26 changes: 14 additions & 12 deletions distr/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -25696,6 +25696,7 @@ struct field_ptrs {
void populate_self(const ecs_iter_t *iter, size_t index, T, Targs... comps) {
fields_[index].ptr = ecs_field_w_size(iter, sizeof(A),
static_cast<int8_t>(index));
fields_[index].is_ref = iter->sources[index] != 0;
populate_self(iter, index + 1, comps ...);
}

Expand All @@ -25717,7 +25718,19 @@ struct each_field { };
// Base class
struct each_column_base {
each_column_base(const _::field_ptr& field, size_t row)
: field_(field), row_(row) { }
: field_(field), row_(row) {

if (field.is_ref) {
// If this is a reference, set the row to 0 as a ref always is a
// single value, not an array. This prevents the application from
// having to do an if-check on whether the column is owned.
//
// This check only happens when the current table being iterated
// over caused the query to match a reference. The check is
// performed once per iterated table.
this->row_ = 0;
}
}

protected:
const _::field_ptr& field_;
Expand Down Expand Up @@ -25796,17 +25809,6 @@ struct each_ref_field : public each_field<T> {
each_ref_field(const flecs::iter_t *iter, _::field_ptr& field, size_t row)
: each_field<T>(iter, field, row) {

if (field.is_ref) {
// If this is a reference, set the row to 0 as a ref always is a
// single value, not an array. This prevents the application from
// having to do an if-check on whether the column is owned.
//
// This check only happens when the current table being iterated
// over caused the query to match a reference. The check is
// performed once per iterated table.
this->row_ = 0;
}

if (field.is_row) {
field.ptr = ecs_field_at_w_size(iter, sizeof(T), field.index,
static_cast<int8_t>(row));
Expand Down
70 changes: 70 additions & 0 deletions test/cpp/src/Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3053,3 +3053,73 @@ void Query_empty_tables_each_w_iter(void) {
test_int(p->y, 33);
}
}

void Query_pair_with_variable_src(void) {
flecs::world world;

struct EmptyRel {};
struct Rel { int x; };
struct ThisComp { int x; };
struct OtherComp { int x; };

world.component<Rel>();
world.component<ThisComp>();
world.component<OtherComp>();

auto other = flecs::entity(world)
.set(OtherComp{0});

flecs::entity(world)
.set(OtherComp{1});

for (int i = 0; i < 3; ++i)
flecs::entity(world)
.set(ThisComp{i})
.add<Rel>(other)
.add<EmptyRel>(other);

{
auto q = world.query_builder<Rel, ThisComp, OtherComp>()
.term_at(0).second("$other")
.term_at(2).src("$other")
.build();

size_t isPresentBitField = 0;
q.each([&isPresentBitField](Rel &rel, ThisComp &thisComp, OtherComp &otherComp) {
isPresentBitField |= (1 << thisComp.x);
rel.x = thisComp.x;
test_int(otherComp.x, 0);
});

test_int(isPresentBitField, 7);
}
{
auto q = world.query_builder<Rel const, ThisComp const, OtherComp const>()
.term_at(0).second("$other")
.term_at(2).src("$other")
.build();

size_t isPresentBitField = 0;
q.each([&isPresentBitField](Rel const &rel, ThisComp const &thisComp, OtherComp const &otherComp) {
isPresentBitField |= (1 << thisComp.x);
test_int(rel.x, thisComp.x);
test_int(otherComp.x, 0);
});

test_int(isPresentBitField, 7);
}
{
auto q = world.query_builder<EmptyRel const, ThisComp const, OtherComp const>()
.term_at(0).second("$other")
.term_at(2).src("$other")
.build();

size_t isPresentBitField = 0;
q.each([&isPresentBitField](EmptyRel const &, ThisComp const &thisComp, OtherComp const &otherComp) {
isPresentBitField |= (1 << thisComp.x);
test_int(otherComp.x, 0);
});

test_int(isPresentBitField, 7);
}
}

0 comments on commit 13fbc14

Please sign in to comment.