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

| 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
5
6namespace flecs {
7
9template <typename ... Components>
10struct iter_iterable;
11
12/** Forward declaration of page_iterable. */
13template <typename ... Components>
14struct page_iterable;
15
16
17template <typename ... Components>
18struct worker_iterable;
19
21template <typename ... Components>
22 struct 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
123 flecs::entity first() const {
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>
176 struct iter_iterable final : iterable<Components...> {
178 template <typename Iterable>
179 iter_iterable(Iterable *it, flecs::world_t *world)
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, nullptr);
185 ecs_assert(next_each_ != nullptr, ECS_INTERNAL_ERROR, nullptr);
186 }
187
189 iter_iterable<Components...>& set_var(int var_id, flecs::entity_t value) {
190 ecs_assert(var_id != -1, ECS_INVALID_PARAMETER, nullptr);
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
229# include "../mixins/json/iterable.inl"
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
251 flecs::entity first() {
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() {
269 ecs_iter_set_group(&it_, _::type<Group>().id(it_.real_world));
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_;
289 ecs_iter_next_action_t next_;
290 ecs_iter_next_action_t next_each_;
291};
292
293template <typename ... Components>
294 iter_iterable<Components...> iterable<Components...>::iter(flecs::world_t *world) const
295{
296 return iter_iterable<Components...>(this, world);
297}
298
299template <typename ... Components>
300 iter_iterable<Components...> iterable<Components...>::iter(flecs::iter& it) const
301{
302 return iter_iterable<Components...>(this, it.world());
303}
304
305template <typename ... Components>
306 iter_iterable<Components...> iterable<Components...>::iter(flecs::entity e) const
307{
308 return iter_iterable<Components...>(this, e.world());
309}
310
312template <typename ... Components>
313 struct 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>
339 page_iterable<Components...> iterable<Components...>::page(
340 int32_t offset,
341 int32_t limit)
342{
343 return page_iterable<Components...>(offset, limit, this);
344}
345
347template <typename ... Components>
348 struct 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>
373 worker_iterable<Components...> iterable<Components...>::worker(
374 int32_t index,
375 int32_t count)
376{
377 return worker_iterable<Components...>(index, count, this);
378}
379
380}
ecs_assert
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
ECS_INVALID_PARAMETER
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:671
ECS_INTERNAL_ERROR
#define ECS_INTERNAL_ERROR
Internal error code.
Definition log.h:681
ecs_iter_t
struct ecs_iter_t ecs_iter_t
Type used for iterating iterable objects.
Definition flecs.h:471
flecs::component::range
untyped_component & range(double min, double max)
Add a member value range.
Definition untyped_component.inl:240
flecs::table_t
ecs_table_t table_t
Table type.
Definition c_types.hpp:23
flecs::entity_t
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
flecs::world_t
ecs_world_t world_t
World type.
Definition c_types.hpp:18
ecs_iter_next_action_t
bool(* ecs_iter_next_action_t)(ecs_iter_t *it)
Function prototype for iterating an iterator.
Definition flecs.h:591
ecs_worker_iter
ecs_iter_t ecs_worker_iter(const ecs_iter_t *it, int32_t index, int32_t count)
Create a worker iterator.
ecs_iter_fini
void ecs_iter_fini(ecs_iter_t *it)
Clean up iterator resources.
ecs_page_iter
ecs_iter_t ecs_page_iter(const ecs_iter_t *it, int32_t offset, int32_t limit)
Create a paged iterator.
ecs_iter_set_var
void ecs_iter_set_var(ecs_iter_t *it, int32_t var_id, ecs_entity_t entity)
Set the value for an iterator variable.
ecs_worker_next
bool ecs_worker_next(ecs_iter_t *it)
Progress a worker iterator.
ecs_iter_set_var_as_table
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.
ecs_page_next
bool ecs_page_next(ecs_iter_t *it)
Progress a paged iterator.
ecs_iter_set_var_as_range
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.
ecs_iter_set_group
void ecs_iter_set_group(ecs_iter_t *it, uint64_t group_id)
Set the group to iterate for a query iterator.
ecs_query_find_var
int32_t ecs_query_find_var(const ecs_query_t *query, const char *name)
Find a variable index.
iterable.inl
JSON iterable mixin.
ecs_iter_t
Iterator.
Definition flecs.h:1170
ecs_iter_t::world
ecs_world_t * world
The world.
Definition flecs.h:1172
flecs::_::each_delegate
Definition delegate.hpp:220
flecs::_::find_delegate
Definition delegate.hpp:389
flecs::_::run_delegate
Definition delegate.hpp:544
flecs::_::type
Definition flecs.hpp:39
flecs::entity
Entity.
Definition entity.hpp:30
flecs::id::world
flecs::world world() const
Get the world.
Definition impl.hpp:58
flecs::id::first
flecs::entity first() const
Get first element from a pair.
Definition impl.hpp:20
flecs::iter_iterable
Forward declaration of iter_iterable.
Definition iterable.hpp:176
flecs::iter_iterable::set_var
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
flecs::iter_iterable::set_group
iter_iterable< Components... > & set_group()
Limit results to tables with the specified group type (grouped queries only).
Definition iterable.hpp:268
flecs::iter_iterable::set_var
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
flecs::iter_iterable::set_group
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::iter_iterable::first
flecs::entity first()
Return the first matching entity.
Definition iterable.hpp:251
flecs::iter_iterable::set_var
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
flecs::iter_iterable::iter_iterable
iter_iterable(Iterable *it, flecs::world_t *world)
Construct iter_iterable from an iterable and a world.
Definition iterable.hpp:179
flecs::iter_iterable::set_var
iter_iterable< Components... > & set_var(int var_id, flecs::entity_t value)
Set query variable by ID.
Definition iterable.hpp:189
flecs::iter_iterable::is_true
bool is_true()
Return whether the iterator yields at least one result.
Definition iterable.hpp:242
flecs::iter_iterable::set_var
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
flecs::iter_iterable::count
int32_t count()
Return the total number of entities in the result.
Definition iterable.hpp:233
flecs::iter
Class for iterating over query results.
Definition iter.hpp:68
flecs::iter::world
flecs::world world() const
Get the world associated with the iterator.
Definition iter.hpp:27
flecs::iterable
Base class for iterable query objects.
Definition iterable.hpp:22
flecs::iterable::is_true
bool is_true() const
Return whether the iterable has any matches.
Definition iterable.hpp:118
flecs::iterable::set_var
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
flecs::iterable::set_group
iter_iterable< Components... > set_group() const
Limit results to tables with the specified group type (grouped queries only).
Definition iterable.hpp:159
flecs::iterable::set_var
iter_iterable< Components... > set_var(int var_id, flecs::entity_t value) const
Set query variable by ID.
Definition iterable.hpp:128
flecs::iterable::run
void run(Func &&func) const
Run the iterator.
Definition iterable.hpp:50
flecs::iterable::first
flecs::entity first() const
Return the first entity matched by the iterable.
Definition iterable.hpp:123
flecs::iterable::each
void each(Func &&func) const
Each iterator.
Definition iterable.hpp:34
flecs::iterable::~iterable
virtual ~iterable()
Virtual destructor.
Definition iterable.hpp:164
flecs::iterable< Components... >::count
int32_t count() const
Definition iterable.hpp:113
flecs::iterable::page
page_iterable< Components... > page(int32_t offset, int32_t limit)
Page iterator.
Definition iterable.hpp:339
flecs::iterable::set_var
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
flecs::iterable::set_var
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
flecs::iterable::set_var
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::iterable::find
flecs::entity find(Func &&func) const
Find the first entity matching a condition.
Definition iterable.hpp:62
flecs::iterable::worker
worker_iterable< Components... > worker(int32_t index, int32_t count)
Worker iterator.
Definition iterable.hpp:373
flecs::iterable::iter
iter_iterable< Components... > iter(flecs::world_t *world=nullptr) const
Create an iterator.
Definition iterable.hpp:294
flecs::iterable::set_group
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
flecs::page_iterable
Forward declaration of page_iterable.
Definition iterable.hpp:313
flecs::page_iterable::page_iterable
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
flecs::table_range
Table range.
Definition table.hpp:449
flecs::table_range::count
int32_t count() const
Get the number of entities in the range.
Definition table.hpp:474
flecs::table_range::offset
int32_t offset() const
Get the offset of the range.
Definition table.hpp:469
flecs::table::get_table
table_t * get_table() const
Get the table.
Definition table.hpp:430
flecs::worker_iterable
Forward declaration of worker_iterable.
Definition iterable.hpp:348
flecs::worker_iterable::worker_iterable
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
flecs::world
The world.
Definition world.hpp:246