Flecs v4.0
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
builder_i.hpp
Go to the documentation of this file.
1
6#pragma once
7
9
10namespace flecs
11{
12
17template<typename Base, typename ... Components>
19 query_builder_i(ecs_query_desc_t *desc, int32_t term_index = 0)
20 : term_index_(term_index)
21 , expr_count_(0)
22 , desc_(desc) { }
23
24 Base& instanced() {
25 desc_->flags |= EcsQueryIsInstanced;
26 return *this;
27 }
28
29 Base& query_flags(ecs_flags32_t flags) {
30 desc_->flags |= flags;
31 return *this;
32 }
33
34 Base& cache_kind(query_cache_kind_t kind) {
35 desc_->cache_kind = static_cast<ecs_query_cache_kind_t>(kind);
36 return *this;
37 }
38
39 Base& cached() {
40 return cache_kind(flecs::QueryCacheAuto);
41 }
42
43 Base& expr(const char *expr) {
44 ecs_check(expr_count_ == 0, ECS_INVALID_OPERATION,
45 "query_builder::expr() called more than once");
46 desc_->expr = expr;
47 expr_count_ ++;
48
49 error:
50 return *this;
51 }
52
53 /* With methods */
54
55 template<typename T>
56 Base& with() {
57 this->term();
58 *this->term_ = flecs::term(_::type<T>::id(this->world_v()));
59 this->term_->inout = static_cast<ecs_inout_kind_t>(
60 _::type_to_inout<T>());
61 if (this->term_->inout == EcsInOutDefault) {
62 this->inout_none();
63 }
64 return *this;
65 }
66
67 Base& with(id_t id) {
68 this->term();
69 *this->term_ = flecs::term(id);
70 if (this->term_->inout == EcsInOutDefault) {
71 this->inout_none();
72 }
73 return *this;
74 }
75
76 Base& with(const char *name) {
77 this->term();
78 *this->term_ = flecs::term().first(name);
79 if (this->term_->inout == EcsInOutDefault) {
80 this->inout_none();
81 }
82 return *this;
83 }
84
85 Base& with(const char *first, const char *second) {
86 this->term();
87 *this->term_ = flecs::term().first(first).second(second);
88 if (this->term_->inout == EcsInOutDefault) {
89 this->inout_none();
90 }
91 return *this;
92 }
93
94 Base& with(entity_t r, entity_t o) {
95 this->term();
96 *this->term_ = flecs::term(r, o);
97 if (this->term_->inout == EcsInOutDefault) {
98 this->inout_none();
99 }
100 return *this;
101 }
102
103 Base& with(entity_t r, const char *o) {
104 this->term();
105 *this->term_ = flecs::term(r).second(o);
106 if (this->term_->inout == EcsInOutDefault) {
107 this->inout_none();
108 }
109 return *this;
110 }
111
112 template<typename First>
113 Base& with(id_t o) {
114 return this->with(_::type<First>::id(this->world_v()), o);
115 }
116
117 template<typename First>
118 Base& with(const char *second) {
119 return this->with(_::type<First>::id(this->world_v())).second(second);
120 }
121
122 template<typename First, typename Second>
123 Base& with() {
124 return this->with<First>(_::type<Second>::id(this->world_v()));
125 }
126
127 template <typename E, if_t< is_enum<E>::value > = 0>
128 Base& with(E value) {
129 flecs::entity_t r = _::type<E>::id(this->world_v());
130 auto o = enum_type<E>(this->world_v()).entity(value);
131 return this->with(r, o);
132 }
133
134 Base& with(flecs::term& term) {
135 this->term();
136 *this->term_ = term;
137 return *this;
138 }
139
140 Base& with(flecs::term&& term) {
141 this->term();
142 *this->term_ = term;
143 return *this;
144 }
145
146 /* Without methods, shorthand for .with(...).not_(). */
147
148 template <typename ... Args>
149 Base& without(Args&&... args) {
150 return this->with(FLECS_FWD(args)...).not_();
151 }
152
153 template <typename T, typename ... Args>
154 Base& without(Args&&... args) {
155 return this->with<T>(FLECS_FWD(args)...).not_();
156 }
157
158 template <typename First, typename Second>
159 Base& without() {
160 return this->with<First, Second>().not_();
161 }
162
163 /* Write/read methods */
164
165 Base& write() {
167 return *this;
168 }
169
170 template <typename ... Args>
171 Base& write(Args&&... args) {
172 return this->with(FLECS_FWD(args)...).write();
173 }
174
175 template <typename T, typename ... Args>
176 Base& write(Args&&... args) {
177 return this->with<T>(FLECS_FWD(args)...).write();
178 }
179
180 template <typename First, typename Second>
181 Base& write() {
182 return this->with<First, Second>().write();
183 }
184
185 Base& read() {
187 return *this;
188 }
189
190 template <typename ... Args>
191 Base& read(Args&&... args) {
192 return this->with(FLECS_FWD(args)...).read();
193 }
194
195 template <typename T, typename ... Args>
196 Base& read(Args&&... args) {
197 return this->with<T>(FLECS_FWD(args)...).read();
198 }
199
200 template <typename First, typename Second>
201 Base& read() {
202 return this->with<First, Second>().read();
203 }
204
205 /* Scope_open/scope_close shorthand notation. */
206 Base& scope_open() {
207 return this->with(flecs::ScopeOpen).entity(0);
208 }
209
210 Base& scope_close() {
211 return this->with(flecs::ScopeClose).entity(0);
212 }
213
214 /* Term notation for more complex query features */
215
216 Base& term() {
217 if (this->term_) {
219 ECS_INVALID_OPERATION,
220 "query_builder::term() called without initializing term");
221 }
222
223 ecs_check(term_index_ < FLECS_TERM_COUNT_MAX,
224 ECS_INVALID_PARAMETER, "maximum number of terms exceeded");
225
226 this->set_term(&desc_->terms[term_index_]);
227
228 term_index_ ++;
229
230 error:
231 return *this;
232 }
233
234 Base& term_at(int32_t term_index) {
235 ecs_assert(term_index >= 0, ECS_INVALID_PARAMETER, NULL);
236 int32_t prev_index = term_index_;
237 term_index_ = term_index;
238 this->term();
239 term_index_ = prev_index;
241 ECS_INVALID_PARAMETER, NULL);
242 return *this;
243 }
244
263 template <typename T>
264 Base& order_by(int(*compare)(flecs::entity_t, const T*, flecs::entity_t, const T*)) {
265 ecs_order_by_action_t cmp = reinterpret_cast<ecs_order_by_action_t>(compare);
266 return this->order_by(_::type<T>::id(this->world_v()), cmp);
267 }
268
275 Base& order_by(flecs::entity_t component, int(*compare)(flecs::entity_t, const void*, flecs::entity_t, const void*)) {
276 desc_->order_by_callback = reinterpret_cast<ecs_order_by_action_t>(compare);
277 desc_->order_by = component;
278 return *this;
279 }
280
298 template <typename T>
299 Base& group_by(uint64_t(*group_by_action)(flecs::world_t*, flecs::table_t *table, flecs::id_t id, void* ctx)) {
300 ecs_group_by_action_t action = reinterpret_cast<ecs_group_by_action_t>(group_by_action);
301 return this->group_by(_::type<T>::id(this->world_v()), action);
302 }
303
310 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)) {
311 desc_->group_by_callback = reinterpret_cast<ecs_group_by_action_t>(group_by_action);
312 desc_->group_by = component;
313 return *this;
314 }
315
321 template <typename T>
322 Base& group_by() {
323 return this->group_by(_::type<T>::id(this->world_v()), nullptr);
324 }
325
331 Base& group_by(flecs::entity_t component) {
332 return this->group_by(component, nullptr);
333 }
334
340 Base& group_by_ctx(void *ctx, ecs_ctx_free_t ctx_free = nullptr) {
341 desc_->group_by_ctx = ctx;
342 desc_->group_by_ctx_free = ctx_free;
343 return *this;
344 }
345
349 desc_->on_group_create = action;
350 return *this;
351 }
352
356 desc_->on_group_delete = action;
357 return *this;
358 }
359
360protected:
361 virtual flecs::world_t* world_v() override = 0;
362 int32_t term_index_;
363 int32_t expr_count_;
364
365private:
366 operator Base&() {
367 return *static_cast<Base*>(this);
368 }
369
370 ecs_query_desc_t *desc_;
371};
372
373}
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:352
#define ecs_check(condition, error_code,...)
Check.
Definition log.h:399
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:555
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:568
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:562
void(* ecs_ctx_free_t)(void *ctx)
Function to cleanup context data.
Definition flecs.h:584
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:537
#define FLECS_TERM_COUNT_MAX
Maximum number of terms in queries.
Definition flecs.h:278
#define EcsQueryIsInstanced
Query iteration is always instanced.
Definition flecs.h:1119
bool ecs_term_is_initialized(const ecs_term_t *term)
Test whether a term is set.
ecs_query_cache_kind_t
Specify cache policy for query.
Definition flecs.h:651
ecs_inout_kind_t
Specify read/write access for term.
Definition flecs.h:630
@ EcsInOutDefault
InOut for regular terms, In for shared terms.
Definition flecs.h:631
Used with ecs_query_init().
Definition flecs.h:1138
ecs_id_t group_by
Component id to be used for grouping.
Definition flecs.h:1169
ecs_term_t terms[32]
Query terms.
Definition flecs.h:1143
ecs_ctx_free_t group_by_ctx_free
Function to free group_by_ctx.
Definition flecs.h:1190
void * group_by_ctx
Context to pass to group_by.
Definition flecs.h:1187
ecs_entity_t order_by
Component to sort on, used together with order_by_callback or order_by_table_callback.
Definition flecs.h:1165
ecs_order_by_action_t order_by_callback
Callback used for ordering query results.
Definition flecs.h:1157
ecs_group_create_action_t on_group_create
Callback that is invoked when a new group is created.
Definition flecs.h:1180
ecs_group_by_action_t group_by_callback
Callback used for grouping results.
Definition flecs.h:1176
ecs_group_delete_action_t on_group_delete
Callback that is invoked when an existing group is deleted.
Definition flecs.h:1184
ecs_flags32_t flags
Flags for enabling query features.
Definition flecs.h:1152
ecs_query_cache_kind_t cache_kind
Caching policy of query.
Definition flecs.h:1149
const char * expr
Query DSL expression (optional)
Definition flecs.h:1146
int16_t inout
Access to contents matched by term.
Definition flecs.h:750
Component class.
Query builder interface.
Definition builder_i.hpp:18
Base & group_by()
Group and sort matched tables.
Base & on_group_delete(ecs_group_delete_action_t action)
Specify on_group_delete action.
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.
Base & on_group_create(ecs_group_create_action_t action)
Specify on_group_create action.
Base & group_by(flecs::entity_t component)
Group and sort matched tables.
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.
Base & order_by(int(*compare)(flecs::entity_t, const T *, flecs::entity_t, const T *))
Sort the output of a query.
Base & group_by_ctx(void *ctx, ecs_ctx_free_t ctx_free=nullptr)
Specify context to be passed to group_by function.
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.
Term builder interface.
Definition builder_i.hpp:99
Base & read()
Short for inout_stage(flecs::In).
Base & inout_none()
Short for inout(flecs::In)
Base & write()
Short for inout_stage(flecs::Out).
Class that describes a term.
Definition impl.hpp:16
Term builder interface.