@@ -1483,9 +1483,9 @@ typedef enum {
14831483} ecs_trav_direction_t;
14841484
14851485typedef struct {
1486- ecs_map_t src; /* map<table_id, trav_up_t> (up direction) */
1487- ecs_trav_down_t down; /* reused buffer (down direction) */
1488- ecs_trav_up_t up; /* reused buffer for top-level up result */
1486+ ecs_map_t src;
1487+ ecs_trav_down_t down;
1488+ ecs_trav_up_t up;
14891489 ecs_id_t with;
14901490 ecs_trav_direction_t dir;
14911491} ecs_trav_up_cache_t;
@@ -2658,10 +2658,6 @@ ecs_iter_t flecs_query_iter(
26582658 const ecs_world_t *world,
26592659 const ecs_query_t *q);
26602660
2661- /* Fast path for testing a trivial query against a table range, used by
2662- * observers. Avoids creating a full query iterator. Returns 1 on match, 0 on no
2663- * match, and -1 if the query is not eligible for this path (caller must fall
2664- * back to ecs_query_has_range). On a match, populates 'it'. */
26652661int flecs_query_trivial_has_range(
26662662 const ecs_query_t *q,
26672663 ecs_iter_t *it,
@@ -13395,11 +13391,12 @@ void flecs_iter_init(
1339513391 char *buf = flecs_stack_alloc(stack, wide + cols,
1339613392 ECS_ALIGNOF(ecs_id_t));
1339713393
13398- it->ids = (ecs_id_t*)buf;
13399- it->sources = (ecs_entity_t*)(buf + (ecs_size_t)sizeof(ecs_id_t) * fc);
13400- it->trs = (const ecs_table_record_t**)(buf +
13394+ it->ids = (ecs_id_t*)(void*)buf;
13395+ it->sources = (ecs_entity_t*)(void*)(buf +
13396+ (ecs_size_t)sizeof(ecs_id_t) * fc);
13397+ it->trs = (const ecs_table_record_t**)(void*)(buf +
1340113398 (ecs_size_t)(sizeof(ecs_id_t) + sizeof(ecs_entity_t)) * fc);
13402- int16_t *columns = (int16_t*)(buf + wide);
13399+ int16_t *columns = (int16_t*)(void*)( buf + wide);
1340313400
1340413401 ecs_os_memset(buf, 0, wide);
1340513402 ecs_os_memset(columns, 0xFF, cols);
@@ -17122,6 +17119,7 @@ void flecs_multi_observer_invoke(
1712217119 }
1712317120
1712417121 ecs_table_t *lock_table = table;
17122+ (void)lock_table;
1712517123 table = table ? table : &world->store.root;
1712617124 prev_table = prev_table ? prev_table : &world->store.root;
1712717125
@@ -17147,9 +17145,6 @@ void flecs_multi_observer_invoke(
1714717145 ecs_assert(match, ECS_INTERNAL_ERROR, NULL);
1714817146 }
1714917147 } else {
17150- /* Fast path: for trivial observer queries we can test the table
17151- * directly without creating a full query iterator. Monitors are handled
17152- * by the regular path as they require an additional check. */
1715317148 int trivial = -1;
1715417149 if (!(impl->flags & EcsObserverIsMonitor)) {
1715517150 trivial = flecs_query_trivial_has_range(o->query, &user_it,
@@ -17249,7 +17244,6 @@ void flecs_multi_observer_invoke_no_query(
1724917244 flecs_poly_assert(o, ecs_observer_t);
1725017245
1725117246 ecs_world_t *world = it->real_world;
17252- ecs_table_t *table = it->table;
1725317247 ecs_iter_t user_it = *it;
1725417248
1725517249 user_it.ctx = o->ctx;
@@ -17262,7 +17256,7 @@ void flecs_multi_observer_invoke_no_query(
1726217256
1726317257 ecs_entity_t old_system = flecs_stage_set_system(
1726417258 world->stages[0], o->entity);
17265- ECS_TABLE_LOCK(it->world, table);
17259+ ECS_TABLE_LOCK(it->world, it-> table);
1726617260
1726717261 if (o->run) {
1726817262 user_it.next = flecs_default_next_callback;
@@ -17271,7 +17265,7 @@ void flecs_multi_observer_invoke_no_query(
1727117265 user_it.callback(&user_it);
1727217266 }
1727317267
17274- ECS_TABLE_UNLOCK(it->world, table);
17268+ ECS_TABLE_UNLOCK(it->world, it-> table);
1727517269 flecs_stage_set_system(world->stages[0], old_system);
1727617270}
1727717271
@@ -86019,10 +86013,6 @@ int flecs_query_trivial_has_range(
8601986013 ecs_flags32_t flags = q->flags;
8602086014 ecs_flags32_t trivial_flags = EcsQueryIsTrivial|EcsQueryMatchOnlySelf;
8602186015
86022- /* Only handle the case where the constrained query would take the trivial
86023- * test code path. This mirrors the conditions in
86024- * flecs_query_apply_iter_flags. For anything else, signal the caller to use
86025- * the regular (full iterator) path. */
8602686016 if (impl->cache ||
8602786017 ((flags & trivial_flags) != trivial_flags) ||
8602886018 (flags & EcsQueryMatchWildcards) ||
@@ -86031,8 +86021,6 @@ int flecs_query_trivial_has_range(
8603186021 return -1;
8603286022 }
8603386023
86034- /* Eval count is incremented unconditionally, matching ecs_query_iter and
86035- * the bloom filter reject path in ecs_query_has_range. */
8603686024 ECS_CONST_CAST(ecs_query_t*, q)->eval_count ++;
8603786025
8603886026 if (table && ((offset + count) > ecs_table_count(table))) {
@@ -86043,9 +86031,6 @@ int flecs_query_trivial_has_range(
8604386031 return 0;
8604486032 }
8604586033
86046- /* Build a minimal iterator for the trivial test. Unlike flecs_query_iter
86047- * this skips the var/written/op_ctx allocations and the query VM, which the
86048- * trivial test never uses. */
8604986034 ecs_iter_t lit = {0};
8605086035 lit.world = ECS_CONST_CAST(ecs_world_t*, world);
8605186036 lit.real_world = q->real_world;
@@ -86058,8 +86043,6 @@ int flecs_query_trivial_has_range(
8605886043 lit.offset = offset;
8605986044 lit.count = count;
8606086045
86061- /* flecs_iter_init asserts that EcsIterIsValid is not set on entry, so only
86062- * mark the iterator valid after initialization. */
8606386046 flecs_iter_init(lit.world, &lit, true);
8606486047 lit.flags |= EcsIterIsValid;
8606586048
@@ -89912,15 +89895,14 @@ void flecs_trav_entity_down_iter_children(
8991289895 bool leaf = false;
8991389896
8991489897 /* Check if table has the component */
89915- if (flecs_component_get_table(cr_with, r->table) != NULL) {
89916- if (self) {
89917- /* If matching self and the table has the component, entity
89918- * shouldn't be matched through traversal and will instead
89919- * be matched directly. */
89920- continue;
89921- }
89898+ if (self || r->table->_->traversable_count) {
89899+ if (flecs_component_get_table(cr_with, r->table) != NULL) {
89900+ if (self) {
89901+ continue;
89902+ }
8992289903
89923- leaf = true;
89904+ leaf = true;
89905+ }
8992489906 }
8992589907
8992689908 /* Add element to the cache for a single child */
@@ -89962,11 +89944,13 @@ void flecs_trav_entity_down_iter_tables(
8996289944 ecs_table_t *table = tr->hdr.table;
8996389945 bool leaf = false;
8996489946
89965- if (flecs_component_get_table(cr_with, table) != NULL) {
89966- if (self) {
89967- continue;
89947+ if (self || table->_->traversable_count) {
89948+ if (flecs_component_get_table(cr_with, table) != NULL) {
89949+ if (self) {
89950+ continue;
89951+ }
89952+ leaf = true;
8996889953 }
89969- leaf = true;
8997089954 }
8997189955
8997289956 /* If record is not the first instance of (trav, *), don't add it
0 commit comments