Flecs v4.1
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
iter.hpp
Go to the documentation of this file.
1
6#pragma once
7
16namespace flecs
17{
18
20
21namespace _ {
22
24
29template <typename T>
31{
32 explicit range_iterator(T value)
33 : value_(value){}
34
35 bool operator!=(range_iterator const& other) const
36 {
37 return value_ != other.value_;
38 }
39
40 T const& operator*() const
41 {
42 return value_;
43 }
44
45 range_iterator& operator++()
46 {
47 ++value_;
48 return *this;
49 }
50
51private:
52 T value_;
53};
54
55} // namespace _
56
57} // namespace flecs
58
59namespace flecs
60{
61
63
68struct iter {
69private:
71
72public:
78 iter(ecs_iter_t *it) : iter_(it) { }
79
82 return row_iterator(0);
83 }
84
86 row_iterator end() const {
87 return row_iterator(static_cast<size_t>(iter_->count));
88 }
89
91 flecs::entity system() const;
92
94 flecs::entity event() const;
95
97 flecs::id event_id() const;
98
100 flecs::world world() const;
101
103 const flecs::iter_t* c_ptr() const {
104 return iter_;
105 }
106
111 size_t count() const {
112 ecs_check(iter_->flags & EcsIterIsValid, ECS_INVALID_PARAMETER,
113 "operation invalid before calling next()");
114 return static_cast<size_t>(iter_->count);
115 error:
116 return 0;
117 }
118
124 return iter_->delta_time;
125 }
126
132 return iter_->delta_system_time;
133 }
134
136 flecs::type type() const;
137
139 flecs::table table() const;
140
146
149
153 void* ctx() {
154 return iter_->ctx;
155 }
156
160 template <typename T>
161 T* ctx() {
162 return static_cast<T*>(iter_->ctx);
163 }
164
168 void* param() {
169 return iter_->param;
170 }
171
175 template <typename T>
176 T* param() {
177 /* TODO: type check */
178 return static_cast<T*>(iter_->param);
179 }
180
186 flecs::entity entity(size_t row) const;
187
193 bool is_self(int8_t index) const {
194 return ecs_field_is_self(iter_, index);
195 }
196
202 bool is_set(int8_t index) const {
203 return ecs_field_is_set(iter_, index);
204 }
205
211 bool is_readonly(int8_t index) const {
212 return ecs_field_is_readonly(iter_, index);
213 }
214
219 int32_t field_count() const {
220 return iter_->field_count;
221 }
222
228 size_t size(int8_t index) const {
229 return ecs_field_size(iter_, index);
230 }
231
237 flecs::entity src(int8_t index) const;
238
244 flecs::id id(int8_t index) const;
245
252 flecs::id pair(int8_t index) const;
253
259 int32_t column_index(int8_t index) const {
260 return ecs_field_column(iter_, index);
261 }
262
267 int8_t term_index() const {
268 return iter_->term_index;
269 }
270
276 char *s = ecs_iter_str(iter_);
277 return flecs::string(s);
278 }
279
292 template <typename T, typename A = actual_type_t<T>, if_t<is_const_v<T>> = 0>
293 flecs::field<A> field(int8_t index) const;
294
307 template <typename T, typename A = actual_type_t<T>, if_not_t<is_const_v<T>> = 0>
308 flecs::field<A> field(int8_t index) const;
309
320 flecs::untyped_field field(int8_t index) const {
321 ecs_assert(!(iter_->flags & EcsIterCppEach) ||
322 ecs_field_src(iter_, index) != 0, ECS_INVALID_OPERATION,
323 "cannot .field from .each, use .field_at(%d, row) instead", index);
324 return get_unchecked_field(index);
325 }
326
334 void* field_at(int8_t index, size_t row) const {
335 if (iter_->row_fields & (1llu << index)) {
336 return get_unchecked_field_at(index, row)[0];
337 } else {
338 return get_unchecked_field(index)[row];
339 }
340 }
341
350 template <typename T, typename A = actual_type_t<T>, if_t< is_const_v<T> > = 0>
351 const A& field_at(int8_t index, size_t row) const {
352 if (iter_->row_fields & (1llu << index)) {
353 return get_field_at<A>(index, row)[0];
354 } else {
355 return get_field<A>(index)[row];
356 }
357 }
358
367 template <typename T, typename A = actual_type_t<T>, if_not_t< is_const_v<T> > = 0>
368 A& field_at(int8_t index, size_t row) const {
369 ecs_assert(!ecs_field_is_readonly(iter_, index),
371 if (iter_->row_fields & (1llu << index)) {
372 return get_field_at<A>(index, row)[0];
373 } else {
374 return get_field<A>(index)[row];
375 }
376 }
377
384 iter_->entities, static_cast<size_t>(iter_->count), false);
385 }
386
392 bool changed() {
393 return ecs_iter_changed(iter_);
394 }
395
403 void skip() {
404 ecs_iter_skip(iter_);
405 }
406
411 uint64_t group_id() const {
412 return ecs_iter_get_group(iter_);
413 }
414
421 flecs::entity get_var(int var_id) const;
422
429 flecs::entity get_var(const char *name) const;
430
439 bool next() {
440 if (iter_->flags & EcsIterIsValid && iter_->table) {
441 ECS_TABLE_UNLOCK(iter_->world, iter_->table);
442 }
443 bool result = iter_->next(iter_);
444 iter_->flags |= EcsIterIsValid;
445 if (result && iter_->table) {
446 ECS_TABLE_LOCK(iter_->world, iter_->table);
447 }
448 return result;
449 }
450
455 void each() {
456 iter_->callback(iter_);
457 }
458
464 template <typename Func>
465 void targets(int8_t index, const Func& func);
466
476 void fini() {
477 if (iter_->flags & EcsIterIsValid && iter_->table) {
478 ECS_TABLE_UNLOCK(iter_->world, iter_->table);
479 }
480 ecs_iter_fini(iter_);
481 }
482
483private:
484 /* Get field, check if correct type is used. */
485 template <typename T, typename A = actual_type_t<T>>
486 flecs::field<T> get_field(int8_t index) const {
487
488#ifndef FLECS_NDEBUG
489 ecs_entity_t term_id = ecs_field_id(iter_, index);
490 ecs_assert(ECS_HAS_ID_FLAG(term_id, PAIR) ||
491 term_id == _::type<T>::id(iter_->world),
493#endif
494
495 size_t count;
496 bool is_shared = !ecs_field_is_self(iter_, index);
497
498 /* If a shared field is retrieved with field(), there will only be a
499 * single value. Ensure that the application does not accidentally read
500 * out of bounds. */
501 if (is_shared) {
502 count = 1;
503 } else {
504 /* If field is owned, there will be as many values as there are
505 * entities. */
506 count = static_cast<size_t>(iter_->count);
507 }
508
509 return flecs::field<A>(
510 static_cast<T*>(ecs_field_w_size(iter_, sizeof(A), index)),
511 count, is_shared);
512 }
513
514 /* Get field, check if correct type is used. */
515 template <typename T, typename A = actual_type_t<T>>
516 flecs::field<T> get_field_at(int8_t index, int32_t row) const {
517
518#ifndef FLECS_NDEBUG
519 ecs_entity_t term_id = ecs_field_id(iter_, index);
520 ecs_assert(ECS_HAS_ID_FLAG(term_id, PAIR) ||
521 term_id == _::type<T>::id(iter_->world),
523#endif
524
525 return flecs::field<A>(
526 static_cast<T*>(ecs_field_at_w_size(iter_, sizeof(A), index, row)),
527 1, false);
528 }
529
530 flecs::untyped_field get_unchecked_field(int8_t index) const {
531 size_t count;
532 size_t size = ecs_field_size(iter_, index);
533 bool is_shared = !ecs_field_is_self(iter_, index);
534
535 /* If a shared field is retrieved with field(), there will only be a
536 * single value. Ensure that the application does not accidentally read
537 * out of bounds. */
538 if (is_shared) {
539 count = 1;
540 } else {
541 /* If field is owned, there will be as many values as there are
542 * entities. */
543 count = static_cast<size_t>(iter_->count);
544 }
545
547 ecs_field_w_size(iter_, size, index), size, count, is_shared);
548 }
549
550 flecs::untyped_field get_unchecked_field_at(int8_t index, size_t row) const {
551 size_t size = ecs_field_size(iter_, index);
553 ecs_field_at_w_size(iter_, size, index, static_cast<int32_t>(row)),
554 size, 1, false);
555 }
556
557 flecs::iter_t *iter_;
558};
559
560} // namespace flecs
561
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_ACCESS_VIOLATION
Access violation error code.
Definition log.h:709
#define ECS_INVALID_OPERATION
Invalid operation error code.
Definition log.h:659
#define ECS_COLUMN_TYPE_MISMATCH
Column type mismatch error code.
Definition log.h:717
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:661
#define ecs_check(condition, error_code,...)
Check.
Definition log.h:517
ecs_id_t ecs_entity_t
An entity identifier.
Definition flecs.h:381
ecs_entity_t ecs_field_src(const ecs_iter_t *it, int8_t index)
Return the field source.
bool ecs_iter_changed(ecs_iter_t *it)
Return whether the current iterator result has changed.
bool ecs_field_is_readonly(const ecs_iter_t *it, int8_t index)
Test whether the field is read-only.
void ecs_iter_fini(ecs_iter_t *it)
Clean up iterator resources.
char * ecs_iter_str(const ecs_iter_t *it)
Convert an iterator to a string.
void * ecs_field_at_w_size(const ecs_iter_t *it, size_t size, int8_t index, int32_t row)
Get data for a field at a specified row.
ecs_id_t ecs_field_id(const ecs_iter_t *it, int8_t index)
Return the ID matched for a field.
bool ecs_field_is_set(const ecs_iter_t *it, int8_t index)
Test whether a field is set.
bool ecs_field_is_self(const ecs_iter_t *it, int8_t index)
Test whether the field is matched on self.
int32_t ecs_field_column(const ecs_iter_t *it, int8_t index)
Return the index of a matched table column.
uint64_t ecs_iter_get_group(const ecs_iter_t *it)
Return the group ID for the currently iterated result.
void * ecs_field_w_size(const ecs_iter_t *it, size_t size, int8_t index)
Get data for a field.
size_t ecs_field_size(const ecs_iter_t *it, int8_t index)
Return the field type size.
#define ecs_ftime_t
Customizable precision for scalar time values.
Definition flecs.h:59
void ecs_iter_skip(ecs_iter_t *it)
Skip a table while iterating.
Iterator.
Definition flecs.h:1166
void * param
Param passed to ecs_run().
Definition flecs.h:1202
ecs_flags32_t flags
Iterator flags.
Definition flecs.h:1216
void * ctx
System context.
Definition flecs.h:1203
ecs_table_t * table
Current table.
Definition flecs.h:1178
ecs_world_t * world
The world.
Definition flecs.h:1168
ecs_flags32_t row_fields
Fields that must be obtained with field_at.
Definition flecs.h:1185
float delta_system_time
Time elapsed since last system invocation.
Definition flecs.h:1210
int8_t term_index
Index of the term that emitted an event.
Definition flecs.h:1196
float delta_time
Time elapsed since last frame.
Definition flecs.h:1209
ecs_iter_action_t callback
Callback of system or observer.
Definition flecs.h:1222
int8_t field_count
Number of fields in the iterator.
Definition flecs.h:1195
int32_t count
Number of entities to iterate.
Definition flecs.h:1173
ecs_iter_next_action_t next
Function to progress iterator.
Definition flecs.h:1221
const ecs_entity_t * entities
Entity identifiers.
Definition flecs.h:1174
Iterate over an integer range (used to iterate over entity range).
Definition iter.hpp:31
Entity.
Definition entity.hpp:30
Wrapper class around a field.
Definition field.hpp:61
Class that wraps around a flecs::id_t.
Definition decl.hpp:27
Class for iterating over query results.
Definition iter.hpp:68
flecs::id id(int8_t index) const
Obtain the ID matched for the field.
Definition iter.hpp:44
size_t size(int8_t index) const
Size of the field data type.
Definition iter.hpp:228
flecs::field< A > field(int8_t index) const
Get read-only access to field data.
Definition iter.hpp:80
flecs::entity event() const
Get the event entity associated with the iterator.
Definition iter.hpp:17
const A & field_at(int8_t index, size_t row) const
Get const reference to field at row.
Definition iter.hpp:351
flecs::table table() const
Get the table for the current iterator result.
Definition iter.hpp:63
bool is_self(int8_t index) const
Return whether the field is matched on self.
Definition iter.hpp:193
flecs::string str() const
Convert current iterator result to string.
Definition iter.hpp:275
flecs::type type() const
Get the type of the iterated table.
Definition iter.hpp:58
int32_t field_count() const
Number of fields in the iterator.
Definition iter.hpp:219
ecs_ftime_t delta_system_time() const
Get the time elapsed since the last system invocation.
Definition iter.hpp:131
int32_t column_index(int8_t index) const
Obtain the column index for the field.
Definition iter.hpp:259
void * param()
Access param.
Definition iter.hpp:168
row_iterator begin() const
Get an iterator to the beginning of the entity range.
Definition iter.hpp:81
row_iterator end() const
Get an iterator to the end of the entity range.
Definition iter.hpp:86
void * field_at(int8_t index, size_t row) const
Get pointer to field at row.
Definition iter.hpp:334
ecs_ftime_t delta_time() const
Get the time elapsed since the last frame.
Definition iter.hpp:123
bool is_readonly(int8_t index) const
Return whether the field is readonly.
Definition iter.hpp:211
flecs::table other_table() const
Get the other table for the current iterator result.
Definition iter.hpp:68
const flecs::iter_t * c_ptr() const
Get a pointer to the underlying C iterator object.
Definition iter.hpp:103
bool changed()
Check if the current table has changed since the last iteration.
Definition iter.hpp:392
int8_t term_index() const
Obtain the term that triggered an observer.
Definition iter.hpp:267
T * ctx()
Access ctx.
Definition iter.hpp:161
void fini()
Free iterator resources.
Definition iter.hpp:476
bool is_set(int8_t index) const
Return whether the field is set.
Definition iter.hpp:202
A & field_at(int8_t index, size_t row) const
Get mutable reference to field at row.
Definition iter.hpp:368
void * ctx()
Access ctx.
Definition iter.hpp:153
flecs::entity entity(size_t row) const
Obtain a mutable handle to the entity being iterated over.
Definition iter.hpp:32
void each()
Forward to each().
Definition iter.hpp:455
flecs::untyped_field field(int8_t index) const
Get unchecked access to field data.
Definition iter.hpp:320
flecs::id pair(int8_t index) const
Obtain the pair ID matched for the field.
Definition iter.hpp:49
flecs::id event_id() const
Get the event ID associated with the iterator.
Definition iter.hpp:22
flecs::entity get_var(int var_id) const
Get value of variable by ID.
Definition iter.hpp:101
size_t count() const
Get the number of entities to iterate over.
Definition iter.hpp:111
flecs::field< const flecs::entity_t > entities() const
Get read-only access to entity IDs.
Definition iter.hpp:382
uint64_t group_id() const
Return the group ID for the current table (grouped queries only).
Definition iter.hpp:411
iter(ecs_iter_t *it)
Construct iterator from C iterator object.
Definition iter.hpp:78
T * param()
Access param.
Definition iter.hpp:176
flecs::table_range range() const
Get the table range for the current iterator result.
Definition iter.hpp:73
void targets(int8_t index, const Func &func)
Iterate targets for pair field.
Definition iter.hpp:119
flecs::entity src(int8_t index) const
Obtain the field source (0 if This).
Definition iter.hpp:39
void skip()
Skip current table.
Definition iter.hpp:403
bool next()
Progress iterator.
Definition iter.hpp:439
flecs::world world() const
Get the world associated with the iterator.
Definition iter.hpp:27
flecs::entity system() const
Get the system entity associated with the iterator.
Definition iter.hpp:12
Owned string wrapper.
Definition string.hpp:15
Table range.
Definition table.hpp:449
Table.
Definition table.hpp:23
Type class.
Definition type.hpp:21
Unsafe wrapper class around a field.
Definition field.hpp:26
The world.
Definition world.hpp:246