Flecs v4.1
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
iterable.hpp
Go to the documentation of this file.
1
6namespace flecs {
7
9template <typename ... Components>
10struct iter_iterable;
11
13template <typename ... Components>
14struct page_iterable;
15
17template <typename ... Components>
18struct worker_iterable;
19
21template <typename ... Components>
22struct iterable {
23
33 template <typename Func>
34 void each(Func&& func) const {
35 ecs_iter_t it = this->get_iter(nullptr);
36 ecs_iter_next_action_t next = this->next_action();
37 while (next(&it)) {
38 _::each_delegate<Func, Components...>(func).invoke(&it);
39 }
40 }
41
49 template <typename Func>
50 void run(Func&& func) const {
51 ecs_iter_t it = this->get_iter(nullptr);
52 _::run_delegate<Func>(func).invoke(&it);
53 }
54
61 template <typename Func>
62 flecs::entity find(Func&& func) const {
63 ecs_iter_t it = this->get_iter(nullptr);
64 ecs_iter_next_action_t next = this->next_action();
65
66 flecs::entity result;
67 while (!result && next(&it)) {
68 result = _::find_delegate<Func, Components...>(func).invoke(&it);
69 }
70
71 if (result) {
72 ecs_iter_fini(&it);
73 }
74
75 return result;
76 }
77
81 iter_iterable<Components...> iter(flecs::world_t *world = nullptr) const;
82
86 iter_iterable<Components...> iter(flecs::iter& iter) const;
87
91 iter_iterable<Components...> iter(flecs::entity e) const;
92
100 page_iterable<Components...> page(int32_t offset, int32_t limit);
101
110 worker_iterable<Components...> worker(int32_t index, int32_t count);
111
113 int32_t count() const {
114 return this->iter().count();
115 }
116
118 bool is_true() const {
119 return this->iter().is_true();
120 }
121
124 return this->iter().first();
125 }
126
128 iter_iterable<Components...> set_var(int var_id, flecs::entity_t value) const {
129 return this->iter().set_var(var_id, value);
130 }
131
132#ifdef FLECS_QUERY_PLANS
134 iter_iterable<Components...> set_var(const char *name, flecs::entity_t value) const {
135 return this->iter().set_var(name, value);
136 }
137
139 iter_iterable<Components...> set_var(const char *name, flecs::table_t *value) const {
140 return this->iter().set_var(name, value);
141 }
142
144 iter_iterable<Components...> set_var(const char *name, ecs_table_range_t value) const {
145 return this->iter().set_var(name, value);
146 }
147
149 iter_iterable<Components...> set_var(const char *name, flecs::table_range value) const {
150 return this->iter().set_var(name, value);
151 }
152#endif
153
154#ifdef FLECS_CACHED_QUERIES
156 iter_iterable<Components...> set_group(uint64_t group_id) const {
157 return this->iter().set_group(group_id);
158 }
159
161 template <typename Group>
162 iter_iterable<Components...> set_group() const {
163 return this->iter().template set_group<Group>();
164 }
165#endif
166
168 virtual ~iterable() { }
169protected:
170 friend iter_iterable<Components...>;
171 friend page_iterable<Components...>;
172 friend worker_iterable<Components...>;
173
174 virtual ecs_iter_t get_iter(flecs::world_t *stage) const = 0;
175 virtual ecs_iter_next_action_t next_action() const = 0;
176};
177
179template <typename ... Components>
180struct iter_iterable final : iterable<Components...> {
182 template <typename Iterable>
184 {
185 it_ = it->get_iter(world);
186 next_ = it->next_action();
187 next_each_ = it->next_action();
188 ecs_assert(next_ != nullptr, ECS_INTERNAL_ERROR, nullptr);
189 ecs_assert(next_each_ != nullptr, ECS_INTERNAL_ERROR, nullptr);
190 }
191
193 iter_iterable<Components...>& set_var(int var_id, flecs::entity_t value) {
194 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, nullptr);
195 ecs_iter_set_var(&it_, var_id, value);
196 return *this;
197 }
198
199#ifdef FLECS_QUERY_PLANS
201 iter_iterable<Components...>& set_var(const char *name, flecs::entity_t value) {
202 int var_id = ecs_query_find_var(it_.query, name);
203 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, "%s", name);
204 ecs_iter_set_var(&it_, var_id, value);
205 return *this;
206 }
207
209 iter_iterable<Components...>& set_var(const char *name, flecs::table_t *value) {
210 int var_id = ecs_query_find_var(it_.query, name);
211 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, "%s", name);
212 ecs_iter_set_var_as_table(&it_, var_id, value);
213 return *this;
214 }
215
217 iter_iterable<Components...>& set_var(const char *name, ecs_table_range_t value) {
218 int var_id = ecs_query_find_var(it_.query, name);
219 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, "%s", name);
220 ecs_iter_set_var_as_range(&it_, var_id, &value);
221 return *this;
222 }
223
225 iter_iterable<Components...>& set_var(const char *name, flecs::table_range value) {
226 ecs_table_range_t range;
227 range.table = value.get_table();
228 range.offset = value.offset();
229 range.count = value.count();
230 return set_var(name, range);
231 }
232#endif
233
234# ifdef FLECS_JSON
236# endif
237
239 int32_t count() {
240 int32_t result = 0;
241 while (next_each_(&it_)) {
242 result += it_.count;
243 }
244 return result;
245 }
246
248 bool is_true() {
249 bool result = next_each_(&it_);
250 if (result) {
251 ecs_iter_fini(&it_);
252 }
253 return result;
254 }
255
258 flecs::entity result;
259 if (next_each_(&it_) && it_.count) {
260 result = flecs::entity(it_.world, it_.entities[0]);
261 ecs_iter_fini(&it_);
262 }
263 return result;
264 }
265
266#ifdef FLECS_CACHED_QUERIES
268 iter_iterable<Components...>& set_group(uint64_t group_id) {
269 ecs_iter_set_group(&it_, group_id);
270 return *this;
271 }
272
274 template <typename Group>
275 iter_iterable<Components...>& set_group() {
277 return *this;
278 }
279#endif
280
281protected:
282 ecs_iter_t get_iter(flecs::world_t *world) const override {
283 if (world) {
284 ecs_iter_t result = it_;
285 result.world = world;
286 return result;
287 }
288 return it_;
289 }
290
291 ecs_iter_next_action_t next_action() const override {
292 return next_;
293 }
294
295private:
296 ecs_iter_t it_;
298 ecs_iter_next_action_t next_each_;
299};
300
301template <typename ... Components>
303{
304 return iter_iterable<Components...>(this, world);
305}
306
307template <typename ... Components>
309{
310 return iter_iterable<Components...>(this, it.world());
311}
312
313template <typename ... Components>
315{
316 return iter_iterable<Components...>(this, e.world());
317}
318
320template <typename ... Components>
321struct page_iterable final : iterable<Components...> {
323 template <typename Iterable>
324 page_iterable(int32_t offset, int32_t limit, Iterable *it)
325 : offset_(offset)
326 , limit_(limit)
327 {
328 chain_it_ = it->get_iter(nullptr);
329 }
330
331protected:
332 ecs_iter_t get_iter(flecs::world_t*) const {
333 return ecs_page_iter(&chain_it_, offset_, limit_);
334 }
335
336 ecs_iter_next_action_t next_action() const {
337 return ecs_page_next;
338 }
339
340private:
341 ecs_iter_t chain_it_;
342 int32_t offset_;
343 int32_t limit_;
344};
345
346template <typename ... Components>
348 int32_t offset,
349 int32_t limit)
350{
351 return page_iterable<Components...>(offset, limit, this);
352}
353
355template <typename ... Components>
356struct worker_iterable final : iterable<Components...> {
358 worker_iterable(int32_t index, int32_t count, iterable<Components...> *it)
359 : index_(index)
360 , count_(count)
361 {
362 chain_it_ = it->get_iter(nullptr);
363 }
364
365protected:
366 ecs_iter_t get_iter(flecs::world_t*) const {
367 return ecs_worker_iter(&chain_it_, index_, count_);
368 }
369
370 ecs_iter_next_action_t next_action() const {
371 return ecs_worker_next;
372 }
373
374private:
375 ecs_iter_t chain_it_;
376 int32_t index_;
377 int32_t count_;
378};
379
380template <typename ... Components>
382 int32_t index,
383 int32_t count)
384{
385 return worker_iterable<Components...>(index, count, this);
386}
387
388}
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:671
#define ECS_INTERNAL_ERROR
Internal error code.
Definition log.h:681
ecs_table_t table_t
Table type.
Definition c_types.hpp:23
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
ecs_world_t world_t
World type.
Definition c_types.hpp:18
bool(* ecs_iter_next_action_t)(ecs_iter_t *it)
Function prototype for iterating an iterator.
Definition flecs.h:599
ecs_iter_t ecs_worker_iter(const ecs_iter_t *it, int32_t index, int32_t count)
Create a worker iterator.
void ecs_iter_fini(ecs_iter_t *it)
Clean up iterator resources.
ecs_iter_t ecs_page_iter(const ecs_iter_t *it, int32_t offset, int32_t limit)
Create a paged iterator.
void ecs_iter_set_var(ecs_iter_t *it, int32_t var_id, ecs_entity_t entity)
Set the value for an iterator variable.
bool ecs_worker_next(ecs_iter_t *it)
Progress a worker iterator.
void ecs_iter_set_var_as_table(ecs_iter_t *it, int32_t var_id, const ecs_table_t *table)
Same as ecs_iter_set_var(), but for a table.
bool ecs_page_next(ecs_iter_t *it)
Progress a paged iterator.
void ecs_iter_set_var_as_range(ecs_iter_t *it, int32_t var_id, const ecs_table_range_t *range)
Same as ecs_iter_set_var(), but for a range of entities.
void ecs_iter_set_group(ecs_iter_t *it, uint64_t group_id)
Set the group to iterate for a query iterator.
int32_t ecs_query_find_var(const ecs_query_t *query, const char *name)
Find a variable index.
JSON iterable mixin.
Iterator.
Definition flecs.h:1190
ecs_world_t * real_world
Actual world.
Definition flecs.h:1193
ecs_world_t * world
The world.
Definition flecs.h:1192
const ecs_query_t * query
Query being evaluated.
Definition flecs.h:1226
int32_t count
Number of entities to iterate.
Definition flecs.h:1197
const ecs_entity_t * entities
Entity identifiers.
Definition flecs.h:1198
Entity.
Definition entity.hpp:30
flecs::world world() const
Get the world.
Definition impl.hpp:58
flecs::entity first() const
Get first element from a pair.
Definition impl.hpp:20
Forward declaration of iter_iterable.
Definition iterable.hpp:180
iter_iterable< Components... > & set_var(const char *name, ecs_table_range_t value)
Set query variable by name to a table range (C type).
Definition iterable.hpp:217
iter_iterable< Components... > & set_group()
Limit results to tables with the specified group type (grouped queries only).
Definition iterable.hpp:275
iter_iterable< Components... > & set_var(const char *name, flecs::table_range value)
Set query variable by name to a table range.
Definition iterable.hpp:225
iter_iterable< Components... > & set_group(uint64_t group_id)
Limit results to tables with the specified group ID (grouped queries only).
Definition iterable.hpp:268
flecs::entity first()
Return the first matching entity.
Definition iterable.hpp:257
iter_iterable< Components... > & set_var(const char *name, flecs::table_t *value)
Set query variable by name to a table value.
Definition iterable.hpp:209
iter_iterable(Iterable *it, flecs::world_t *world)
Construct iter_iterable from an iterable and a world.
Definition iterable.hpp:183
iter_iterable< Components... > & set_var(int var_id, flecs::entity_t value)
Set query variable by ID.
Definition iterable.hpp:193
bool is_true()
Return whether the iterator yields at least one result.
Definition iterable.hpp:248
iter_iterable< Components... > & set_var(const char *name, flecs::entity_t value)
Set query variable by name to an entity value.
Definition iterable.hpp:201
int32_t count()
Return the total number of entities in the result.
Definition iterable.hpp:239
Class for iterating over query results.
Definition iter.hpp:68
flecs::world world() const
Get the world associated with the iterator.
Definition iter.hpp:27
Base class for iterable query objects.
Definition iterable.hpp:22
bool is_true() const
Return whether the iterable has any matches.
Definition iterable.hpp:118
iter_iterable< Components... > set_var(const char *name, flecs::entity_t value) const
Set query variable by name to an entity value.
Definition iterable.hpp:134
iter_iterable< Components... > set_group() const
Limit results to tables with the specified group type (grouped queries only).
Definition iterable.hpp:162
iter_iterable< Components... > set_var(int var_id, flecs::entity_t value) const
Set query variable by ID.
Definition iterable.hpp:128
void run(Func &&func) const
Run the iterator.
Definition iterable.hpp:50
flecs::entity first() const
Return the first entity matched by the iterable.
Definition iterable.hpp:123
void each(Func &&func) const
Each iterator.
Definition iterable.hpp:34
virtual ~iterable()
Virtual destructor.
Definition iterable.hpp:168
int32_t count() const
Return the number of entities matched by the iterable.
Definition iterable.hpp:113
iter_iterable< Components... > iter(flecs::entity e) const
Create an iterator.
Definition iterable.hpp:314
page_iterable< Components... > page(int32_t offset, int32_t limit)
Page iterator.
Definition iterable.hpp:347
iter_iterable< Components... > set_var(const char *name, flecs::table_t *value) const
Set query variable by name to a table value.
Definition iterable.hpp:139
iter_iterable< Components... > set_var(const char *name, flecs::table_range value) const
Set query variable by name to a table range.
Definition iterable.hpp:149
iter_iterable< Components... > set_var(const char *name, ecs_table_range_t value) const
Set query variable by name to a table range (C type).
Definition iterable.hpp:144
flecs::entity find(Func &&func) const
Find the first entity matching a condition.
Definition iterable.hpp:62
iter_iterable< Components... > iter(flecs::iter &iter) const
Create an iterator.
Definition iterable.hpp:308
worker_iterable< Components... > worker(int32_t index, int32_t count)
Worker iterator.
Definition iterable.hpp:381
iter_iterable< Components... > iter(flecs::world_t *world=nullptr) const
Create an iterator.
Definition iterable.hpp:302
iter_iterable< Components... > set_group(uint64_t group_id) const
Limit results to tables with the specified group ID (grouped queries only).
Definition iterable.hpp:156
Forward declaration of page_iterable.
Definition iterable.hpp:321
page_iterable(int32_t offset, int32_t limit, Iterable *it)
Construct a page_iterable from an offset, limit, and source iterable.
Definition iterable.hpp:324
Table range.
Definition table.hpp:449
int32_t count() const
Get the number of entities in the range.
Definition table.hpp:474
int32_t offset() const
Get the offset of the range.
Definition table.hpp:469
table_t * get_table() const
Get the table.
Definition table.hpp:430
Forward declaration of worker_iterable.
Definition iterable.hpp:356
worker_iterable(int32_t index, int32_t count, iterable< Components... > *it)
Construct a worker_iterable from an index, count, and source iterable.
Definition iterable.hpp:358
The world.
Definition world.hpp:244