Skip to content

Commit 0ec9bd5

Browse files
committed
#124 implement new query change detection
1 parent be21305 commit 0ec9bd5

File tree

12 files changed

+1252
-296
lines changed

12 files changed

+1252
-296
lines changed

flecs.c

+370-107
Large diffs are not rendered by default.

flecs.h

+40-6
Original file line numberDiff line numberDiff line change
@@ -2831,7 +2831,7 @@ typedef struct ecs_filter_iter_t {
28312831
/** Query-iterator specific data */
28322832
typedef struct ecs_query_iter_t {
28332833
ecs_query_t *query;
2834-
ecs_query_table_node_t *node;
2834+
ecs_query_table_node_t *node, *prev;
28352835
int32_t sparse_smallest;
28362836
int32_t sparse_first;
28372837
int32_t bitset_first;
@@ -6055,18 +6055,52 @@ bool ecs_query_next_instanced(
60556055
ecs_iter_t *iter);
60566056

60576057
/** Returns whether the query data changed since the last iteration.
6058-
* This operation must be invoked before obtaining the iterator, as this will
6059-
* reset the changed state. The operation will return true after:
6058+
* The operation will return true after:
60606059
* - new entities have been matched with
6060+
* - new tables have been matched/unmatched with
60616061
* - matched entities were deleted
60626062
* - matched components were changed
60636063
*
6064-
* @param query The query.
6064+
* The operation will not return true after a write-only (EcsOut) or filter
6065+
* (EcsInOutFilter) term has changed, when a term is not matched with the
6066+
* current table (This subject) or for tag terms.
6067+
*
6068+
* The changed state of a table is reset after it is iterated. If a iterator was
6069+
* not iterated until completion, tables may still be marked as changed.
6070+
*
6071+
* If no iterator is provided the operation will return the changed state of the
6072+
* all matched tables of the query.
6073+
*
6074+
* If an iterator is provided, the operation will return the changed state of
6075+
* the currently returned iterator result. The following preconditions must be
6076+
* met before using an iterator with change detection:
6077+
*
6078+
* - The iterator is a query iterator (created with ecs_query_iter)
6079+
* - The iterator must be valid (ecs_query_next must have returned true)
6080+
* - The iterator must be instanced
6081+
*
6082+
* @param query The query (optional if 'it' is provided).
6083+
* @param it The iterator result to test (optional if 'query' is provided).
60656084
* @return true if entities changed, otherwise false.
60666085
*/
60676086
FLECS_API
60686087
bool ecs_query_changed(
6069-
const ecs_query_t *query);
6088+
ecs_query_t *query,
6089+
ecs_iter_t *it);
6090+
6091+
/** Skip a table while iterating.
6092+
* This operation lets the query iterator know that a table was skipped while
6093+
* iterating. A skipped table will not reset its changed state, and the query
6094+
* will not update the dirty flags of the table for its out columns.
6095+
*
6096+
* Only valid iterators must be provided (next has to be called at least once &
6097+
* return true) and the iterator must be a query iterator.
6098+
*
6099+
* @param it The iterator result to skip.
6100+
*/
6101+
FLECS_API
6102+
void ecs_query_skip(
6103+
ecs_iter_t *it);
60706104

60716105
/** Returns whether query is orphaned.
60726106
* When the parent query of a subquery is deleted, it is left in an orphaned
@@ -18526,7 +18560,7 @@ struct query_base {
1852618560
* @return true if entities changed, otherwise false.
1852718561
*/
1852818562
bool changed() {
18529-
return ecs_query_changed(m_query);
18563+
return ecs_query_changed(m_query, 0);
1853018564
}
1853118565

1853218566
/** Returns whether query is orphaned.

include/flecs.h

+38-4
Original file line numberDiff line numberDiff line change
@@ -2885,18 +2885,52 @@ bool ecs_query_next_instanced(
28852885
ecs_iter_t *iter);
28862886

28872887
/** Returns whether the query data changed since the last iteration.
2888-
* This operation must be invoked before obtaining the iterator, as this will
2889-
* reset the changed state. The operation will return true after:
2888+
* The operation will return true after:
28902889
* - new entities have been matched with
2890+
* - new tables have been matched/unmatched with
28912891
* - matched entities were deleted
28922892
* - matched components were changed
28932893
*
2894-
* @param query The query.
2894+
* The operation will not return true after a write-only (EcsOut) or filter
2895+
* (EcsInOutFilter) term has changed, when a term is not matched with the
2896+
* current table (This subject) or for tag terms.
2897+
*
2898+
* The changed state of a table is reset after it is iterated. If a iterator was
2899+
* not iterated until completion, tables may still be marked as changed.
2900+
*
2901+
* If no iterator is provided the operation will return the changed state of the
2902+
* all matched tables of the query.
2903+
*
2904+
* If an iterator is provided, the operation will return the changed state of
2905+
* the currently returned iterator result. The following preconditions must be
2906+
* met before using an iterator with change detection:
2907+
*
2908+
* - The iterator is a query iterator (created with ecs_query_iter)
2909+
* - The iterator must be valid (ecs_query_next must have returned true)
2910+
* - The iterator must be instanced
2911+
*
2912+
* @param query The query (optional if 'it' is provided).
2913+
* @param it The iterator result to test (optional if 'query' is provided).
28952914
* @return true if entities changed, otherwise false.
28962915
*/
28972916
FLECS_API
28982917
bool ecs_query_changed(
2899-
const ecs_query_t *query);
2918+
ecs_query_t *query,
2919+
ecs_iter_t *it);
2920+
2921+
/** Skip a table while iterating.
2922+
* This operation lets the query iterator know that a table was skipped while
2923+
* iterating. A skipped table will not reset its changed state, and the query
2924+
* will not update the dirty flags of the table for its out columns.
2925+
*
2926+
* Only valid iterators must be provided (next has to be called at least once &
2927+
* return true) and the iterator must be a query iterator.
2928+
*
2929+
* @param it The iterator result to skip.
2930+
*/
2931+
FLECS_API
2932+
void ecs_query_skip(
2933+
ecs_iter_t *it);
29002934

29012935
/** Returns whether query is orphaned.
29022936
* When the parent query of a subquery is deleted, it is left in an orphaned

include/flecs/addons/cpp/mixins/query/impl.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct query_base {
4747
* @return true if entities changed, otherwise false.
4848
*/
4949
bool changed() {
50-
return ecs_query_changed(m_query);
50+
return ecs_query_changed(m_query, 0);
5151
}
5252

5353
/** Returns whether query is orphaned.

include/flecs/private/api_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ typedef struct ecs_filter_iter_t {
133133
/** Query-iterator specific data */
134134
typedef struct ecs_query_iter_t {
135135
ecs_query_t *query;
136-
ecs_query_table_node_t *node;
136+
ecs_query_table_node_t *node, *prev;
137137
int32_t sparse_smallest;
138138
int32_t sparse_first;
139139
int32_t bitset_first;

src/private_types.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ struct ecs_query_table_match_t {
295295

296296
/* Next match in cache for same table (includes empty tables) */
297297
ecs_query_table_match_t *next_match;
298+
299+
int32_t *monitor; /* Used to monitor table for changes */
298300
};
299301

300302
/** A single table can occur multiple times in the cache when a term matches
@@ -303,7 +305,6 @@ typedef struct ecs_query_table_t {
303305
ecs_table_cache_hdr_t hdr; /* Header for ecs_table_cache_t */
304306
ecs_query_table_match_t *first; /* List with matches for table */
305307
ecs_query_table_match_t *last; /* Last discovered match for table */
306-
int32_t *monitor; /* Used to monitor table for changes */
307308
} ecs_query_table_t;
308309

309310
/** Points to the beginning & ending of a query group */
@@ -322,6 +323,7 @@ typedef struct ecs_query_table_list_t {
322323
#define EcsQueryIsOrphaned (512) /* Is subquery orphaned */
323324
#define EcsQueryHasOutColumns (1024) /* Does query have out columns */
324325
#define EcsQueryHasOptional (2048) /* Does query have optional columns */
326+
#define EcsQueryHasMonitor (4096) /* Does query track changes */
325327

326328
/* Query event type for notifying queries of world events */
327329
typedef enum ecs_query_eventkind_t {

0 commit comments

Comments
 (0)