@@ -56087,44 +56087,52 @@ ecs_query_table_match_t* flecs_query_cache_add(
56087
56087
56088
56088
typedef struct {
56089
56089
ecs_table_t *table;
56090
- int32_t *dirty_state;
56091
56090
int32_t column;
56092
- } table_dirty_state_t ;
56091
+ } flecs_table_column_t ;
56093
56092
56094
56093
static
56095
- void flecs_query_get_dirty_state (
56094
+ void flecs_query_get_column_for_term (
56096
56095
ecs_query_t *query,
56097
56096
ecs_query_table_match_t *match,
56098
- int32_t term ,
56099
- table_dirty_state_t *out)
56097
+ int32_t t ,
56098
+ flecs_table_column_t *out)
56100
56099
{
56101
- ecs_world_t *world = query->filter.world;
56102
- ecs_entity_t src = match->sources[term];
56103
- ecs_table_t *table;
56100
+ const ecs_filter_t *filter = &query->filter;
56101
+ ecs_world_t *world = filter->world;
56102
+ ecs_term_t *term = &filter->terms[t];
56103
+ int32_t field = term->field_index;
56104
+ ecs_entity_t src = match->sources[t];
56105
+ ecs_table_t *table = NULL;
56104
56106
int32_t column = -1;
56105
56107
56106
- if (!src) {
56107
- table = match->table;
56108
- column = match->storage_columns[term];
56109
- } else {
56110
- const ecs_filter_t *filter = &query->filter;
56111
- table = ecs_get_table(world, src);
56112
- if (ecs_term_match_this(&filter->terms[term])) {
56113
- int32_t ref_index = -match->columns[term] - 1;
56114
- ecs_ref_t *ref = ecs_vec_get_t(&match->refs, ecs_ref_t, ref_index);
56115
- if (ref->id != 0) {
56116
- ecs_ref_update(world, ref);
56117
- column = ref->tr->column;
56118
- column = ecs_table_type_to_storage_index(table, column);
56108
+ if (term->oper != EcsNot) {
56109
+ if (!src) {
56110
+ if (term->src.flags != EcsIsEntity) {
56111
+ table = match->table;
56112
+ column = match->storage_columns[field];
56113
+ if (column == -2) {
56114
+ /* Shared field */
56115
+ column = -1;
56116
+ }
56119
56117
}
56120
56118
} else {
56121
- column = match->columns[term];
56119
+ table = ecs_get_table(world, src);
56120
+ if (ecs_term_match_this(term)) {
56121
+ int32_t ref_index = -match->columns[field] - 1;
56122
+ ecs_ref_t *ref = ecs_vec_get_t(&match->refs, ecs_ref_t, ref_index);
56123
+ if (ref->id != 0) {
56124
+ ecs_ref_update(world, ref);
56125
+ column = ref->tr->column;
56126
+ column = ecs_table_type_to_storage_index(table, column);
56127
+ }
56128
+ } else {
56129
+ column = -(match->columns[field] + 1);
56130
+ }
56122
56131
}
56123
56132
}
56124
56133
56125
56134
out->table = table;
56126
56135
out->column = column;
56127
- out->dirty_state = flecs_table_get_dirty_state(world, table);
56128
56136
}
56129
56137
56130
56138
/* Get match monitor. Monitors are used to keep track of whether components
@@ -56144,39 +56152,38 @@ bool flecs_query_get_match_monitor(
56144
56152
/* Mark terms that don't need to be monitored. This saves time when reading
56145
56153
* and/or updating the monitor. */
56146
56154
const ecs_filter_t *f = &query->filter;
56147
- int32_t i, t = -1, term_count = f->term_count;
56148
- table_dirty_state_t cur_dirty_state ;
56155
+ int32_t i, field = -1, term_count = f->term_count;
56156
+ flecs_table_column_t tc ;
56149
56157
56150
56158
for (i = 0; i < term_count; i ++) {
56151
- if (t == f->terms[i].field_index) {
56152
- if (monitor[t + 1] != -1) {
56159
+ if (field == f->terms[i].field_index) {
56160
+ if (monitor[field + 1] != -1) {
56153
56161
continue;
56154
56162
}
56155
56163
}
56156
56164
56157
- t = f->terms[i].field_index;
56158
- monitor[t + 1] = -1;
56165
+ field = f->terms[i].field_index;
56166
+ monitor[field + 1] = -1;
56159
56167
56160
56168
if (f->terms[i].inout != EcsIn &&
56161
56169
f->terms[i].inout != EcsInOut &&
56162
56170
f->terms[i].inout != EcsInOutDefault) {
56163
56171
continue; /* If term isn't read, don't monitor */
56164
56172
}
56165
56173
56166
- int32_t column = match->columns[t ];
56174
+ int32_t column = match->columns[field ];
56167
56175
if (column == 0) {
56168
56176
continue; /* Don't track terms that aren't matched */
56169
56177
}
56170
56178
56171
- flecs_query_get_dirty_state (query, match, t , &cur_dirty_state );
56172
- if (cur_dirty_state .column == -1) {
56179
+ flecs_query_get_column_for_term (query, match, i , &tc );
56180
+ if (tc .column == -1) {
56173
56181
continue; /* Don't track terms that aren't stored */
56174
56182
}
56175
56183
56176
- monitor[t + 1] = 0;
56184
+ monitor[field + 1] = 0;
56177
56185
}
56178
56186
56179
-
56180
56187
/* If matched table needs entity filter, make sure to test fields that could
56181
56188
* be matched by flattened parents. */
56182
56189
ecs_entity_filter_t *ef = match->entity_filter;
@@ -56219,33 +56226,33 @@ void flecs_query_sync_match_monitor(
56219
56226
monitor[0] = dirty_state[0]; /* Did table gain/lose entities */
56220
56227
}
56221
56228
56222
- table_dirty_state_t cur;
56223
- int32_t i, term_count = query->filter.term_count;
56224
- for (i = 0; i < term_count; i ++) {
56225
- int32_t t = query->filter.terms[i].field_index;
56226
- if (monitor[t + 1] == -1) {
56227
- continue;
56228
- }
56229
+ ecs_filter_t *filter = &query->filter;
56230
+ {
56231
+ flecs_table_column_t tc;
56232
+ int32_t t, term_count = filter->term_count;
56233
+ for (t = 0; t < term_count; t ++) {
56234
+ int32_t field = filter->terms[t].field_index;
56235
+ if (monitor[field + 1] == -1) {
56236
+ continue;
56237
+ }
56229
56238
56230
- flecs_query_get_dirty_state(query, match, t, &cur);
56231
- if (cur.column < 0) {
56232
- // continue;
56233
- cur.column = -(cur.column + 1);
56234
- }
56239
+ flecs_query_get_column_for_term(query, match, t, &tc);
56235
56240
56236
- monitor[t + 1] = cur.dirty_state[cur.column + 1];
56241
+ monitor[field + 1] = flecs_table_get_dirty_state(
56242
+ filter->world, tc.table)[tc.column + 1];
56243
+ }
56237
56244
}
56238
56245
56239
56246
ecs_entity_filter_t *ef = match->entity_filter;
56240
56247
if (ef && ef->flat_tree_column != -1) {
56241
56248
flecs_flat_table_term_t *fields = ecs_vec_first(&ef->ft_terms);
56242
- int32_t field_count = ecs_vec_count(&ef->ft_terms);
56243
- for (i = 0; i < field_count; i ++) {
56244
- flecs_flat_table_term_t *field = &fields[i ];
56249
+ int32_t f, field_count = ecs_vec_count(&ef->ft_terms);
56250
+ for (f = 0; f < field_count; f ++) {
56251
+ flecs_flat_table_term_t *field = &fields[f ];
56245
56252
flecs_flat_monitor_t *tgt_mon = ecs_vec_first(&field->monitor);
56246
- int32_t t , tgt_count = ecs_vec_count(&field->monitor);
56247
- for (t = 0; t < tgt_count; t ++) {
56248
- tgt_mon[t ].monitor = tgt_mon[t ].table_state;
56253
+ int32_t tgt , tgt_count = ecs_vec_count(&field->monitor);
56254
+ for (tgt = 0; tgt < tgt_count; tgt ++) {
56255
+ tgt_mon[tgt ].monitor = tgt_mon[tgt ].table_state;
56249
56256
}
56250
56257
}
56251
56258
}
@@ -56284,11 +56291,12 @@ bool flecs_query_check_match_monitor_term(
56284
56291
return false;
56285
56292
}
56286
56293
56287
- table_dirty_state_t cur;
56288
- flecs_query_get_dirty_state (query, match, term - 1, &cur);
56294
+ flecs_table_column_t cur;
56295
+ flecs_query_get_column_for_term (query, match, term - 1, &cur);
56289
56296
ecs_assert(cur.column != -1, ECS_INTERNAL_ERROR, NULL);
56290
56297
56291
- return monitor[term] != cur.dirty_state[cur.column + 1];
56298
+ return monitor[term] != flecs_table_get_dirty_state(
56299
+ query->filter.world, cur.table)[cur.column + 1];
56292
56300
}
56293
56301
56294
56302
/* Check if any term for match has changed */
@@ -57107,7 +57115,16 @@ int flecs_query_process_signature(
57107
57115
"invalid usage of Filter for query");
57108
57116
57109
57117
if (inout != EcsIn && inout != EcsInOutNone) {
57110
- query->flags |= EcsQueryHasOutColumns;
57118
+ /* Non-this terms default to EcsIn */
57119
+ if (ecs_term_match_this(term) || inout != EcsInOutDefault) {
57120
+ query->flags |= EcsQueryHasOutTerms;
57121
+ }
57122
+
57123
+ bool match_non_this = !ecs_term_match_this(term) ||
57124
+ (term->src.flags & EcsUp);
57125
+ if (match_non_this && inout != EcsInOutDefault) {
57126
+ query->flags |= EcsQueryHasNonThisOutTerms;
57127
+ }
57111
57128
}
57112
57129
57113
57130
if (src->flags & EcsCascade) {
@@ -57994,31 +58011,41 @@ void flecs_query_mark_columns_dirty(
57994
58011
ecs_query_table_match_t *qm)
57995
58012
{
57996
58013
ecs_table_t *table = qm->table;
57997
- if (!table) {
57998
- return;
57999
- }
58000
-
58001
- int32_t *dirty_state = table->dirty_state;
58002
- if (dirty_state) {
58003
- int32_t *storage_columns = qm->storage_columns;
58004
- ecs_filter_t *filter = &query->filter;
58014
+ ecs_filter_t *filter = &query->filter;
58015
+ if ((table && table->dirty_state) || (query->flags & EcsQueryHasNonThisOutTerms)) {
58005
58016
ecs_term_t *terms = filter->terms;
58006
58017
int32_t i, count = filter->term_count;
58007
58018
58008
58019
for (i = 0; i < count; i ++) {
58009
58020
ecs_term_t *term = &terms[i];
58010
- if (term->inout == EcsIn || term->inout == EcsInOutNone) {
58021
+ ecs_inout_kind_t inout = term->inout;
58022
+ if (inout == EcsIn || inout == EcsInOutNone) {
58011
58023
/* Don't mark readonly terms dirty */
58012
58024
continue;
58013
58025
}
58014
58026
58015
- int32_t field = term->field_index;
58016
- int32_t column = storage_columns[field];
58017
- if (column < 0) {
58027
+ flecs_table_column_t tc;
58028
+ flecs_query_get_column_for_term(query, qm, i, &tc);
58029
+
58030
+ if (tc.column == -1) {
58031
+ continue;
58032
+ }
58033
+
58034
+ ecs_assert(tc.table != NULL, ECS_INTERNAL_ERROR, NULL);
58035
+ int32_t *dirty_state = tc.table->dirty_state;
58036
+ if (!dirty_state) {
58018
58037
continue;
58019
58038
}
58020
58039
58021
- dirty_state[column + 1] ++;
58040
+ if (table != tc.table) {
58041
+ if (inout == EcsInOutDefault) {
58042
+ continue;
58043
+ }
58044
+ }
58045
+
58046
+ ecs_assert(tc.column >= 0, ECS_INTERNAL_ERROR, NULL);
58047
+
58048
+ dirty_state[tc.column + 1] ++;
58022
58049
}
58023
58050
}
58024
58051
}
@@ -58040,7 +58067,7 @@ bool ecs_query_next_table(
58040
58067
if (query->flags & EcsQueryHasMonitor) {
58041
58068
flecs_query_sync_match_monitor(query, prev);
58042
58069
}
58043
- if (query->flags & EcsQueryHasOutColumns ) {
58070
+ if (query->flags & EcsQueryHasOutTerms ) {
58044
58071
if (it->count) {
58045
58072
flecs_query_mark_columns_dirty(query, prev);
58046
58073
}
@@ -58231,7 +58258,7 @@ bool ecs_query_next_instanced(
58231
58258
if (flags & EcsQueryHasMonitor) {
58232
58259
flecs_query_sync_match_monitor(query, prev);
58233
58260
}
58234
- if (flags & EcsQueryHasOutColumns ) {
58261
+ if (flags & EcsQueryHasOutTerms ) {
58235
58262
flecs_query_mark_columns_dirty(query, prev);
58236
58263
}
58237
58264
}
0 commit comments