Skip to content

Commit

Permalink
Fix issue where ecs_iter_t::ref_fields wasn't correctly set
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Sep 2, 2024
1 parent 7922011 commit fc4e296
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 105 deletions.
8 changes: 7 additions & 1 deletion distr/flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -34254,6 +34254,12 @@ int flecs_query_finalize_terms(
ECS_TERMSET_SET(q->fixed_fields, 1u << term->field_index);
}

if ((term->src.id & EcsIsVariable) &&
(ECS_TERM_REF_ID(&term->src) != EcsThis))
{
ECS_TERMSET_SET(q->var_fields, 1u << term->field_index);
}

ecs_id_record_t *idr = flecs_id_record_get(world, term->id);
if (idr) {
if (ecs_os_has_threading()) {
Expand Down Expand Up @@ -69940,7 +69946,7 @@ ecs_iter_t flecs_query_iter(
it.field_count = q->field_count;
it.sizes = q->sizes;
it.set_fields = q->set_fields;
it.ref_fields = q->fixed_fields | q->row_fields;
it.ref_fields = q->fixed_fields | q->row_fields | q->var_fields;
it.row_fields = q->row_fields;
it.up_fields = 0;
flecs_query_apply_iter_flags(&it, q);
Expand Down
24 changes: 12 additions & 12 deletions distr/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3425,6 +3425,7 @@ struct ecs_query_t {

/* Bitmasks for quick field information lookups */
ecs_termset_t fixed_fields; /**< Fields with a fixed source */
ecs_termset_t var_fields; /**< Fields with non-$this variable source */
ecs_termset_t static_id_fields; /**< Fields with a static (component) id */
ecs_termset_t data_fields; /**< Fields that have data */
ecs_termset_t write_fields; /**< Fields that write data */
Expand Down Expand Up @@ -25719,17 +25720,6 @@ struct each_field { };
struct each_column_base {
each_column_base(const _::field_ptr& field, size_t 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:
Expand Down Expand Up @@ -25809,14 +25799,24 @@ 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));
}
}
};


// Type that handles passing components to each callbacks
template <typename Func, typename ... Components>
struct each_delegate : public delegate {
Expand Down
1 change: 1 addition & 0 deletions include/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ struct ecs_query_t {

/* Bitmasks for quick field information lookups */
ecs_termset_t fixed_fields; /**< Fields with a fixed source */
ecs_termset_t var_fields; /**< Fields with non-$this variable source */
ecs_termset_t static_id_fields; /**< Fields with a static (component) id */
ecs_termset_t data_fields; /**< Fields that have data */
ecs_termset_t write_fields; /**< Fields that write data */
Expand Down
23 changes: 11 additions & 12 deletions include/flecs/addons/cpp/delegate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,6 @@ struct each_field { };
struct each_column_base {
each_column_base(const _::field_ptr& field, size_t 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:
Expand Down Expand Up @@ -212,14 +201,24 @@ 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));
}
}
};


// Type that handles passing components to each callbacks
template <typename Func, typename ... Components>
struct each_delegate : public delegate {
Expand Down
2 changes: 1 addition & 1 deletion src/query/engine/eval_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ ecs_iter_t flecs_query_iter(
it.field_count = q->field_count;
it.sizes = q->sizes;
it.set_fields = q->set_fields;
it.ref_fields = q->fixed_fields | q->row_fields;
it.ref_fields = q->fixed_fields | q->row_fields | q->var_fields;
it.row_fields = q->row_fields;
it.up_fields = 0;
flecs_query_apply_iter_flags(&it, q);
Expand Down
6 changes: 6 additions & 0 deletions src/query/validator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,12 @@ int flecs_query_finalize_terms(
ECS_TERMSET_SET(q->fixed_fields, 1u << term->field_index);
}

if ((term->src.id & EcsIsVariable) &&
(ECS_TERM_REF_ID(&term->src) != EcsThis))
{
ECS_TERMSET_SET(q->var_fields, 1u << term->field_index);
}

ecs_id_record_t *idr = flecs_id_record_get(world, term->id);
if (idr) {
if (ecs_os_has_threading()) {
Expand Down
Loading

0 comments on commit fc4e296

Please sign in to comment.