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

| 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
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> {
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& query_flags(ecs_flags32_t flags) {
25 desc_->flags |= flags;
26 return *this;
27 }
28
29 Base& cache_kind(query_cache_kind_t kind) {
30 desc_->cache_kind = static_cast<ecs_query_cache_kind_t>(kind);
31 return *this;
32 }
33
34 Base& cached() {
35 return cache_kind(flecs::QueryCacheAuto);
36 }
37
38 Base& expr(const char *expr) {
39 ecs_check(expr_count_ == 0, ECS_INVALID_OPERATION,
40 "query_builder::expr() called more than once");
41 desc_->expr = expr;
42 expr_count_ ++;
43
44 error:
45 return *this;
46 }
47
48 /* With methods */
49
50 template<typename T>
51 Base& with() {
52 this->term();
53 *this->term_ = flecs::term(_::type<T>::id(this->world_v()));
54 this->term_->inout = static_cast<ecs_inout_kind_t>(
55 _::type_to_inout<T>());
56 if (this->term_->inout == EcsInOutDefault) {
57 this->inout_none();
58 }
59 return *this;
60 }
61
62 Base& with(id_t id) {
63 this->term();
64 *this->term_ = flecs::term(id);
65 if (this->term_->inout == EcsInOutDefault) {
66 this->inout_none();
67 }
68 return *this;
69 }
70
71 Base& with(const char *name) {
72 this->term();
73 *this->term_ = flecs::term().first(name);
74 if (this->term_->inout == EcsInOutDefault) {
75 this->inout_none();
76 }
77 return *this;
78 }
79
80 Base& with(const char *first, const char *second) {
81 this->term();
82 *this->term_ = flecs::term().first(first).second(second);
83 if (this->term_->inout == EcsInOutDefault) {
84 this->inout_none();
85 }
86 return *this;
87 }
88
89 Base& with(entity_t r, entity_t o) {
90 this->term();
91 *this->term_ = flecs::term(r, o);
92 if (this->term_->inout == EcsInOutDefault) {
93 this->inout_none();
94 }
95 return *this;
96 }
97
98 Base& with(entity_t r, const char *o) {
99 this->term();
100 *this->term_ = flecs::term(r).second(o);
101 if (this->term_->inout == EcsInOutDefault) {
102 this->inout_none();
103 }
104 return *this;
105 }
106
107 Base& with(const char *r, entity_t o) {
108 this->term();
109 *this->term_ = flecs::term().first(r).second(o);
110 if (this->term_->inout == EcsInOutDefault) {
111 this->inout_none();
112 }
113 return *this;
114 }
115
116 template<typename First>
117 Base& with(id_t o) {
118 return this->with(_::type<First>::id(this->world_v()), o);
119 }
120
121 template<typename First>
122 Base& with(const char *second) {
123 return this->with(_::type<First>::id(this->world_v())).second(second);
124 }
125
126 template<typename First, typename Second>
127 Base& with() {
128 return this->with<First>(_::type<Second>::id(this->world_v()));
129 }
130
131 template <typename E, if_t< is_enum<E>::value > = 0>
132 Base& with(E value) {
133 flecs::entity_t r = _::type<E>::id(this->world_v());
134 auto o = enum_type<E>(this->world_v()).entity(value);
135 return this->with(r, o);
136 }
137
138 Base& with(flecs::term& term) {
139 this->term();
140 *this->term_ = term;
141 return *this;
142 }
143
144 Base& with(flecs::term&& term) {
145 this->term();
146 *this->term_ = term;
147 return *this;
148 }
149
150 /* Without methods, shorthand for .with(...).not_(). */
151
152 template <typename ... Args>
153 Base& without(Args&&... args) {
154 return this->with(FLECS_FWD(args)...).not_();
155 }
156
157 template <typename T, typename ... Args>
158 Base& without(Args&&... args) {
159 return this->with<T>(FLECS_FWD(args)...).not_();
160 }
161
162 template <typename First, typename Second>
163 Base& without() {
164 return this->with<First, Second>().not_();
165 }
166
167 /* Write/read methods */
168
169 Base& write() {
170 term_builder_i<Base>::write();
171 return *this;
172 }
173
174 template <typename ... Args>
175 Base& write(Args&&... args) {
176 return this->with(FLECS_FWD(args)...).write();
177 }
178
179 template <typename T, typename ... Args>
180 Base& write(Args&&... args) {
181 return this->with<T>(FLECS_FWD(args)...).write();
182 }
183
184 template <typename First, typename Second>
185 Base& write() {
186 return this->with<First, Second>().write();
187 }
188
189 Base& read() {
190 term_builder_i<Base>::read();
191 return *this;
192 }
193
194 template <typename ... Args>
195 Base& read(Args&&... args) {
196 return this->with(FLECS_FWD(args)...).read();
197 }
198
199 template <typename T, typename ... Args>
200 Base& read(Args&&... args) {
201 return this->with<T>(FLECS_FWD(args)...).read();
202 }
203
204 template <typename First, typename Second>
205 Base& read() {
206 return this->with<First, Second>().read();
207 }
208
209 /* Scope_open/scope_close shorthand notation. */
210 Base& scope_open() {
211 return this->with(flecs::ScopeOpen).entity(0);
212 }
213
214 Base& scope_close() {
215 return this->with(flecs::ScopeClose).entity(0);
216 }
217
218 /* Term notation for more complex query features */
219
220 Base& term() {
221 if (this->term_) {
222 ecs_check(ecs_term_is_initialized(this->term_),
223 ECS_INVALID_OPERATION,
224 "query_builder::term() called without initializing term");
225 }
226
227 ecs_check(term_index_ < FLECS_TERM_COUNT_MAX,
228 ECS_INVALID_PARAMETER, "maximum number of terms exceeded");
229
230 this->set_term(&desc_->terms[term_index_]);
231
232 term_index_ ++;
233
234 error:
235 return *this;
236 }
237
238 Base& term_at(int32_t term_index) {
239 ecs_assert(term_index >= 0, ECS_INVALID_PARAMETER, NULL);
240 int32_t prev_index = term_index_;
241 term_index_ = term_index;
242 this->term();
243 term_index_ = prev_index;
244 ecs_assert(ecs_term_is_initialized(this->term_),
245 ECS_INVALID_PARAMETER, NULL);
246 return *this;
247 }
248
267 template <typename T>
268 Base& order_by(int(*compare)(flecs::entity_t, const T*, flecs::entity_t, const T*)) {
269 ecs_order_by_action_t cmp = reinterpret_cast<ecs_order_by_action_t>(compare);
270 return this->order_by(_::type<T>::id(this->world_v()), cmp);
271 }
272
279 Base& order_by(flecs::entity_t component, int(*compare)(flecs::entity_t, const void*, flecs::entity_t, const void*)) {
280 desc_->order_by_callback = reinterpret_cast<ecs_order_by_action_t>(compare);
281 desc_->order_by = component;
282 return *this;
283 }
284
302 template <typename T>
303 Base& group_by(uint64_t(*group_by_action)(flecs::world_t*, flecs::table_t *table, flecs::id_t id, void* ctx)) {
304 ecs_group_by_action_t action = reinterpret_cast<ecs_group_by_action_t>(group_by_action);
305 return this->group_by(_::type<T>::id(this->world_v()), action);
306 }
307
314 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)) {
315 desc_->group_by_callback = reinterpret_cast<ecs_group_by_action_t>(group_by_action);
316 desc_->group_by = component;
317 return *this;
318 }
319
325 template <typename T>
326 Base& group_by() {
327 return this->group_by(_::type<T>::id(this->world_v()), nullptr);
328 }
329
335 Base& group_by(flecs::entity_t component) {
336 return this->group_by(component, nullptr);
337 }
338
344 Base& group_by_ctx(void *ctx, ecs_ctx_free_t ctx_free = nullptr) {
345 desc_->group_by_ctx = ctx;
346 desc_->group_by_ctx_free = ctx_free;
347 return *this;
348 }
349
352 Base& on_group_create(ecs_group_create_action_t action) {
353 desc_->on_group_create = action;
354 return *this;
355 }
356
359 Base& on_group_delete(ecs_group_delete_action_t action) {
360 desc_->on_group_delete = action;
361 return *this;
362 }
363
364protected:
365 virtual flecs::world_t* world_v() override = 0;
366 int32_t term_index_;
367 int32_t expr_count_;
368
369private:
370 operator Base&() {
371 return *static_cast<Base*>(this);
372 }
373
374 ecs_query_desc_t *desc_;
375};
376
377}
ecs_assert
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:368
ecs_check
#define ecs_check(condition, error_code,...)
Check.
Definition log.h:415
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:585
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:598
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:592
ecs_ctx_free_t
void(* ecs_ctx_free_t)(void *ctx)
Function to cleanup context data.
Definition flecs.h:614
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:567
FLECS_TERM_COUNT_MAX
#define FLECS_TERM_COUNT_MAX
Maximum number of terms in queries.
Definition flecs.h:277
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:681
ecs_inout_kind_t
ecs_inout_kind_t
Specify read/write access for term.
Definition flecs.h:660
EcsInOutDefault
@ EcsInOutDefault
InOut for regular terms, In for shared terms.
Definition flecs.h:661
ecs_query_desc_t
Used with ecs_query_init().
Definition flecs.h:1199
flecs::_::type
Definition flecs.hpp:38
flecs::component
Component class.
Definition flecs.hpp:30
flecs::query_builder_i::group_by
Base & group_by()
Group and sort matched tables.
Definition builder_i.hpp:326
flecs::query_builder_i::on_group_delete
Base & on_group_delete(ecs_group_delete_action_t action)
Specify on_group_delete action.
Definition builder_i.hpp:359
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:314
flecs::query_builder_i::on_group_create
Base & on_group_create(ecs_group_create_action_t action)
Specify on_group_create action.
Definition builder_i.hpp:352
flecs::query_builder_i::group_by
Base & group_by(flecs::entity_t component)
Group and sort matched tables.
Definition builder_i.hpp:335
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:303
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:268
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 group_by function.
Definition builder_i.hpp:344
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:279
flecs::table
Definition table.hpp:18
flecs::term_builder_i::read
Base & read()
Short for inout_stage(flecs::In).
Definition builder_i.hpp:315
flecs::term_builder_i::inout_none
Base & inout_none()
Short for inout(flecs::In)
Definition builder_i.hpp:342
flecs::term_builder_i::write
Base & write()
Short for inout_stage(flecs::Out).
Definition builder_i.hpp:308
flecs::term
Class that describes a term.
Definition impl.hpp:16
builder_i.hpp
Term builder interface.