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
133 iter_iterable<Components...> set_var(const char *name, flecs::entity_t value) const {
134 return this->iter().set_var(name, value);
135 }
136
138 iter_iterable<Components...> set_var(const char *name, flecs::table_t *value) const {
139 return this->iter().set_var(name, value);
140 }
141
143 iter_iterable<Components...> set_var(const char *name, ecs_table_range_t value) const {
144 return this->iter().set_var(name, value);
145 }
146
148 iter_iterable<Components...> set_var(const char *name, flecs::table_range value) const {
149 return this->iter().set_var(name, value);
150 }
151
153 iter_iterable<Components...> set_group(uint64_t group_id) const {
154 return this->iter().set_group(group_id);
155 }
156
158 template <typename Group>
159 iter_iterable<Components...> set_group() const {
160 return this->iter().template set_group<Group>();
161 }
162
164 virtual ~iterable() { }
165protected:
166 friend iter_iterable<Components...>;
167 friend page_iterable<Components...>;
168 friend worker_iterable<Components...>;
169
170 virtual ecs_iter_t get_iter(flecs::world_t *stage) const = 0;
171 virtual ecs_iter_next_action_t next_action() const = 0;
172};
173
175template <typename ... Components>
176struct iter_iterable final : iterable<Components...> {
178 template <typename Iterable>
180 {
181 it_ = it->get_iter(world);
182 next_ = it->next_action();
183 next_each_ = it->next_action();
184 ecs_assert(next_ != nullptr, ECS_INTERNAL_ERROR, NULL);
185 ecs_assert(next_each_ != nullptr, ECS_INTERNAL_ERROR, NULL);
186 }
187
189 iter_iterable<Components...>& set_var(int var_id, flecs::entity_t value) {
190 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, 0);
191 ecs_iter_set_var(&it_, var_id, value);
192 return *this;
193 }
194
196 iter_iterable<Components...>& set_var(const char *name, flecs::entity_t value) {
197 int var_id = ecs_query_find_var(it_.query, name);
198 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, "%s", name);
199 ecs_iter_set_var(&it_, var_id, value);
200 return *this;
201 }
202
204 iter_iterable<Components...>& set_var(const char *name, flecs::table_t *value) {
205 int var_id = ecs_query_find_var(it_.query, name);
206 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, "%s", name);
207 ecs_iter_set_var_as_table(&it_, var_id, value);
208 return *this;
209 }
210
212 iter_iterable<Components...>& set_var(const char *name, ecs_table_range_t value) {
213 int var_id = ecs_query_find_var(it_.query, name);
214 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, "%s", name);
215 ecs_iter_set_var_as_range(&it_, var_id, &value);
216 return *this;
217 }
218
220 iter_iterable<Components...>& set_var(const char *name, flecs::table_range value) {
221 ecs_table_range_t range;
222 range.table = value.get_table();
223 range.offset = value.offset();
224 range.count = value.count();
225 return set_var(name, range);
226 }
227
228# ifdef FLECS_JSON
230# endif
231
233 int32_t count() {
234 int32_t result = 0;
235 while (next_each_(&it_)) {
236 result += it_.count;
237 }
238 return result;
239 }
240
242 bool is_true() {
243 bool result = next_each_(&it_);
244 if (result) {
245 ecs_iter_fini(&it_);
246 }
247 return result;
248 }
249
252 flecs::entity result;
253 if (next_each_(&it_) && it_.count) {
254 result = flecs::entity(it_.world, it_.entities[0]);
255 ecs_iter_fini(&it_);
256 }
257 return result;
258 }
259
261 iter_iterable<Components...>& set_group(uint64_t group_id) {
262 ecs_iter_set_group(&it_, group_id);
263 return *this;
264 }
265
267 template <typename Group>
268 iter_iterable<Components...>& set_group() {
270 return *this;
271 }
272
273protected:
274 ecs_iter_t get_iter(flecs::world_t *world) const override {
275 if (world) {
276 ecs_iter_t result = it_;
277 result.world = world;
278 return result;
279 }
280 return it_;
281 }
282
283 ecs_iter_next_action_t next_action() const override {
284 return next_;
285 }
286
287private:
288 ecs_iter_t it_;
290 ecs_iter_next_action_t next_each_;
291};
292
293template <typename ... Components>
295{
296 return iter_iterable<Components...>(this, world);
297}
298
299template <typename ... Components>
301{
302 return iter_iterable<Components...>(this, it.world());
303}
304
305template <typename ... Components>
307{
308 return iter_iterable<Components...>(this, e.world());
309}
310
312template <typename ... Components>
313struct page_iterable final : iterable<Components...> {
315 template <typename Iterable>
316 page_iterable(int32_t offset, int32_t limit, Iterable *it)
317 : offset_(offset)
318 , limit_(limit)
319 {
320 chain_it_ = it->get_iter(nullptr);
321 }
322
323protected:
324 ecs_iter_t get_iter(flecs::world_t*) const {
325 return ecs_page_iter(&chain_it_, offset_, limit_);
326 }
327
328 ecs_iter_next_action_t next_action() const {
329 return ecs_page_next;
330 }
331
332private:
333 ecs_iter_t chain_it_;
334 int32_t offset_;
335 int32_t limit_;
336};
337
338template <typename ... Components>
340 int32_t offset,
341 int32_t limit)
342{
343 return page_iterable<Components...>(offset, limit, this);
344}
345
347template <typename ... Components>
348struct worker_iterable final : iterable<Components...> {
350 worker_iterable(int32_t index, int32_t count, iterable<Components...> *it)
351 : index_(index)
352 , count_(count)
353 {
354 chain_it_ = it->get_iter(nullptr);
355 }
356
357protected:
358 ecs_iter_t get_iter(flecs::world_t*) const {
359 return ecs_worker_iter(&chain_it_, index_, count_);
360 }
361
362 ecs_iter_next_action_t next_action() const {
363 return ecs_worker_next;
364 }
365
366private:
367 ecs_iter_t chain_it_;
368 int32_t index_;
369 int32_t count_;
370};
371
372template <typename ... Components>
374 int32_t index,
375 int32_t count)
376{
377 return worker_iterable<Components...>(index, count, this);
378}
379
380}
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:661
#define ECS_INTERNAL_ERROR
Internal error code.
Definition log.h:671
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:587
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:1166
ecs_world_t * real_world
Actual world.
Definition flecs.h:1169
ecs_world_t * world
The world.
Definition flecs.h:1168
const ecs_query_t * query
Query being evaluated.
Definition flecs.h:1199
int32_t count
Number of entities to iterate.
Definition flecs.h:1173
const ecs_entity_t * entities
Entity identifiers.
Definition flecs.h:1174
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:176
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:212
iter_iterable< Components... > & set_group()
Limit results to tables with the specified group type (grouped queries only).
Definition iterable.hpp:268
iter_iterable< Components... > & set_var(const char *name, flecs::table_range value)
Set query variable by name to a table range.
Definition iterable.hpp:220
iter_iterable< Components... > & set_group(uint64_t group_id)
Limit results to tables with the specified group ID (grouped queries only).
Definition iterable.hpp:261
flecs::entity first()
Return the first matching entity.
Definition iterable.hpp:251
iter_iterable< Components... > & set_var(const char *name, flecs::table_t *value)
Set query variable by name to a table value.
Definition iterable.hpp:204
iter_iterable(Iterable *it, flecs::world_t *world)
Construct iter_iterable from an iterable and a world.
Definition iterable.hpp:179
iter_iterable< Components... > & set_var(int var_id, flecs::entity_t value)
Set query variable by ID.
Definition iterable.hpp:189
bool is_true()
Return whether the iterator yields at least one result.
Definition iterable.hpp:242
iter_iterable< Components... > & set_var(const char *name, flecs::entity_t value)
Set query variable by name to an entity value.
Definition iterable.hpp:196
int32_t count()
Return the total number of entities in the result.
Definition iterable.hpp:233
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:133
iter_iterable< Components... > set_group() const
Limit results to tables with the specified group type (grouped queries only).
Definition iterable.hpp:159
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:164
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:306
page_iterable< Components... > page(int32_t offset, int32_t limit)
Page iterator.
Definition iterable.hpp:339
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:138
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:148
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:143
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:300
worker_iterable< Components... > worker(int32_t index, int32_t count)
Worker iterator.
Definition iterable.hpp:373
iter_iterable< Components... > iter(flecs::world_t *world=nullptr) const
Create an iterator.
Definition iterable.hpp:294
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:153
Forward declaration of page_iterable.
Definition iterable.hpp:313
page_iterable(int32_t offset, int32_t limit, Iterable *it)
Construct a page_iterable from an offset, limit, and source iterable.
Definition iterable.hpp:316
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:348
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:350
The world.
Definition world.hpp:246