Flecs v3.2
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 filter_builder_i(ecs_filter_desc_t *desc, int32_t term_index = 0)
20 : m_term_index(term_index)
21 , m_expr_count(0)
22 , m_desc(desc) { }
23
24 Base& instanced() {
25 m_desc->instanced = true;
26 return *this;
27 }
28
29 Base& filter_flags(ecs_flags32_t flags) {
30 m_desc->flags |= flags;
31 return *this;
32 }
33
34 Base& expr(const char *expr) {
35 ecs_check(m_expr_count == 0, ECS_INVALID_OPERATION,
36 "filter_builder::expr() called more than once");
37 m_desc->expr = expr;
38 m_expr_count ++;
39
40 error:
41 return *this;
42 }
43
44 /* With/without shorthand notation. */
45
46 template <typename ... Args>
47 Base& with(Args&&... args) {
48 return this->term(FLECS_FWD(args)...).inout_none();
49 }
50
51 template <typename T, typename ... Args>
52 Base& with(Args&&... args) {
53 return this->term<T>(FLECS_FWD(args)...).inout_none();
54 }
55
56 template <typename First, typename Second>
57 Base& with() {
58 return this->term<First, Second>().inout_none();
59 }
60
61 template <typename ... Args>
62 Base& without(Args&&... args) {
63 return this->term(FLECS_FWD(args)...).not_();
64 }
65
66 template <typename T, typename ... Args>
67 Base& without(Args&&... args) {
68 return this->term<T>(FLECS_FWD(args)...).not_();
69 }
70
71 template <typename First, typename Second>
72 Base& without() {
73 return this->term<First, Second>().not_();
74 }
75
76 /* Write/read shorthand notation */
77
78 Base& write() {
80 return *this;
81 }
82
83 template <typename ... Args>
84 Base& write(Args&&... args) {
85 return this->term(FLECS_FWD(args)...).write();
86 }
87
88 template <typename T, typename ... Args>
89 Base& write(Args&&... args) {
90 return this->term<T>(FLECS_FWD(args)...).write();
91 }
92
93 template <typename First, typename Second>
94 Base& write() {
95 return this->term<First, Second>().write();
96 }
97
98 Base& read() {
100 return *this;
101 }
102
103 template <typename ... Args>
104 Base& read(Args&&... args) {
105 return this->term(FLECS_FWD(args)...).read();
106 }
107
108 template <typename T, typename ... Args>
109 Base& read(Args&&... args) {
110 return this->term<T>(FLECS_FWD(args)...).read();
111 }
112
113 template <typename First, typename Second>
114 Base& read() {
115 return this->term<First, Second>().read();
116 }
117
118 /* Scope_open/scope_close shorthand notation. */
119 Base& scope_open() {
120 return this->with(flecs::ScopeOpen).entity(0);
121 }
122
123 Base& scope_close() {
124 return this->with(flecs::ScopeClose).entity(0);
125 }
126
127 /* Term notation for more complex query features */
128
129 Base& term() {
130 if (this->m_term) {
131 ecs_check(ecs_term_is_initialized(this->m_term),
132 ECS_INVALID_OPERATION,
133 "filter_builder::term() called without initializing term");
134 }
135
136 if (m_term_index >= FLECS_TERM_DESC_MAX) {
137 if (m_term_index == FLECS_TERM_DESC_MAX) {
138 m_desc->terms_buffer = ecs_os_calloc_n(
139 ecs_term_t, m_term_index + 1);
140 ecs_os_memcpy_n(m_desc->terms_buffer, m_desc->terms,
141 ecs_term_t, m_term_index);
142 ecs_os_memset_n(m_desc->terms, 0,
144 } else {
145 m_desc->terms_buffer = ecs_os_realloc_n(m_desc->terms_buffer,
146 ecs_term_t, m_term_index + 1);
147 }
148
149 m_desc->terms_buffer_count = m_term_index + 1;
150
151 this->set_term(&m_desc->terms_buffer[m_term_index]);
152 } else {
153 this->set_term(&m_desc->terms[m_term_index]);
154 }
155
156 m_term_index ++;
157
158 error:
159 return *this;
160 }
161
162 Base& term_at(int32_t term_index) {
163 ecs_assert(term_index > 0, ECS_INVALID_PARAMETER, NULL);
164 int32_t prev_index = m_term_index;
165 m_term_index = term_index - 1;
166 this->term();
167 m_term_index = prev_index;
168 ecs_assert(ecs_term_is_initialized(this->m_term),
169 ECS_INVALID_PARAMETER, NULL);
170 return *this;
171 }
172
173 Base& arg(int32_t term_index) {
174 return this->term_at(term_index);
175 }
176
177 template<typename T>
178 Base& term() {
179 this->term();
180 *this->m_term = flecs::term(_::cpp_type<T>::id(this->world_v())).move();
181 this->m_term->inout = static_cast<ecs_inout_kind_t>(
182 _::type_to_inout<T>());
183 return *this;
184 }
185
186 Base& term(id_t id) {
187 this->term();
188 *this->m_term = flecs::term(id).move();
189 return *this;
190 }
191
192 Base& term(const char *name) {
193 this->term();
194 *this->m_term = flecs::term().first(name).move();
195 return *this;
196 }
197
198 Base& term(const char *first, const char *second) {
199 this->term();
200 *this->m_term = flecs::term().first(first).second(second).move();
201 return *this;
202 }
203
204 Base& term(entity_t r, entity_t o) {
205 this->term();
206 *this->m_term = flecs::term(r, o).move();
207 return *this;
208 }
209
210 Base& term(entity_t r, const char *o) {
211 this->term();
212 *this->m_term = flecs::term(r).second(o).move();
213 return *this;
214 }
215
216 template<typename First>
217 Base& term(id_t o) {
218 return this->term(_::cpp_type<First>::id(this->world_v()), o);
219 }
220
221 template<typename First>
222 Base& term(const char *second) {
223 return this->term(_::cpp_type<First>::id(this->world_v())).second(second);
224 }
225
226 template<typename First, typename Second>
227 Base& term() {
228 return this->term<First>(_::cpp_type<Second>::id(this->world_v()));
229 }
230
231 template <typename E, if_t< is_enum<E>::value > = 0>
232 Base& term(E value) {
233 flecs::entity_t r = _::cpp_type<E>::id(this->world_v());
234 auto o = enum_type<E>(this->world_v()).entity(value);
235 return this->term(r, o);
236 }
237
238 Base& term(flecs::term& term) {
239 this->term();
240 *this->m_term = term.move();
241 return *this;
242 }
243
244 Base& term(flecs::term&& term) {
245 this->term();
246 *this->m_term = term.move();
247 return *this;
248 }
249
250protected:
251 virtual flecs::world_t* world_v() = 0;
252 int32_t m_term_index;
253 int32_t m_expr_count;
254
255private:
256 operator Base&() {
257 return *static_cast<Base*>(this);
258 }
259
260 ecs_filter_desc_t *m_desc;
261};
262
263}
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:351
#define ecs_check(condition, error_code,...)
Check.
Definition log.h:398
bool ecs_term_is_initialized(const ecs_term_t *term)
Test whether a term is set.
#define FLECS_TERM_DESC_MAX
Maximum number of terms in ecs_filter_desc_t.
Definition flecs.h:266
ecs_inout_kind_t
Specify read/write access for term.
Definition flecs.h:687
Used with ecs_filter_init().
Definition flecs.h:998
ecs_term_t * terms_buffer
For filters with lots of terms an outside array can be provided.
Definition flecs.h:1006
bool instanced
When true, terms returned by an iterator may either contain 1 or N elements, where terms with N eleme...
Definition flecs.h:1019
ecs_term_t terms[(16)]
Terms of the filter.
Definition flecs.h:1003
int32_t terms_buffer_count
Number of terms in array provided in terms_buffer.
Definition flecs.h:1009
ecs_flags32_t flags
Flags for advanced usage.
Definition flecs.h:1022
const char * expr
Filter expression.
Definition flecs.h:1025
Type that describes a term (single element in a query)
Definition flecs.h:758
ecs_inout_kind_t inout
Access to contents matched by term.
Definition flecs.h:768
Filter builder interface.
Definition builder_i.hpp:18
Term builder interface.
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.