Skip to content
Flecs v4.1
iter.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/iter.hpp
3 * @brief Wrapper classes for ecs_iter_t and component arrays.
4 */
5
6#pragma once
7
8/**
9 * @defgroup cpp_iterator Iterators
10 * @ingroup cpp_core
11 * Iterator operations.
12 *
13 * @{
14 */
15
16namespace flecs
17{
18
19////////////////////////////////////////////////////////////////////////////////
20
21namespace _ {
22
23////////////////////////////////////////////////////////////////////////////////
24
25/** Iterate over an integer range (used to iterate over entity range).
26 *
27 * @tparam T The value type of the iterator.
28 */
29template <typename T>
30struct range_iterator
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
62////////////////////////////////////////////////////////////////////////////////
63
64/** Class for iterating over query results.
65 *
66 * @ingroup cpp_iterator
67 */
68struct iter {
69private:
70 using row_iterator = _::range_iterator<size_t>;
71
72public:
73 /** Construct iterator from C iterator object.
74 * This operation is typically not invoked directly by the user.
75 *
76 * @param it Pointer to C iterator.
77 */
78 iter(ecs_iter_t *it) : iter_(it) { }
79
80 /** Get an iterator to the beginning of the entity range. */
81 row_iterator begin() const {
82 return row_iterator(0);
83 }
84
85 /** Get an iterator to the end of the entity range. */
86 row_iterator end() const {
87 return row_iterator(static_cast<size_t>(iter_->count));
88 }
89
90 /** Get the system entity associated with the iterator. */
91 flecs::entity system() const;
92
93 /** Get the event entity associated with the iterator. */
94 flecs::entity event() const;
95
96 /** Get the event ID associated with the iterator. */
97 flecs::id event_id() const;
98
99 /** Get the world associated with the iterator. */
100 flecs::world world() const;
101 flecs::world stage() const;
102
103 /** Get a pointer to the underlying C iterator object. */
104 const flecs::iter_t* c_ptr() const {
105 return iter_;
106 }
107
108 /** Get the number of entities to iterate over.
109 *
110 * @return The number of entities in the current result.
111 */
112 size_t count() const {
113 ecs_check(iter_->flags & EcsIterIsValid, ECS_INVALID_PARAMETER,
114 "operation invalid before calling next()");
115 return static_cast<size_t>(iter_->count);
116 error:
117 return 0;
118 }
119
120 size_t frame_offset() const {
121 ecs_check(iter_->flags & EcsIterIsValid, ECS_INVALID_PARAMETER,
122 "operation invalid before calling next()");
123 return static_cast<size_t>(iter_->frame_offset);
124 error:
125 return 0;
126 }
127
128 /** Get the time elapsed since the last frame.
129 *
130 * @return The delta time.
131 */
133 return iter_->delta_time;
134 }
135
136 /** Get the time elapsed since the last system invocation.
137 *
138 * @return The delta system time.
139 */
141 return iter_->delta_system_time;
142 }
143
144 /** Get the type of the iterated table. */
145 flecs::type type() const;
146
147 /** Get the table for the current iterator result. */
148 flecs::table table() const;
149
150 /** Get the other table for the current iterator result.
151 * This is used for move operations where data is moved from one table
152 * to another.
153 */
155
156 /** Get the table range for the current iterator result. */
157 flecs::table_range range() const;
158
159 /** Access ctx.
160 * ctx contains the context pointer assigned to a system.
161 */
162 void* ctx() {
163 return iter_->ctx;
164 }
165
166 /** Access ctx.
167 * ctx contains the context pointer assigned to a system.
168 */
169 template <typename T>
170 T* ctx() {
171 return static_cast<T*>(iter_->ctx);
172 }
173
174 /** Access param.
175 * param contains the pointer passed to the param argument of system::run().
176 */
177 void* param() {
178 return iter_->param;
179 }
180
181 /** Access param.
182 * param contains the pointer passed to the param argument of system::run().
183 */
184 template <typename T>
185 T* param() {
186 /* TODO: type check */
187 return static_cast<T*>(iter_->param);
188 }
189
190 /** Obtain a mutable handle to the entity being iterated over.
191 *
192 * @param row Row being iterated over.
193 * @return The entity at the specified row.
194 */
195 flecs::entity entity(size_t row) const;
196
197 /** Return whether the field is matched on self.
198 *
199 * @param index The field index.
200 * @return True if the field is matched on self, false if not.
201 */
202 bool is_self(int8_t index) const {
203 return ecs_field_is_self(iter_, index);
204 }
205
206 /** Return whether the field is set.
207 *
208 * @param index The field index.
209 * @return True if the field is set, false if not.
210 */
211 bool is_set(int8_t index) const {
212 return ecs_field_is_set(iter_, index);
213 }
214
215 /** Return whether the field is readonly.
216 *
217 * @param index The field index.
218 * @return True if the field is readonly, false if not.
219 */
220 bool is_readonly(int8_t index) const {
221 return ecs_field_is_readonly(iter_, index);
222 }
223
224 /** Number of fields in the iterator.
225 *
226 * @return The number of fields.
227 */
228 int32_t field_count() const {
229 return iter_->field_count;
230 }
231
232 /** Size of the field data type.
233 *
234 * @param index The field index.
235 * @return The size of the field data type.
236 */
237 size_t size(int8_t index) const {
238 return ecs_field_size(iter_, index);
239 }
240
241 /** Obtain the field source (0 if This).
242 *
243 * @param index The field index.
244 * @return The source entity for the field.
245 */
246 flecs::entity src(int8_t index) const;
247
248 /** Obtain the ID matched for the field.
249 *
250 * @param index The field index.
251 * @return The ID matched for the field.
252 */
253 flecs::id id(int8_t index) const;
254
255 /** Obtain the pair ID matched for the field.
256 * This operation will fail if the ID is not a pair.
257 *
258 * @param index The field index.
259 * @return The pair ID matched for the field.
260 */
261 flecs::id pair(int8_t index) const;
262
263 /** Obtain the column index for the field.
264 *
265 * @param index The field index.
266 * @return The column index for the field.
267 */
268 int32_t column_index(int8_t index) const {
269 return ecs_field_column(iter_, index);
270 }
271
272 /** Obtain the term that triggered an observer.
273 *
274 * @return The index of the term that triggered the observer.
275 */
276 int8_t term_index() const {
277 return iter_->term_index;
278 }
279
280 /** Get read-only access to field data.
281 * If the specified field index does not match with the provided type, the
282 * function will assert.
283 *
284 * This function should not be used in each() callbacks, unless it is to
285 * access a shared field. For access to non-shared fields in each(), use
286 * field_at().
287 *
288 * @tparam T Type of the field.
289 * @param index The field index.
290 * @return The field data.
291 */
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
295 /** Get read/write access to field data.
296 * If the matched ID for the specified field does not match with the provided
297 * type or if the field is readonly, the function will assert.
298 *
299 * This function should not be used in each() callbacks, unless it is to
300 * access a shared field. For access to non-shared fields in each(), use
301 * field_at().
302 *
303 * @tparam T Type of the field.
304 * @param index The field index.
305 * @return The field data.
306 */
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
310 /** Get access to a field matched through component inheritance.
311 * Like field(), but returns a base_field that iterates with a runtime
312 * stride, so it works when the matched (derived) component is larger than T.
313 * Unlike field(), this does not assert when the field is of type T or a
314 * subtype of T.
315 *
316 * @tparam T Base type of the field.
317 * @param index The field index.
318 * @return The field data.
319 */
320 template <typename T, typename A = actual_type_t<T>, if_t<is_const_v<T>> = 0>
321 flecs::base_field<A> base_field(int8_t index) const;
322
323 /** Get read/write access to a field matched through component inheritance.
324 *
325 * @tparam T Base type of the field.
326 * @param index The field index.
327 * @return The field data.
328 */
329 template <typename T, typename A = actual_type_t<T>, if_not_t<is_const_v<T>> = 0>
330 flecs::base_field<A> base_field(int8_t index) const;
331
332 /** Get unchecked access to field data.
333 * Unchecked access is required when a system does not know the type of a
334 * field at compile time.
335 *
336 * This function should not be used in each() callbacks, unless it is to
337 * access a shared field. For access to non-shared fields in each(), use
338 * field_at().
339 *
340 * @param index The field index.
341 */
342 flecs::untyped_field field(int8_t index) const {
343 ecs_assert(!(iter_->flags & EcsIterCppEach) ||
344 ecs_field_src(iter_, index) != 0, ECS_INVALID_OPERATION,
345 "cannot .field from .each, use .field_at(%d, row) instead", index);
346 return get_unchecked_field(index);
347 }
348
349 /** Get pointer to field at row.
350 * This function may be used to access shared fields when row is set to 0.
351 *
352 * @param index The field index.
353 * @param row The row index.
354 * @return Pointer to the field value at the specified row.
355 */
356 void* field_at(int8_t index, size_t row) const {
357 if (iter_->row_fields & (1llu << index)) {
358 return get_unchecked_field_at(index, row)[0];
359 } else {
360 return get_unchecked_field(index)[row];
361 }
362 }
363
364 /** Get const reference to field at row.
365 * This function may be used to access shared fields when row is set to 0.
366 *
367 * @tparam T Type of the field (must be const-qualified).
368 * @param index The field index.
369 * @param row The row index.
370 * @return Const reference to the field value at the specified row.
371 */
372 template <typename T, typename A = actual_type_t<T>, if_t< is_const_v<T> > = 0>
373 const A& field_at(int8_t index, size_t row) const {
374 if (iter_->row_fields & (1llu << index)) {
375 return get_field_at<A>(index, row)[0];
376 } else {
377 return get_field<A>(index)[row];
378 }
379 }
380
381 /** Get mutable reference to field at row.
382 * This function may be used to access shared fields when row is set to 0.
383 *
384 * @tparam T Type of the field (must not be const-qualified).
385 * @param index The field index.
386 * @param row The row index.
387 * @return Mutable reference to the field value at the specified row.
388 */
389 template <typename T, typename A = actual_type_t<T>, if_not_t< is_const_v<T> > = 0>
390 A& field_at(int8_t index, size_t row) const {
391 ecs_assert(!ecs_field_is_readonly(iter_, index),
392 ECS_ACCESS_VIOLATION, nullptr);
393 if (iter_->row_fields & (1llu << index)) {
394 return get_field_at<A>(index, row)[0];
395 } else {
396 return get_field<A>(index)[row];
397 }
398 }
399
400 /** Get read-only access to entity IDs.
401 *
402 * @return The entity IDs.
403 */
406 iter_->entities, static_cast<size_t>(iter_->count), false);
407 }
408
409#ifdef FLECS_CACHED_QUERIES
410 /** Check if the current table has changed since the last iteration.
411 * Can only be used when iterating queries and/or systems.
412 *
413 * @return True if the table has changed.
414 */
415 bool changed() {
416 return ecs_iter_changed(iter_);
417 }
418
419 /** Skip current table.
420 * This indicates to the query that the data in the current table is not
421 * modified. By default, iterating a table with a query will mark the
422 * iterated components as dirty if they are annotated with InOut or Out.
423 *
424 * When this operation is invoked, the components of the current table will
425 * not be marked dirty. */
426 void skip() {
427 ecs_iter_skip(iter_);
428 }
429
430 /** Return the group ID for the current table (grouped queries only).
431 *
432 * @return The group ID.
433 */
434 uint64_t group_id() const {
435 return ecs_iter_get_group(iter_);
436 }
437#endif
438
439#ifdef FLECS_QUERY_PLANS
440 /** Get value of variable by ID.
441 * Get value of a query variable for current result.
442 *
443 * @param var_id The variable ID.
444 * @return The variable value.
445 */
446 flecs::entity get_var(int var_id) const;
447
448 /** Get value of variable by name.
449 * Get value of a query variable for current result.
450 *
451 * @param name The variable name.
452 * @return The variable value.
453 */
454 flecs::entity get_var(const char *name) const;
455#endif
456
457 /** Progress iterator.
458 * This operation should only be called from a context where the iterator is
459 * not being progressed automatically. An example of a valid context is
460 * inside of a run() callback. An example of an invalid context is inside of
461 * an each() callback.
462 *
463 * @return True if there is more data to iterate, false if not.
464 */
465 bool next() {
466 if (iter_->flags & EcsIterIsValid && iter_->table) {
467 ECS_TABLE_UNLOCK(iter_->stage, iter_->table);
468 }
469 bool result = iter_->next(iter_);
470 iter_->flags |= EcsIterIsValid;
471 if (result && iter_->table) {
472 ECS_TABLE_LOCK(iter_->stage, iter_->table);
473 }
474 return result;
475 }
476
477 /** Forward to each().
478 * If a system has an each() callback registered, this operation will forward
479 * the current iterator to the each() callback.
480 */
481 void each() {
482 iter_->callback(iter_);
483 }
484
485 /** Iterate targets for pair field.
486 *
487 * @param index The field index.
488 * @param func Callback invoked for each target.
489 */
490 template <typename Func>
491 void targets(int8_t index, const Func& func);
492
493 /** Free iterator resources.
494 * This operation only needs to be called when the iterator is not iterated
495 * until completion (e.g., the last call to next() did not return false).
496 *
497 * Failing to call this operation on an unfinished iterator will throw a
498 * fatal LEAK_DETECTED error.
499 *
500 * @see ecs_iter_fini()
501 */
502 void fini() {
503 if (iter_->flags & EcsIterIsValid && iter_->table) {
504 ECS_TABLE_UNLOCK(iter_->stage, iter_->table);
505 }
506 ecs_iter_fini(iter_);
507 }
508
509private:
510 /* Get field, check if correct type is used. */
511 template <typename T, typename A = actual_type_t<T>>
512 flecs::field<T> get_field(int8_t index) const {
513
514#ifndef FLECS_NDEBUG
515 ecs_entity_t term_id = ecs_field_id(iter_, index);
516 ecs_assert(ECS_HAS_ID_FLAG(term_id, PAIR) ||
517 term_id == _::type<T>::id(iter_->stage),
518 ECS_COLUMN_TYPE_MISMATCH, nullptr);
519#endif
520
521 size_t count;
522 bool is_shared = !ecs_field_is_self(iter_, index);
523
524 /* If a shared field is retrieved with field(), there will only be a
525 * single value. Ensure that the application does not accidentally read
526 * out of bounds. */
527 if (is_shared) {
528 count = 1;
529 } else {
530 /* If field is owned, there will be as many values as there are
531 * entities. */
532 count = static_cast<size_t>(iter_->count);
533 }
534
535 return flecs::field<A>(
536 static_cast<T*>(ecs_field_w_size(iter_, sizeof(A), index)),
537 count, is_shared);
538 }
539
540 /* Get field matched through component inheritance. Checks the queried
541 * (base) type matches T, not the (possibly derived) matched id, so a field
542 * of type T or a subtype of T is accepted. Uses a runtime stride. */
543 template <typename T, typename A = actual_type_t<T>>
544 flecs::base_field<T> get_base_field(int8_t index) const {
545
546#ifndef FLECS_NDEBUG
547 ecs_assert(ecs_field_size(iter_, index) == sizeof(A),
549#endif
550
551 size_t count;
552 bool is_shared = !ecs_field_is_self(iter_, index);
553
554 if (is_shared) {
555 count = 1;
556 } else {
557 count = static_cast<size_t>(iter_->count);
558 }
559
560 return flecs::base_field<A>(
561 static_cast<T*>(ecs_base_field_w_size(iter_, sizeof(A), index)),
562 ecs_field_stride(iter_, index), count, is_shared);
563 }
564
565 /* Get field, check if correct type is used. */
566 template <typename T, typename A = actual_type_t<T>>
567 flecs::field<T> get_field_at(int8_t index, int32_t row) const {
568
569#ifndef FLECS_NDEBUG
570 ecs_entity_t term_id = ecs_field_id(iter_, index);
571 ecs_assert(ECS_HAS_ID_FLAG(term_id, PAIR) ||
572 term_id == _::type<T>::id(iter_->stage),
573 ECS_COLUMN_TYPE_MISMATCH, nullptr);
574#endif
575
576 return flecs::field<A>(
577 static_cast<T*>(ecs_field_at_w_size(iter_, sizeof(A), index, row)),
578 1, false);
579 }
580
581 flecs::untyped_field get_unchecked_field(int8_t index) const {
582 size_t count;
583 size_t size = ecs_field_size(iter_, index);
584 bool is_shared = !ecs_field_is_self(iter_, index);
585
586 /* If a shared field is retrieved with field(), there will only be a
587 * single value. Ensure that the application does not accidentally read
588 * out of bounds. */
589 if (is_shared) {
590 count = 1;
591 } else {
592 /* If field is owned, there will be as many values as there are
593 * entities. */
594 count = static_cast<size_t>(iter_->count);
595 }
596
597 return flecs::untyped_field(
598 ecs_field_w_size(iter_, size, index), size, count, is_shared);
599 }
600
601 flecs::untyped_field get_unchecked_field_at(int8_t index, size_t row) const {
602 size_t size = ecs_field_size(iter_, index);
603 return flecs::untyped_field(
604 ecs_field_at_w_size(iter_, size, index, static_cast<int32_t>(row)),
605 size, 1, false);
606 }
607
608 flecs::iter_t *iter_;
609};
610
611} // namespace flecs
612
613/** @} */
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_ACCESS_VIOLATION
Access violation error code.
Definition log.h:746
#define ECS_INVALID_OPERATION
Invalid operation error code.
Definition log.h:696
#define ECS_COLUMN_TYPE_MISMATCH
Column type mismatch error code.
Definition log.h:754
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:698
#define ecs_check(condition, error_code,...)
Check.
Definition log.h:527
ecs_id_t ecs_entity_t
An entity identifier.
Definition flecs.h:396
ecs_iter_t iter_t
Iterator type.
Definition c_types.hpp:28
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.
size_t ecs_field_stride(const ecs_iter_t *it, int8_t index)
Return the field storage stride.
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.
void * ecs_base_field_w_size(const ecs_iter_t *it, size_t size, int8_t index)
Get data for a field matched through component inheritance.
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.
Int to enum.
Definition component.hpp:18
Iterator.
Definition flecs.h:1184
int32_t frame_offset
Offset relative to the start of iteration.
Definition flecs.h:1233
ecs_flags32_t flags
Iterator flags.
Definition flecs.h:1236
int32_t count
Number of entities to iterate.
Definition flecs.h:1190
Iterate over an integer range (used to iterate over entity range).
Definition iter.hpp:31
Wrapper class around a field matched through component inheritance.
Definition field.hpp:122
Entity.
Definition entity.hpp:30
entity()
Default constructor.
Definition entity.hpp:32
Wrapper class around a field.
Definition field.hpp:61
field(T *array, size_t count, bool is_shared=false)
Create a field from a component array.
Definition field.hpp:71
Class that wraps around a flecs::id_t.
Definition decl.hpp:27
size_t size(int8_t index) const
Size of the field data type.
Definition iter.hpp:237
flecs::field< A > field(int8_t index) const
Get read/write access to field data.
const A & field_at(int8_t index, size_t row) const
Get const reference to field at row.
Definition iter.hpp:373
bool is_self(int8_t index) const
Return whether the field is matched on self.
Definition iter.hpp:202
int32_t field_count() const
Number of fields in the iterator.
Definition iter.hpp:228
ecs_ftime_t delta_system_time() const
Get the time elapsed since the last system invocation.
Definition iter.hpp:140
int32_t column_index(int8_t index) const
Obtain the column index for the field.
Definition iter.hpp:268
void * param()
Access param.
Definition iter.hpp:177
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
flecs::base_field< A > base_field(int8_t index) const
Get access to a field matched through component inheritance.
Definition iter.hpp:106
void * field_at(int8_t index, size_t row) const
Get pointer to field at row.
Definition iter.hpp:356
ecs_ftime_t delta_time() const
Get the time elapsed since the last frame.
Definition iter.hpp:132
bool is_readonly(int8_t index) const
Return whether the field is readonly.
Definition iter.hpp:220
flecs::table other_table() const
Get the other table for the current iterator result.
Definition iter.hpp:72
const flecs::iter_t * c_ptr() const
Get a pointer to the underlying C iterator object.
Definition iter.hpp:104
bool changed()
Check if the current table has changed since the last iteration.
Definition iter.hpp:415
int8_t term_index() const
Obtain the term that triggered an observer.
Definition iter.hpp:276
T * ctx()
Access ctx.
Definition iter.hpp:170
void fini()
Free iterator resources.
Definition iter.hpp:502
bool is_set(int8_t index) const
Return whether the field is set.
Definition iter.hpp:211
A & field_at(int8_t index, size_t row) const
Get mutable reference to field at row.
Definition iter.hpp:390
void * ctx()
Access ctx.
Definition iter.hpp:162
void each()
Forward to each().
Definition iter.hpp:481
flecs::untyped_field field(int8_t index) const
Get unchecked access to field data.
Definition iter.hpp:342
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:128
size_t count() const
Get the number of entities to iterate over.
Definition iter.hpp:112
flecs::field< const flecs::entity_t > entities() const
Get read-only access to entity IDs.
Definition iter.hpp:404
uint64_t group_id() const
Return the group ID for the current table (grouped queries only).
Definition iter.hpp:434
iter(ecs_iter_t *it)
Construct iterator from C iterator object.
Definition iter.hpp:78
T * param()
Access param.
Definition iter.hpp:185
void targets(int8_t index, const Func &func)
Iterate targets for pair field.
Definition iter.hpp:147
flecs::entity src(int8_t index) const
Obtain the field source (0 if This).
Definition iter.hpp:43
void skip()
Skip current table.
Definition iter.hpp:426
bool next()
Progress iterator.
Definition iter.hpp:465
pair(type &v)
Construct pair from a mutable reference to the storage type.
Definition pair.hpp:45
system()
Default constructor.
Definition impl.hpp:82
Table range.
Definition table.hpp:205
Table.
Definition table.hpp:23
table()
Default constructor.
Definition table.hpp:25
Type class.
Definition type.hpp:21
type()
Default constructor.
Definition type.hpp:23
Unsafe wrapper class around a field.
Definition field.hpp:26
The world.
Definition world.hpp:129
world()
Create a world.
Definition world.hpp:132
flecs::event_builder event(flecs::entity_t evt) const
Create a new event.