Flecs: include/flecs/addons/cpp/mixins/query/builder_i.hpp Source File
Description: A fast entity component system (ECS) for C & C++

| Flecs v4.1 A fast entity component system (ECS) for C & C++

Loading...
Searching...
No Matches
builder_i.hpp
Go to the documentation of this file.
1
5
6#pragma once
7
8#include "../term/builder_i.hpp"
9
10namespace flecs
11{
12
17template<typename Base, typename ... Components>
18 struct query_builder_i : term_builder_i<Base> {
20 query_builder_i(ecs_query_desc_t *desc, int32_t term_index = 0)
21 : term_index_(term_index)
22 , expr_count_(0)
23 , desc_(desc) { }
24
26 Base& query_flags(ecs_flags32_t flags) {
27 desc_->flags |= flags;
28 return *this;
29 }
30
32 Base& cache_kind(query_cache_kind_t kind) {
33 desc_->cache_kind = static_cast<ecs_query_cache_kind_t>(kind);
34 return *this;
35 }
36
38 Base& cached() {
39 return cache_kind(flecs::QueryCacheAuto);
40 }
41
43 Base& detect_changes() {
44 desc_->flags |= EcsQueryDetectChanges;
45 return *this;
46 }
47
49 Base& expr(const char *expr) {
50 ecs_check(expr_count_ == 0, ECS_INVALID_OPERATION,
51 "query_builder::expr() called more than once");
52 desc_->expr = expr;
53 expr_count_ ++;
54
55 error:
56 return *this;
57 }
58
62
64 template<typename T>
65 Base& with() {
66 this->term();
67 *this->term_ = flecs::term(_::type<T>::id(this->world_v()));
68 this->term_->inout = static_cast<ecs_inout_kind_t>(
69 _::type_to_inout<T>());
70 return *this;
71 }
72
74 Base& with(id_t component_id) {
75 this->term();
76 *this->term_ = flecs::term(component_id);
77 return *this;
78 }
79
81 Base& with(const char *component_name) {
82 this->term();
83 *this->term_ = flecs::term().first(component_name);
84 return *this;
85 }
86
88 Base& with(const char *first, const char *second) {
89 this->term();
90 *this->term_ = flecs::term().first(first).second(second);
91 return *this;
92 }
93
95 Base& with(entity_t first, entity_t second) {
96 this->term();
97 *this->term_ = flecs::term(first, second);
98 return *this;
99 }
100
102 Base& with(entity_t first, const char *second) {
103 this->term();
104 *this->term_ = flecs::term(first).second(second);
105 return *this;
106 }
107
109 Base& with(const char *first, entity_t second) {
110 this->term();
111 *this->term_ = flecs::term().first(first).second(second);
112 return *this;
113 }
114
116 template<typename First>
117 Base& with(entity_t second) {
118 return this->with(_::type<First>::id(this->world_v()), second);
119 }
120
122 template<typename First>
123 Base& with(const char *second) {
124 return this->with(_::type<First>::id(this->world_v())).second(second);
125 }
126
128 template<typename First, typename Second>
129 Base& with() {
130 return this->with<First>(_::type<Second>::id(this->world_v()));
131 }
132
134 template <typename E, if_t< is_enum<E>::value > = 0>
135 Base& with(E value) {
136 flecs::entity_t r = _::type<E>::id(this->world_v());
137 auto o = enum_type<E>(this->world_v()).entity(value);
138 return this->with(r, o);
139 }
140
142 Base& with(flecs::term& term) {
143 this->term();
144 *this->term_ = term;
145 return *this;
146 }
147
149 Base& with(flecs::term&& term) {
150 this->term();
151 *this->term_ = term;
152 return *this;
153 }
154
160
162 template <typename ... Args>
163 Base& without(Args&&... args) {
164 return this->with(FLECS_FWD(args)...).not_();
165 }
166
168 template <typename T, typename ... Args>
169 Base& without(Args&&... args) {
170 return this->with<T>(FLECS_FWD(args)...).not_();
171 }
172
174 template <typename First, typename Second>
175 Base& without() {
176 return this->with<First, Second>().not_();
177 }
178
183
185 Base& write() {
186 term_builder_i<Base>::write();
187 return *this;
188 }
189
191 template <typename ... Args>
192 Base& write(Args&&... args) {
193 return this->with(FLECS_FWD(args)...).write();
194 }
195
197 template <typename T, typename ... Args>
198 Base& write(Args&&... args) {
199 return this->with<T>(FLECS_FWD(args)...).write();
200 }
201
203 template <typename First, typename Second>
204 Base& write() {
205 return this->with<First, Second>().write();
206 }
207
209 Base& read() {
210 term_builder_i<Base>::read();
211 return *this;
212 }
213
215 template <typename ... Args>
216 Base& read(Args&&... args) {
217 return this->with(FLECS_FWD(args)...).read();
218 }
219
221 template <typename T, typename ... Args>
222 Base& read(Args&&... args) {
223 return this->with<T>(FLECS_FWD(args)...).read();
224 }
225
227 template <typename First, typename Second>
228 Base& read() {
229 return this->with<First, Second>().read();
230 }
231
233
235 Base& scope_open() {
236 return this->with(flecs::ScopeOpen).entity(0);
237 }
238
240 Base& scope_close() {
241 return this->with(flecs::ScopeClose).entity(0);
242 }
243
245 Base& term() {
246 if (this->term_) {
247 ecs_check(ecs_term_is_initialized(this->term_),
248 ECS_INVALID_OPERATION,
249 "query_builder::term() called without initializing term");
250 }
251
252 ecs_check(term_index_ < FLECS_TERM_COUNT_MAX,
253 ECS_INVALID_PARAMETER, "maximum number of terms exceeded");
254
255 this->set_term(&desc_->terms[term_index_]);
256
257 term_index_ ++;
258
259 error:
260 return *this;
261 }
262
267 template <typename T>
268 Base& term_at() {
269 flecs::id_t term_id = _::type<T>::id(this->world_v());
270 for (int i = 0; i < term_index_; i ++) {
271 ecs_term_t cur_term = desc_->terms[i];
272 ecs_id_t cur_term_id = cur_term.id;
273 ecs_id_t cur_term_pair = ecs_pair(cur_term.first.id, cur_term.second.id);
274
275 if ((term_id == cur_term_id || (cur_term_id != 0 && term_id == ecs_get_typeid(this->world_v(), cur_term_id))) ||
276 (term_id == cur_term_pair || (cur_term_pair != 0 && term_id == ecs_get_typeid(this->world_v(), cur_term_pair)))) {
277 return term_at(i);
278 }
279 }
280
281 ecs_err("term not found");
282 return *this;
283 }
284
286 Base& term_at(int32_t term_index) {
287 ecs_assert(term_index >= 0, ECS_INVALID_PARAMETER, nullptr);
288 int32_t prev_index = term_index_;
289 term_index_ = term_index;
290 this->term();
291 term_index_ = prev_index;
292 ecs_assert(ecs_term_is_initialized(this->term_),
293 ECS_INVALID_PARAMETER, nullptr);
294 return *this;
295 }
296
299 template <typename T>
300 Base& term_at(int32_t term_index) {
301 this->term_at(term_index);
302#if !defined(FLECS_NDEBUG) || defined(FLECS_KEEP_ASSERT)
303 flecs::id_t term_id = _::type<T>::id(this->world_v());
304 ecs_term_t cur_term = *this->term_;
305 ecs_id_t cur_term_id = cur_term.id;
306 ecs_id_t cur_term_pair = ecs_pair(cur_term.first.id, cur_term.second.id);
307
308 ecs_assert((term_id == cur_term_id || (cur_term_id != 0 && term_id == ecs_get_typeid(this->world_v(), cur_term_id))) ||
309 (term_id == cur_term_pair || (cur_term_pair != 0 && term_id == ecs_get_typeid(this->world_v(), cur_term_pair))),
310 ECS_INVALID_PARAMETER, "term type mismatch");
311#endif
312 return *this;
313 }
314
333 template <typename T>
334 Base& order_by(int(*compare)(flecs::entity_t, const T*, flecs::entity_t, const T*)) {
335 ecs_order_by_action_t cmp = reinterpret_cast<ecs_order_by_action_t>(compare);
336 return this->order_by(_::type<T>::id(this->world_v()), cmp);
337 }
338
345 Base& order_by(flecs::entity_t component, int(*compare)(flecs::entity_t, const void*, flecs::entity_t, const void*)) {
346 desc_->order_by_callback = reinterpret_cast<ecs_order_by_action_t>(compare);
347 desc_->order_by = component;
348 return *this;
349 }
350
368 template <typename T>
369 Base& group_by(uint64_t(*group_by_action)(flecs::world_t*, flecs::table_t *table, flecs::id_t id, void* ctx)) {
370 ecs_group_by_action_t action = reinterpret_cast<ecs_group_by_action_t>(group_by_action);
371 return this->group_by(_::type<T>::id(this->world_v()), action);
372 }
373
380 Base& group_by(flecs::entity_t component, uint64_t(*group_by_action)(flecs::world_t*, flecs::table_t *table, flecs::id_t id, void* ctx)) {
381 desc_->group_by_callback = reinterpret_cast<ecs_group_by_action_t>(group_by_action);
382 desc_->group_by = component;
383 return *this;
384 }
385
391 template <typename T>
392 Base& group_by() {
393 return this->group_by(_::type<T>::id(this->world_v()), nullptr);
394 }
395
401 Base& group_by(flecs::entity_t component) {
402 return this->group_by(component, nullptr);
403 }
404
410 Base& group_by_ctx(void *ctx, ecs_ctx_free_t ctx_free = nullptr) {
411 desc_->group_by_ctx = ctx;
412 desc_->group_by_ctx_free = ctx_free;
413 return *this;
414 }
415
417 Base& on_group_create(ecs_group_create_action_t action) {
418 desc_->on_group_create = action;
419 return *this;
420 }
421
423 Base& on_group_delete(ecs_group_delete_action_t action) {
424 desc_->on_group_delete = action;
425 return *this;
426 }
427
428protected:
429 virtual flecs::world_t* world_v() override = 0;
430 int32_t term_index_;
431 int32_t expr_count_;
432
433private:
434 operator Base&() {
435 return *static_cast<Base*>(this);
436 }
437
438 ecs_query_desc_t *desc_;
439};
440
441}
ecs_assert
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
ECS_INVALID_OPERATION
#define ECS_INVALID_OPERATION
Invalid operation error code.
Definition log.h:669
ecs_err
#define ecs_err(...)
Error macro.
Definition log.h:319
ECS_INVALID_PARAMETER
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:671
ecs_check
#define ecs_check(condition, error_code,...)
Check.
Definition log.h:527
ecs_id_t
uint64_t ecs_id_t
IDs are the things that can be added to an entity.
Definition flecs.h:378
flecs::table_t
ecs_table_t table_t
Table type.
Definition c_types.hpp:23
flecs::id_t
ecs_id_t id_t
ID type.
Definition c_types.hpp:20
flecs::entity_t
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
flecs::query_cache_kind_t
query_cache_kind_t
Query cache kind.
Definition c_types.hpp:60
flecs::world_t
ecs_world_t world_t
World type.
Definition c_types.hpp:18
flecs::QueryCacheAuto
@ QueryCacheAuto
Auto query cache.
Definition c_types.hpp:62
ecs_group_by_action_t
uint64_t(* ecs_group_by_action_t)(ecs_world_t *world, ecs_table_t *table, ecs_id_t group_id, void *ctx)
Callback used for grouping tables in a query.
Definition flecs.h:621
ecs_group_delete_action_t
void(* ecs_group_delete_action_t)(ecs_world_t *world, uint64_t group_id, void *group_ctx, void *group_by_ctx)
Callback invoked when a query deletes an existing group.
Definition flecs.h:634
ecs_group_create_action_t
void *(* ecs_group_create_action_t)(ecs_world_t *world, uint64_t group_id, void *group_by_ctx)
Callback invoked when a query creates a new group.
Definition flecs.h:628
ecs_ctx_free_t
void(* ecs_ctx_free_t)(void *ctx)
Function to clean up context data.
Definition flecs.h:650
ecs_order_by_action_t
int(* ecs_order_by_action_t)(ecs_entity_t e1, const void *ptr1, ecs_entity_t e2, const void *ptr2)
Callback used for comparing components.
Definition flecs.h:603
ecs_get_typeid
ecs_entity_t ecs_get_typeid(const ecs_world_t *world, ecs_id_t component)
Get the type for a component.
FLECS_TERM_COUNT_MAX
#define FLECS_TERM_COUNT_MAX
Maximum number of terms in queries.
Definition flecs.h:330
EcsQueryDetectChanges
#define EcsQueryDetectChanges
Enable change detection for a query.
Definition flecs.h:1273
ecs_term_is_initialized
bool ecs_term_is_initialized(const ecs_term_t *term)
Test whether a term is set.
ecs_query_cache_kind_t
ecs_query_cache_kind_t
Specify cache policy for query.
Definition flecs.h:729
ecs_inout_kind_t
ecs_inout_kind_t
Specify read/write access for term.
Definition flecs.h:708
ecs_query_desc_t
Used with ecs_query_init().
Definition flecs.h:1301
ecs_term_ref_t::id
ecs_entity_t id
Entity ID.
Definition flecs.h:800
ecs_term_t
Type that describes a term (single element in a query).
Definition flecs.h:814
ecs_term_t::id
ecs_id_t id
Component ID to be matched by term.
Definition flecs.h:815
ecs_term_t::second
ecs_term_ref_t second
Second element of pair.
Definition flecs.h:822
ecs_term_t::first
ecs_term_ref_t first
Component or first element of pair.
Definition flecs.h:821
flecs::_::type
Definition flecs.hpp:39
flecs::component
Component class.
Definition component.hpp:444
flecs::query_builder_i::with
Base & with(id_t component_id)
Add a term for the specified component ID.
Definition builder_i.hpp:74
flecs::query_builder_i::with
Base & with(E value)
Add a term for an enum value.
Definition builder_i.hpp:135
flecs::query_builder_i::term_at
Base & term_at(int32_t term_index)
Set the current term to the one at the provided index and assert that the type matches.
Definition builder_i.hpp:300
flecs::query_builder_i::group_by
Base & group_by()
Group and sort matched tables.
Definition builder_i.hpp:392
flecs::query_builder_i::scope_close
Base & scope_close()
Close a query scope.
Definition builder_i.hpp:240
flecs::query_builder_i::on_group_delete
Base & on_group_delete(ecs_group_delete_action_t action)
Specify the on_group_delete() action.
Definition builder_i.hpp:423
flecs::query_builder_i::write
Base & write()
Short for inout_stage(flecs::Out).
Definition builder_i.hpp:185
flecs::query_builder_i::write
Base & write(Args &&... args)
Add a write term for the specified type.
Definition builder_i.hpp:198
flecs::query_builder_i::scope_open
Base & scope_open()
Open a query scope.
Definition builder_i.hpp:235
flecs::query_builder_i::read
Base & read(Args &&... args)
Add a read term for the specified type.
Definition builder_i.hpp:222
flecs::query_builder_i::read
Base & read()
Add a read term for a pair of types.
Definition builder_i.hpp:228
flecs::query_builder_i::without
Base & without()
Add a negated term for a pair of types.
Definition builder_i.hpp:175
flecs::query_builder_i::with
Base & with(flecs::term &&term)
Add a term from an existing term (move).
Definition builder_i.hpp:149
flecs::query_builder_i::group_by
Base & group_by(flecs::entity_t component, uint64_t(*group_by_action)(flecs::world_t *, flecs::table_t *table, flecs::id_t id, void *ctx))
Group and sort matched tables.
Definition builder_i.hpp:380
flecs::query_builder_i::cache_kind
Base & cache_kind(query_cache_kind_t kind)
Set the cache kind for the query.
Definition builder_i.hpp:32
flecs::query_builder_i::with
Base & with()
Add a term for the specified type.
Definition builder_i.hpp:65
flecs::query_builder_i::expr
Base & expr(const char *expr)
Set the query expression string.
Definition builder_i.hpp:49
flecs::query_builder_i::on_group_create
Base & on_group_create(ecs_group_create_action_t action)
Specify the on_group_create() action.
Definition builder_i.hpp:417
flecs::query_builder_i::detect_changes
Base & detect_changes()
Enable change detection for the query.
Definition builder_i.hpp:43
flecs::query_builder_i::with
Base & with(const char *first, const char *second)
Add a term for a pair specified by name.
Definition builder_i.hpp:88
flecs::query_builder_i::with
Base & with()
Add a term for a pair with types First and Second.
Definition builder_i.hpp:129
flecs::query_builder_i::write
Base & write()
Add a write term for a pair of types.
Definition builder_i.hpp:204
flecs::query_builder_i::with
Base & with(const char *component_name)
Add a term for the specified component name.
Definition builder_i.hpp:81
flecs::query_builder_i::query_flags
Base & query_flags(ecs_flags32_t flags)
Set the query flags.
Definition builder_i.hpp:26
flecs::query_builder_i::group_by
Base & group_by(flecs::entity_t component)
Group and sort matched tables.
Definition builder_i.hpp:401
flecs::query_builder_i::read
Base & read(Args &&... args)
Add a read term with the specified arguments.
Definition builder_i.hpp:216
flecs::query_builder_i::group_by
Base & group_by(uint64_t(*group_by_action)(flecs::world_t *, flecs::table_t *table, flecs::id_t id, void *ctx))
Group and sort matched tables.
Definition builder_i.hpp:369
flecs::query_builder_i::term_at
Base & term_at(int32_t term_index)
Set the current term to the one at the provided index.
Definition builder_i.hpp:286
flecs::query_builder_i::term
Base & term()
Set the current term to the next one in the term list.
Definition builder_i.hpp:245
flecs::query_builder_i::with
Base & with(entity_t first, entity_t second)
Add a term for a pair specified by entity IDs.
Definition builder_i.hpp:95
flecs::query_builder_i::write
Base & write(Args &&... args)
Add a write term with the specified arguments.
Definition builder_i.hpp:192
flecs::query_builder_i::with
Base & with(entity_t second)
Add a term for a pair with type First and an entity ID second.
Definition builder_i.hpp:117
flecs::query_builder_i::without
Base & without(Args &&... args)
Add a negated term.
Definition builder_i.hpp:163
flecs::query_builder_i::without
Base & without(Args &&... args)
Add a negated term for the specified type.
Definition builder_i.hpp:169
flecs::query_builder_i::read
Base & read()
Short for inout_stage(flecs::In).
Definition builder_i.hpp:209
flecs::query_builder_i::with
Base & with(entity_t first, const char *second)
Add a term for a pair with an entity ID first and a name second.
Definition builder_i.hpp:102
flecs::query_builder_i::order_by
Base & order_by(int(*compare)(flecs::entity_t, const T *, flecs::entity_t, const T *))
Sort the output of a query.
Definition builder_i.hpp:334
flecs::query_builder_i::group_by_ctx
Base & group_by_ctx(void *ctx, ecs_ctx_free_t ctx_free=nullptr)
Specify context to be passed to the group_by() function.
Definition builder_i.hpp:410
flecs::query_builder_i::query_builder_i
query_builder_i(ecs_query_desc_t *desc, int32_t term_index=0)
Construct from a query descriptor.
Definition builder_i.hpp:20
flecs::query_builder_i::cached
Base & cached()
Enable auto-caching for the query.
Definition builder_i.hpp:38
flecs::query_builder_i::with
Base & with(const char *second)
Add a term for a pair with type First and name second.
Definition builder_i.hpp:123
flecs::query_builder_i::term_at
Base & term_at()
Set the current term to the one with the provided type.
Definition builder_i.hpp:268
flecs::query_builder_i::with
Base & with(flecs::term &term)
Add a term from an existing term reference.
Definition builder_i.hpp:142
flecs::query_builder_i::order_by
Base & order_by(flecs::entity_t component, int(*compare)(flecs::entity_t, const void *, flecs::entity_t, const void *))
Sort the output of a query.
Definition builder_i.hpp:345
flecs::query_builder_i::with
Base & with(const char *first, entity_t second)
Add a term for a pair with a name first and an entity ID second.
Definition builder_i.hpp:109
flecs::table
Table.
Definition table.hpp:23
flecs::term_builder_i::set_term
void set_term(ecs_term_t *term)
Set the current term pointer.
Definition builder_i.hpp:411
flecs::term_builder_i::desc
Base & desc()
Use with cascade() to iterate results in descending (bottom-to-top) order.
Definition builder_i.hpp:264
flecs::term_builder_i::term_
ecs_term_t * term_
Pointer to the current term.
Definition builder_i.hpp:405
flecs::term_builder_i::second
Base & second()
Call prior to setting values for the second identifier.
Definition builder_i.hpp:135
flecs::term_builder_i::read
Base & read()
Short for inout_stage(flecs::In).
Definition builder_i.hpp:324
flecs::term_builder_i::term_builder_i
term_builder_i()
Default constructor.
Definition builder_i.hpp:105
flecs::term_builder_i::write
Base & write()
Short for inout_stage(flecs::Out).
Definition builder_i.hpp:317
flecs::term_builder_i::first
Base & first()
Call prior to setting values for the first identifier.
Definition builder_i.hpp:127
flecs::term_ref_builder_i::flags
Base & flags(flecs::flags64_t flags)
Override the term ID flags.
Definition builder_i.hpp:74
flecs::term
Class that describes a term.
Definition impl.hpp:16
builder_i.hpp
Term builder interface.