Flecs v3.2
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 : m_value(value){}
34
35 bool operator!=(range_iterator const& other) const
36 {
37 return m_value != other.m_value;
38 }
39
40 T const& operator*() const
41 {
42 return m_value;
43 }
44
45 range_iterator& operator++()
46 {
47 ++m_value;
48 return *this;
49 }
50
51private:
52 T m_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) : m_iter(it) {
79 m_begin = 0;
80 m_end = static_cast<std::size_t>(it->count);
81 }
82
83 row_iterator begin() const {
84 return row_iterator(m_begin);
85 }
86
87 row_iterator end() const {
88 return row_iterator(m_end);
89 }
90
91 flecs::entity system() const;
92
93 flecs::entity event() const;
94
95 flecs::id event_id() const;
96
97 flecs::world world() const;
98
99 const flecs::iter_t* c_ptr() const {
100 return m_iter;
101 }
102
103 size_t count() const {
104 return static_cast<size_t>(m_iter->count);
105 }
106
107 ecs_ftime_t delta_time() const {
108 return m_iter->delta_time;
109 }
110
111 ecs_ftime_t delta_system_time() const {
112 return m_iter->delta_system_time;
113 }
114
115 flecs::type type() const;
116
117 flecs::table table() const;
118
119 flecs::table_range range() const;
120
124 void* ctx() {
125 return m_iter->ctx;
126 }
127
131 template <typename T>
132 T* ctx() {
133 return static_cast<T*>(m_iter->ctx);
134 }
135
139 void* param() {
140 return m_iter->param;
141 }
142
146 template <typename T>
147 T* param() {
148 /* TODO: type check */
149 return static_cast<T*>(m_iter->param);
150 }
151
156 flecs::entity entity(size_t row) const;
157
162 bool is_self(int32_t index) const {
163 return ecs_field_is_self(m_iter, index);
164 }
165
170 bool is_set(int32_t index) const {
171 return ecs_field_is_set(m_iter, index);
172 }
173
178 bool is_readonly(int32_t index) const {
179 return ecs_field_is_readonly(m_iter, index);
180 }
181
184 int32_t field_count() const {
185 return m_iter->field_count;
186 }
187
192 size_t size(int32_t index) const {
193 return ecs_field_size(m_iter, index);
194 }
195
200 flecs::entity src(int32_t index) const;
201
206 flecs::id id(int32_t index) const;
207
213 flecs::id pair(int32_t index) const;
214
219 int32_t column_index(int32_t index) const {
220 return ecs_field_column_index(m_iter, index);
221 }
222
225 int32_t term_index() const {
226 return m_iter->term_index + 1; // in iter_t, the term index is zero-based, so add 1.
227 }
228
232 char *s = ecs_iter_str(m_iter);
233 return flecs::string(s);
234 }
235
244 template <typename T, typename A = actual_type_t<T>,
245 typename std::enable_if<std::is_const<T>::value, void>::type* = nullptr>
246 flecs::field<A> field(int32_t index) const;
247
256 template <typename T, typename A = actual_type_t<T>,
257 typename std::enable_if<
258 std::is_const<T>::value == false, void>::type* = nullptr>
259 flecs::field<A> field(int32_t index) const;
260
267 flecs::untyped_field field(int32_t index) const {
268 ecs_assert(!(m_iter->flags & EcsIterCppEach), ECS_INVALID_OPERATION,
269 "cannot .field from .each, use .field_at(%d, row) instead", index);
270 return get_unchecked_field(index);
271 }
272
274 void* field_at(int32_t index, size_t row) const {
275 return get_unchecked_field(index)[row];
276 }
277
279 template <typename T, typename A = actual_type_t<T>,
280 typename std::enable_if<std::is_const<T>::value, void>::type* = nullptr>
281 const A& field_at(int32_t index, size_t row) const {
282 return get_field<A>(index)[row];
283 }
284
286 template <typename T, typename A = actual_type_t<T>,
287 typename std::enable_if<
288 std::is_const<T>::value == false, void>::type* = nullptr>
289 A& field_at(int32_t index, size_t row) const {
290 ecs_assert(!ecs_field_is_readonly(m_iter, index),
291 ECS_ACCESS_VIOLATION, NULL);
292 return get_field<A>(index)[row];
293 }
294
300 return flecs::field<const flecs::entity_t>(m_iter->entities, static_cast<size_t>(m_iter->count), false);
301 }
302
304 int32_t table_count() const {
305 return m_iter->table_count;
306 }
307
310 bool changed() {
311 return ecs_query_changed(nullptr, m_iter);
312 }
313
321 void skip() {
322 ecs_query_skip(m_iter);
323 }
324
325 /* Return group id for current table (grouped queries only) */
326 uint64_t group_id() const {
327 return m_iter->group_id;
328 }
329
330#ifdef FLECS_RULES
334 flecs::entity get_var(int var_id) const;
335
339 flecs::entity get_var(const char *name) const;
340#endif
341
342private:
343 /* Get field, check if correct type is used */
344 template <typename T, typename A = actual_type_t<T>>
345 flecs::field<T> get_field(int32_t index) const {
346
347#ifndef FLECS_NDEBUG
348 ecs_entity_t term_id = ecs_field_id(m_iter, index);
349 ecs_assert(ECS_HAS_ID_FLAG(term_id, PAIR) ||
350 term_id == _::cpp_type<T>::id(m_iter->world),
351 ECS_COLUMN_TYPE_MISMATCH, NULL);
352#endif
353
354 size_t count;
355 bool is_shared = !ecs_field_is_self(m_iter, index);
356
357 /* If a shared column is retrieved with 'column', there will only be a
358 * single value. Ensure that the application does not accidentally read
359 * out of bounds. */
360 if (is_shared) {
361 count = 1;
362 } else {
363 /* If column is owned, there will be as many values as there are
364 * entities. */
365 count = static_cast<size_t>(m_iter->count);
366 }
367
368 return flecs::field<A>(
369 static_cast<T*>(ecs_field_w_size(m_iter, sizeof(A), index)),
370 count, is_shared);
371 }
372
373 flecs::untyped_field get_unchecked_field(int32_t index) const {
374 size_t count;
375 size_t size = ecs_field_size(m_iter, index);
376 bool is_shared = !ecs_field_is_self(m_iter, index);
377
378 /* If a shared column is retrieved with 'column', there will only be a
379 * single value. Ensure that the application does not accidentally read
380 * out of bounds. */
381 if (is_shared) {
382 count = 1;
383 } else {
384 /* If column is owned, there will be as many values as there are
385 * entities. */
386 count = static_cast<size_t>(m_iter->count);
387 }
388
390 ecs_field_w_size(m_iter, 0, index), size, count, is_shared);
391 }
392
393 flecs::iter_t *m_iter;
394 std::size_t m_begin;
395 std::size_t m_end;
396};
397
398} // namespace flecs
399
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:351
ecs_id_t ecs_entity_t
An entity identifier.
Definition flecs.h:318
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.
int32_t ecs_field_column_index(const ecs_iter_t *it, int32_t index)
Return index of matched table column.
#define ecs_ftime_t
Customizable precision for scalar time values.
Definition flecs.h:57
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.
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(int32_t index) const
Obtain id matched for field.
Definition iter.hpp:37
int32_t table_count() const
Obtain the total number of tables the iterator will iterate over.
Definition iter.hpp:304
flecs::string str() const
Convert current iterator result to string.
Definition iter.hpp:231
int32_t field_count() const
Number of fields in iterator.
Definition iter.hpp:184
void * param()
Access param.
Definition iter.hpp:139
bool changed()
Check if the current table has changed since the last iteration.
Definition iter.hpp:310
const A & field_at(int32_t index, size_t row) const
Get reference to field at row.
Definition iter.hpp:281
A & field_at(int32_t index, size_t row) const
Get reference to field at row.
Definition iter.hpp:289
T * ctx()
Access ctx.
Definition iter.hpp:132
flecs::entity src(int32_t index) const
Obtain field source (0 if This).
Definition iter.hpp:33
void * field_at(int32_t index, size_t row) const
Get pointer to field at row.
Definition iter.hpp:274
flecs::field< A > field(int32_t index) const
Get readonly access to field data.
Definition iter.hpp:64
void * ctx()
Access ctx.
Definition iter.hpp:124
flecs::entity entity(size_t row) const
Obtain mutable handle to entity being iterated over.
Definition iter.hpp:27
int32_t term_index() const
Obtain term that triggered an observer.
Definition iter.hpp:225
size_t size(int32_t index) const
Size of field data type.
Definition iter.hpp:192
flecs::id pair(int32_t index) const
Obtain pair id matched for field.
Definition iter.hpp:41
flecs::untyped_field field(int32_t index) const
Get unchecked access to field data.
Definition iter.hpp:267
flecs::entity get_var(int var_id) const
Get value of variable by id.
Definition iter.hpp:84
flecs::field< const flecs::entity_t > entities() const
Get readonly access to entity ids.
Definition iter.hpp:299
int32_t column_index(int32_t index) const
Obtain column index for field.
Definition iter.hpp:219
bool is_set(int32_t index) const
Returns whether field is set.
Definition iter.hpp:170
iter(ecs_iter_t *it)
Construct iterator from C iterator object.
Definition iter.hpp:78
T * param()
Access param.
Definition iter.hpp:147
bool is_self(int32_t index) const
Returns whether field is matched on self.
Definition iter.hpp:162
bool is_readonly(int32_t index) const
Returns whether field is readonly.
Definition iter.hpp:178
void skip()
Skip current table.
Definition iter.hpp:321
Type class.
Definition type.hpp:21
Unsafe wrapper class around a field.
Definition field.hpp:26
The world.
Definition world.hpp:132