@@ -56087,44 +56087,52 @@ ecs_query_table_match_t* flecs_query_cache_add(
5608756087
5608856088typedef struct {
5608956089 ecs_table_t *table;
56090- int32_t *dirty_state;
5609156090 int32_t column;
56092- } table_dirty_state_t ;
56091+ } flecs_table_column_t ;
5609356092
5609456093static
56095- void flecs_query_get_dirty_state (
56094+ void flecs_query_get_column_for_term (
5609656095 ecs_query_t *query,
5609756096 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)
5610056099{
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[field];
56105+ ecs_table_t *table = NULL;
5610456106 int32_t column = -1;
5610556107
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+ }
5611956117 }
5612056118 } 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+ }
5612256131 }
5612356132 }
5612456133
5612556134 out->table = table;
5612656135 out->column = column;
56127- out->dirty_state = flecs_table_get_dirty_state(world, table);
5612856136}
5612956137
5613056138/* Get match monitor. Monitors are used to keep track of whether components
@@ -56144,39 +56152,38 @@ bool flecs_query_get_match_monitor(
5614456152 /* Mark terms that don't need to be monitored. This saves time when reading
5614556153 * and/or updating the monitor. */
5614656154 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 ;
5614956157
5615056158 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) {
5615356161 continue;
5615456162 }
5615556163 }
5615656164
56157- t = f->terms[i].field_index;
56158- monitor[t + 1] = -1;
56165+ field = f->terms[i].field_index;
56166+ monitor[field + 1] = -1;
5615956167
5616056168 if (f->terms[i].inout != EcsIn &&
5616156169 f->terms[i].inout != EcsInOut &&
5616256170 f->terms[i].inout != EcsInOutDefault) {
5616356171 continue; /* If term isn't read, don't monitor */
5616456172 }
5616556173
56166- int32_t column = match->columns[t ];
56174+ int32_t column = match->columns[field ];
5616756175 if (column == 0) {
5616856176 continue; /* Don't track terms that aren't matched */
5616956177 }
5617056178
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) {
5617356181 continue; /* Don't track terms that aren't stored */
5617456182 }
5617556183
56176- monitor[t + 1] = 0;
56184+ monitor[field + 1] = 0;
5617756185 }
5617856186
56179-
5618056187 /* If matched table needs entity filter, make sure to test fields that could
5618156188 * be matched by flattened parents. */
5618256189 ecs_entity_filter_t *ef = match->entity_filter;
@@ -56219,33 +56226,33 @@ void flecs_query_sync_match_monitor(
5621956226 monitor[0] = dirty_state[0]; /* Did table gain/lose entities */
5622056227 }
5622156228
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+ }
5622956238
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);
5623556240
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+ }
5623756244 }
5623856245
5623956246 ecs_entity_filter_t *ef = match->entity_filter;
5624056247 if (ef && ef->flat_tree_column != -1) {
5624156248 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 ];
5624556252 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;
5624956256 }
5625056257 }
5625156258 }
@@ -56284,11 +56291,12 @@ bool flecs_query_check_match_monitor_term(
5628456291 return false;
5628556292 }
5628656293
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);
5628956296 ecs_assert(cur.column != -1, ECS_INTERNAL_ERROR, NULL);
5629056297
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];
5629256300}
5629356301
5629456302/* Check if any term for match has changed */
@@ -57107,7 +57115,16 @@ int flecs_query_process_signature(
5710757115 "invalid usage of Filter for query");
5710857116
5710957117 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+ }
5711157128 }
5711257129
5711357130 if (src->flags & EcsCascade) {
@@ -57994,31 +58011,41 @@ void flecs_query_mark_columns_dirty(
5799458011 ecs_query_table_match_t *qm)
5799558012{
5799658013 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)) {
5800558016 ecs_term_t *terms = filter->terms;
5800658017 int32_t i, count = filter->term_count;
5800758018
5800858019 for (i = 0; i < count; i ++) {
5800958020 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) {
5801158023 /* Don't mark readonly terms dirty */
5801258024 continue;
5801358025 }
5801458026
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) {
5801858037 continue;
5801958038 }
5802058039
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] ++;
5802258049 }
5802358050 }
5802458051}
@@ -58040,7 +58067,7 @@ bool ecs_query_next_table(
5804058067 if (query->flags & EcsQueryHasMonitor) {
5804158068 flecs_query_sync_match_monitor(query, prev);
5804258069 }
58043- if (query->flags & EcsQueryHasOutColumns ) {
58070+ if (query->flags & EcsQueryHasOutTerms ) {
5804458071 if (it->count) {
5804558072 flecs_query_mark_columns_dirty(query, prev);
5804658073 }
@@ -58231,7 +58258,7 @@ bool ecs_query_next_instanced(
5823158258 if (flags & EcsQueryHasMonitor) {
5823258259 flecs_query_sync_match_monitor(query, prev);
5823358260 }
58234- if (flags & EcsQueryHasOutColumns ) {
58261+ if (flags & EcsQueryHasOutTerms ) {
5823558262 flecs_query_mark_columns_dirty(query, prev);
5823658263 }
5823758264 }
0 commit comments