Flecs v3.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
26 untyped_column(void* array, size_t size, size_t count, bool is_shared = false)
27 : m_array(array)
28 , m_size(size)
29 , m_count(count)
30 , m_is_shared(is_shared) {}
31
38 void* operator[](size_t index) const {
39 ecs_assert(index < m_count, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
40 ecs_assert(!m_is_shared, ECS_INVALID_PARAMETER, NULL);
41 return ECS_OFFSET(m_array, m_size * index);
42 }
43
44protected:
45 void* m_array;
46 size_t m_size;
47 size_t m_count;
48 bool m_is_shared;
49};
50
57template <typename T>
58struct column {
59 static_assert(std::is_empty<T>::value == false,
60 "invalid type for column, cannot iterate empty type");
61
68 column(T* array, size_t count, bool is_shared = false)
69 : m_array(array)
70 , m_count(count)
71 , m_is_shared(is_shared) {}
72
79
86 T& operator[](size_t index) const {
87 ecs_assert(index < m_count, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
88 ecs_assert(!index || !m_is_shared, ECS_INVALID_PARAMETER, NULL);
89 ecs_assert(m_array != nullptr, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
90 return m_array[index];
91 }
92
98 T& operator*() const {
99 ecs_assert(m_array != nullptr, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
100 return *m_array;
101 }
102
108 T* operator->() const {
109 ecs_assert(m_array != nullptr, ECS_COLUMN_INDEX_OUT_OF_RANGE, NULL);
110 return m_array;
111 }
112
113protected:
114 T* m_array;
115 size_t m_count;
116 bool m_is_shared;
117};
118
119
121
122namespace _ {
123
125
130template <typename T>
132{
133 explicit range_iterator(T value)
134 : m_value(value){}
135
136 bool operator!=(range_iterator const& other) const
137 {
138 return m_value != other.m_value;
139 }
140
141 T const& operator*() const
142 {
143 return m_value;
144 }
145
146 range_iterator& operator++()
147 {
148 ++m_value;
149 return *this;
150 }
151
152private:
153 T m_value;
154};
155
156} // namespace _
157
158} // namespace flecs
159
160namespace flecs
161{
162
164
169struct iter {
170private:
172
173public:
179 iter(ecs_iter_t *it) : m_iter(it) {
180 m_begin = 0;
181 m_end = static_cast<std::size_t>(it->count);
182 }
183
184 row_iterator begin() const {
185 return row_iterator(m_begin);
186 }
187
188 row_iterator end() const {
189 return row_iterator(m_end);
190 }
191
192 flecs::entity system() const;
193
194 flecs::entity event() const;
195
196 flecs::id event_id() const;
197
198 flecs::world world() const;
199
200 const flecs::iter_t* c_ptr() const {
201 return m_iter;
202 }
203
204 size_t count() const {
205 return static_cast<size_t>(m_iter->count);
206 }
207
208 ecs_ftime_t delta_time() const {
209 return m_iter->delta_time;
210 }
211
212 ecs_ftime_t delta_system_time() const {
213 return m_iter->delta_system_time;
214 }
215
216 flecs::type type() const;
217
218 flecs::table table() const;
219
220 flecs::table_range range() const;
221
223 bool has_module() const {
224 return ecs_table_has_module(m_iter->table);
225 }
226
230 void* ctx() {
231 return m_iter->ctx;
232 }
233
237 template <typename T>
238 T* ctx() {
239 return static_cast<T*>(m_iter->ctx);
240 }
241
245 void* param() {
246 return m_iter->param;
247 }
248
252 template <typename T>
253 T* param() {
254 /* TODO: type check */
255 return static_cast<T*>(m_iter->param);
256 }
257
262 flecs::entity entity(size_t row) const;
263
268 bool is_self(int32_t index) const {
269 return ecs_field_is_self(m_iter, index);
270 }
271
276 bool is_set(int32_t index) const {
277 return ecs_field_is_set(m_iter, index);
278 }
279
284 bool is_readonly(int32_t index) const {
285 return ecs_field_is_readonly(m_iter, index);
286 }
287
290 int32_t field_count() const {
291 return m_iter->field_count;
292 }
293
298 size_t size(int32_t index) const {
299 return ecs_field_size(m_iter, index);
300 }
301
306 flecs::entity src(int32_t index) const;
307
312 flecs::entity id(int32_t index) const;
313
319 flecs::id pair(int32_t index) const;
320
324 char *s = ecs_iter_str(m_iter);
325 return flecs::string(s);
326 }
327
336 template <typename T, typename A = actual_type_t<T>,
337 typename std::enable_if<std::is_const<T>::value, void>::type* = nullptr>
338 flecs::column<A> field(int32_t index) const {
339 return get_field<A>(index);
340 }
341
350 template <typename T, typename A = actual_type_t<T>,
351 typename std::enable_if<
352 std::is_const<T>::value == false, void>::type* = nullptr>
353 flecs::column<A> field(int32_t index) const {
354 ecs_assert(!ecs_field_is_readonly(m_iter, index),
355 ECS_ACCESS_VIOLATION, NULL);
356 return get_field<A>(index);
357 }
358
365 flecs::untyped_column field(int32_t index) const {
366 return get_unchecked_field(index);
367 }
368
370 int32_t table_count() const {
371 return m_iter->table_count;
372 }
373
376 bool changed() {
377 return ecs_query_changed(nullptr, m_iter);
378 }
379
387 void skip() {
388 ecs_query_skip(m_iter);
389 }
390
391 /* Return group id for current table (grouped queries only) */
392 uint64_t group_id() const {
393 return m_iter->group_id;
394 }
395
396#ifdef FLECS_RULES
400 flecs::entity get_var(int var_id) const;
401
405 flecs::entity get_var(const char *name) const;
406#endif
407
408private:
409 /* Get field, check if correct type is used */
410 template <typename T, typename A = actual_type_t<T>>
411 flecs::column<T> get_field(int32_t index) const {
412
413#ifndef FLECS_NDEBUG
414 ecs_entity_t term_id = ecs_field_id(m_iter, index);
415 ecs_assert(ECS_HAS_ID_FLAG(term_id, PAIR) ||
416 term_id == _::cpp_type<T>::id(m_iter->world),
417 ECS_COLUMN_TYPE_MISMATCH, NULL);
418#endif
419
420 size_t count;
421 bool is_shared = !ecs_field_is_self(m_iter, index);
422
423 /* If a shared column is retrieved with 'column', there will only be a
424 * single value. Ensure that the application does not accidentally read
425 * out of bounds. */
426 if (is_shared) {
427 count = 1;
428 } else {
429 /* If column is owned, there will be as many values as there are
430 * entities. */
431 count = static_cast<size_t>(m_iter->count);
432 }
433
434 return flecs::column<A>(
435 static_cast<T*>(ecs_field_w_size(m_iter, sizeof(A), index)),
436 count, is_shared);
437 }
438
439 flecs::untyped_column get_unchecked_field(int32_t index) const {
440 size_t count;
441 size_t size = ecs_field_size(m_iter, index);
442 bool is_shared = !ecs_field_is_self(m_iter, index);
443
444 /* If a shared column is retrieved with 'column', there will only be a
445 * single value. Ensure that the application does not accidentally read
446 * out of bounds. */
447 if (is_shared) {
448 count = 1;
449 } else {
450 /* If column is owned, there will be as many values as there are
451 * entities. */
452 count = static_cast<size_t>(m_iter->count);
453 }
454
456 ecs_field_w_size(m_iter, 0, index), size, count, is_shared);
457 }
458
459 flecs::iter_t *m_iter;
460 std::size_t m_begin;
461 std::size_t m_end;
462};
463
464} // namespace flecs
465
#define ecs_assert(condition, error_code,...)
Assert.
Definition: log.h:352
ecs_id_t ecs_entity_t
An entity identifier.
Definition: flecs.h:220
bool ecs_field_is_set(const ecs_iter_t *it, int32_t index)
Test whether field is set.
bool ecs_field_is_self(const ecs_iter_t *it, int32_t index)
Test whether the field is matched on self.
void * ecs_field_w_size(const ecs_iter_t *it, size_t size, int32_t index)
Obtain data for a query field.
size_t ecs_field_size(const ecs_iter_t *it, int32_t index)
Return field type size.
char * ecs_iter_str(const ecs_iter_t *it)
Convert iterator to string.
ecs_id_t ecs_field_id(const ecs_iter_t *it, int32_t index)
Return id matched for field.
bool ecs_field_is_readonly(const ecs_iter_t *it, int32_t index)
Test whether the field is readonly.
#define ecs_ftime_t
Customizable precision for scalar time values.
Definition: flecs.h:42
void ecs_query_skip(ecs_iter_t *it)
Skip a table while iterating.
bool ecs_query_changed(ecs_query_t *query, const ecs_iter_t *it)
Returns whether the query data changed since the last iteration.
bool ecs_table_has_module(ecs_table_t *table)
Returns whether table is a module or contains module contents Returns true for tables that have modul...
Iterate over an integer range (used to iterate over entity range).
Definition: iter.hpp:132
Wrapper class around a column.
Definition: iter.hpp:58
T & operator[](size_t index) const
Return element in component array.
Definition: iter.hpp:86
T * operator->() const
Return first element of component array.
Definition: iter.hpp:108
column(T *array, size_t count, bool is_shared=false)
Create column from component array.
Definition: iter.hpp:68
T & operator*() const
Return first element of component array.
Definition: iter.hpp:98
column(iter &iter, int column)
Create column from iterator.
Entity.
Definition: entity.hpp:30
Class that wraps around a flecs::id_t.
Definition: decl.hpp:27
Class for iterating over query results.
Definition: iter.hpp:169
int32_t table_count() const
Obtain the total number of tables the iterator will iterate over.
Definition: iter.hpp:370
flecs::string str() const
Convert current iterator result to string.
Definition: iter.hpp:323
int32_t field_count() const
Number of fields in iteator.
Definition: iter.hpp:290
void * param()
Access param.
Definition: iter.hpp:245
bool changed()
Check if the current table has changed since the last iteration.
Definition: iter.hpp:376
flecs::untyped_column field(int32_t index) const
Get unchecked access to field data.
Definition: iter.hpp:365
T * ctx()
Access ctx.
Definition: iter.hpp:238
flecs::entity src(int32_t index) const
Obtain field source (0 if This).
Definition: iter.hpp:38
void * ctx()
Access ctx.
Definition: iter.hpp:230
size_t size(int32_t index) const
Size of field data type.
Definition: iter.hpp:298
flecs::entity get_var(int var_id) const
Get value of variable by id.
Definition: iter.hpp:68
bool has_module() const
Is current type a module or does it contain module contents?
Definition: iter.hpp:223
bool is_set(int32_t index) const
Returns whether field is set.
Definition: iter.hpp:276
iter(ecs_iter_t *it)
Construct iterator from C iterator object.
Definition: iter.hpp:179
flecs::column< A > field(int32_t index) const
Get readonly access to field data.
Definition: iter.hpp:338
T * param()
Access param.
Definition: iter.hpp:253
bool is_self(int32_t index) const
Returns whether field is matched on self.
Definition: iter.hpp:268
bool is_readonly(int32_t index) const
Returns whether field is readonly.
Definition: iter.hpp:284
void skip()
Skip current table.
Definition: iter.hpp:387
Type that represents a pair.
Definition: pair.hpp:36
Type class.
Definition: type.hpp:21
Unsafe wrapper class around a column.
Definition: iter.hpp:25
void * operator[](size_t index) const
Return element in component array.
Definition: iter.hpp:38
The world.
Definition: world.hpp:113