Skip to content
Flecs v4.1
entity_view.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/entity_view.hpp
3 * @brief Entity class with only read-only operations.
4 *
5 * This class provides read-only access to entities. Using this class to store
6 * entities in components ensures valid handles, as this class will always store
7 * the actual world vs. a stage. The constructors of this class will never
8 * create a new entity.
9 *
10 * To obtain a mutable handle to the entity, use the mut() function.
11 */
13#pragma once
14
17/**
18 * @ingroup cpp_entities
19 * @{
20 */
21
22namespace flecs
23{
24
25/** Entity view.
26 * Class with read operations for entities. Base for flecs::entity.
27 *
28 * @ingroup cpp_entities
29 */
30struct entity_view : public id {
31
32 /** Default constructor. Creates an empty entity view. */
33 entity_view() : flecs::id() { }
35 /** Wrap an existing entity ID.
36 *
37 * @param world The world in which the entity is created.
38 * @param id The entity ID.
39 */
41 : flecs::id(world
42 ? const_cast<flecs::world_t*>(ecs_get_world(world))
43 : nullptr
44 , id ) { }
46 /** Implicit conversion from flecs::entity_t to flecs::entity_view. */
48 : flecs::id( nullptr, id ) { }
49
50 /** Get entity ID.
51 * @return The integer entity ID.
52 */
53 entity_t id() const {
54 return id_;
55 }
56
57 /** Check if entity is valid.
58 * An entity is valid if:
59 * - its ID is not 0
60 * - the ID contains a valid bit pattern for an entity
61 * - the entity is alive (see is_alive())
62 *
63 * @return True if the entity is valid, false otherwise.
64 * @see ecs_is_valid()
65 */
66 bool is_valid() const {
67 return world_ && ecs_is_valid(world_, id_);
68 }
69
70 /** Conversion to bool. Returns true if entity is valid. */
71 explicit operator bool() const {
72 return is_valid();
73 }
74
75 /** Check if entity is alive.
76 *
77 * @return True if the entity is alive, false otherwise.
78 * @see ecs_is_alive()
79 */
80 bool is_alive() const {
82 }
83
84 /** Return the entity name.
85 *
86 * @return The entity name.
87 */
90 }
92 /** Return the entity symbol.
93 *
94 * @return The entity symbol.
95 */
98 }
99
100 /** Return the entity path.
101 *
102 * @param sep The separator used between path elements.
103 * @param init_sep The initial separator prepended to the path.
104 * @return The hierarchical entity path.
105 */
106 flecs::string path(const char *sep = "::", const char *init_sep = "::") const {
107 return path_from(0, sep, init_sep);
108 }
109
110 /** Return the entity path relative to a parent.
111 *
112 * @param parent The parent entity to compute the path relative to.
113 * @param sep The separator used between path elements.
114 * @param init_sep The initial separator prepended to the path.
115 * @return The relative hierarchical entity path.
116 */
117 flecs::string path_from(flecs::entity_t parent, const char *sep = "::", const char *init_sep = "::") const {
118 char *path = ecs_get_path_w_sep(world_, parent, id_, sep, init_sep);
119 return flecs::string(path);
120 }
121
122 /** Return the entity path relative to a typed parent.
123 *
124 * @tparam Parent The parent type to compute the path relative to.
125 * @param sep The separator used between path elements.
126 * @param init_sep The initial separator prepended to the path.
127 * @return The relative hierarchical entity path.
128 */
129 template <typename Parent>
130 flecs::string path_from(const char *sep = "::", const char *init_sep = "::") const {
131 return path_from(_::type<Parent>::id(world_), sep, init_sep);
132 }
133
134 /** Check if entity is enabled (does not have the Disabled tag).
135 *
136 * @return True if the entity is enabled, false otherwise.
137 */
138 bool enabled() const {
139 return !ecs_has_id(world_, id_, flecs::Disabled);
140 }
141
142 /** Get the entity's type.
143 *
144 * @return The entity's type.
145 */
146 flecs::type type() const;
147
148 /** Get the entity's table.
149 *
150 * @return The entity's table.
151 */
152 flecs::table table() const;
153
154 /** Get table range for the entity.
155 * Return a range with the entity's row as offset and count set to 1. If
156 * the entity is not stored in a table, the function returns a range with
157 * count 0.
158 *
159 * @return The entity's table range.
160 */
161 flecs::table_range range() const;
162
163 /** Iterate (component) IDs of an entity.
164 * The function parameter must match the following signature:
165 *
166 * @code
167 * void(*)(flecs::id id)
168 * @endcode
169 *
170 * @param func The function invoked for each ID.
171 */
172 template <typename Func>
173 void each(const Func& func) const;
174
175 /** Iterate matching pair IDs of an entity.
176 * The function parameter must match the following signature:
177 *
178 * @code
179 * void(*)(flecs::id id)
180 * @endcode
181 *
182 * @param first The first element of the pair to match.
183 * @param second The second element of the pair to match.
184 * @param func The function invoked for each ID.
185 */
186 template <typename Func>
187 void each(flecs::id_t first, flecs::id_t second, const Func& func) const;
188
189 /** Iterate targets for a given relationship.
190 * The function parameter must match the following signature:
191 *
192 * @code
193 * void(*)(flecs::entity target)
194 * @endcode
195 *
196 * @param rel The relationship for which to iterate the targets.
197 * @param func The function invoked for each target.
198 */
199 template <typename Func>
200 void each(const flecs::entity_view& rel, const Func& func) const;
201
202 /** Iterate targets for a given relationship.
203 * The function parameter must match the following signature:
204 *
205 * @code
206 * void(*)(flecs::entity target)
207 * @endcode
208 *
209 * @tparam First The relationship for which to iterate the targets.
210 * @param func The function invoked for each target.
211 */
212 template <typename First, typename Func>
213 void each(const Func& func) const {
214 return each(_::type<First>::id(world_), func);
215 }
216
217 /** Iterate children for an entity.
218 * The function parameter must match the following signature:
219 *
220 * @code
221 * void(*)(flecs::entity target)
222 * @endcode
223 *
224 * @param rel The relationship to follow.
225 * @param func The function invoked for each child.
226 */
227 template <typename Func>
228 void children(flecs::entity_t rel, Func&& func) const {
229 /* When the entity is a wildcard, this would attempt to query for all
230 * entities with (ChildOf, *) or (ChildOf, _) instead of querying for
231 * the children of the wildcard entity. */
232 if (id_ == flecs::Wildcard || id_ == flecs::Any) {
233 /* This is correct, wildcard entities don't have children. */
234 return;
235 }
236
238
240 while (ecs_children_next(&it)) {
241 _::each_delegate<Func>(FLECS_MOV(func)).invoke(&it);
242 }
243 }
244
245 /** Iterate children for an entity.
246 * The function parameter must match the following signature:
247 *
248 * @code
249 * void(*)(flecs::entity target)
250 * @endcode
251 *
252 * @tparam Rel The relationship to follow.
253 * @param func The function invoked for each child.
254 */
255 template <typename Rel, typename Func>
256 void children(Func&& func) const {
257 children(_::type<Rel>::id(world_), FLECS_MOV(func));
258 }
259
260 /** Iterate children for an entity.
261 * The function parameter must match the following signature:
262 *
263 * @code
264 * void(*)(flecs::entity target)
265 * @endcode
266 *
267 * This operation follows the ChildOf relationship.
268 *
269 * @param func The function invoked for each child.
270 */
271 template <typename Func>
272 void children(Func&& func) const {
273 children(flecs::ChildOf, FLECS_MOV(func));
274 }
275
276
277 template <typename... T, typename... Args>
278 decltype(auto) try_get(Args... args) const {
279 return _::get_component<false, false>(world_, id_,
280 _::make_id<T...>(world_, args...));
281 }
282
283 template <typename... T, typename... Args>
284 decltype(auto) try_get_second(Args... args) const {
285 return _::get_component<false, false>(world_, id_,
286 _::second_id<T...>(world_, args...));
287 }
288
289 template <typename... T>
290 auto try_get_n() const {
291 static_assert(sizeof...(T) > 1 && sizeof...(T) < 9,
292 "component tuple requires between two and eight components");
293 return typename tuple_builder<sizeof...(T), T...>::type_const_ptr {try_get<T>()...};
294 }
295
296 template <typename Func, if_t<is_callable<Func>::value> = 0>
297 bool get(const Func& func) const;
298
299 template <typename... T, typename... Args>
300 decltype(auto) get(Args... args) const {
301 return _::get_component<false, true>(world_, id_,
302 _::make_id<T...>(world_, args...));
303 }
304
305 template <typename... T, typename... Args>
306 decltype(auto) get_second(Args... args) const {
307 return _::get_component<false, true>(world_, id_,
308 _::second_id<T...>(world_, args...));
309 }
310
311 template <typename... T>
312 auto get_n() const {
313 static_assert(sizeof...(T) > 1 && sizeof...(T) < 9,
314 "component tuple requires between two and eight components");
315 return typename tuple_builder<sizeof...(T), T...>::type_const {get<T>()...};
316 }
317
318 template <typename... T, typename... Args>
319 decltype(auto) try_get_mut(Args... args) const {
320 return _::get_component<true, false>(world_, id_,
321 _::make_id<T...>(world_, args...));
322 }
323
324 template <typename... T, typename... Args>
325 decltype(auto) try_get_mut_second(Args... args) const {
326 return _::get_component<true, false>(world_, id_,
327 _::second_id<T...>(world_, args...));
328 }
329
330 template <typename... T>
331 auto try_get_mut_n() const {
332 static_assert(sizeof...(T) > 1 && sizeof...(T) < 9,
333 "component tuple requires between two and eight components");
334 return typename tuple_builder<sizeof...(T), T...>::type_ptr {try_get_mut<T>()...};
335 }
336
337 template <typename... T, typename... Args>
338 decltype(auto) get_mut(Args... args) const {
339 return _::get_component<true, true>(world_, id_,
340 _::make_id<T...>(world_, args...));
341 }
342
343 template <typename... T, typename... Args>
344 decltype(auto) get_mut_second(Args... args) const {
345 return _::get_component<true, true>(world_, id_,
346 _::second_id<T...>(world_, args...));
347 }
348
349 template <typename... T>
350 auto get_mut_n() const {
351 static_assert(sizeof...(T) > 1 && sizeof...(T) < 9,
352 "component tuple requires between two and eight components");
353 return typename tuple_builder<sizeof...(T), T...>::type {get_mut<T>()...};
354 }
355
356 /** Get enum constant for enum relationship.
357 *
358 * @tparam Enum The enum type.
359 * @return The enum constant value.
360 */
361 template<typename Enum>
362 Enum get_constant() const;
363
364 /** Get target for a given pair.
365 * This operation returns the target for a given pair. The optional
366 * index can be used to iterate through targets, in case the entity has
367 * multiple instances for the same relationship.
368 *
369 * @tparam First The first element of the pair.
370 * @param index The index (0 for the first instance of the relationship).
371 * @return The target entity.
372 */
373 template<typename First>
374 flecs::entity target(int32_t index = 0) const;
375
376 /** Get target for a given pair.
377 * This operation returns the target for a given pair. The optional
378 * index can be used to iterate through targets, in case the entity has
379 * multiple instances for the same relationship.
380 *
381 * @param first The first element of the pair for which to retrieve the target.
382 * @param index The index (0 for the first instance of the relationship).
383 * @return The target entity.
384 */
385 flecs::entity target(flecs::entity_t first, int32_t index = 0) const;
386
387 /** Get the target of a pair for a given relationship ID.
388 * This operation returns the first entity that has the provided component ID
389 * by following the specified relationship. If the entity itself has the
390 * component ID, then the entity will be returned. If the component ID cannot
391 * be found on the entity or by following the
392 * relationship, the operation will return 0.
393 *
394 * This operation can be used to lookup, for example, which prefab is providing
395 * a component by specifying the IsA pair:
396 *
397 * @code
398 * // Is Position provided by the entity or one of its base entities?
399 * ecs_get_target_for_id(world, entity, EcsIsA, ecs_id(Position))
400 * @endcode
401 *
402 * @param relationship The relationship to follow.
403 * @param id The component ID to lookup.
404 * @return The entity for which the target has been found.
405 */
406 flecs::entity target_for(flecs::entity_t relationship, flecs::id_t id) const;
407
408 /** Get the target of a pair for a given relationship ID.
409 *
410 * @tparam T The component type to lookup.
411 * @param relationship The relationship to follow.
412 * @return The entity for which the target has been found.
413 */
414 template <typename T>
415 flecs::entity target_for(flecs::entity_t relationship) const;
416
417 /** Get the target of a pair for a given relationship ID.
418 *
419 * @tparam First The first element of the pair to lookup.
420 * @tparam Second The second element of the pair to lookup.
421 * @param relationship The relationship to follow.
422 * @return The entity for which the target has been found.
423 */
424 template <typename First, typename Second>
425 flecs::entity target_for(flecs::entity_t relationship) const;
426
427 /** Get the depth for a given relationship.
428 *
429 * @param rel The relationship.
430 * @return The depth.
431 */
432 int32_t depth(flecs::entity_t rel) const {
433 return ecs_get_depth(world_, id_, rel);
434 }
435
436 /** Get the depth for a given relationship.
437 *
438 * @tparam Rel The relationship.
439 * @return The depth.
440 */
441 template<typename Rel>
442 int32_t depth() const {
443 return this->depth(_::type<Rel>::id(world_));
444 }
445
446 /** Get parent of entity.
447 * Short for target(flecs::ChildOf).
448 *
449 * @return The parent of the entity.
450 */
451 flecs::entity parent() const;
452
453 /** Lookup an entity by name.
454 * Lookup an entity in the scope of this entity. The provided path may
455 * contain double colons as scope separators, for example: "Foo::Bar".
456 *
457 * @param path The name of the entity to lookup.
458 * @param search_path When false, only the entity's scope is searched.
459 * @return The found entity, or entity::null if no entity matched.
460 */
461 flecs::entity lookup(const char *path, bool search_path = false) const;
462
463 template <typename... T, typename... Args>
464 bool has(Args... args) const {
465 return _::has_component(world_, id_, _::make_id<T...>(world_, args...));
466 }
467
468 template <typename Second>
469 bool has_second(flecs::entity_t first) const {
470 return has(first, _::type<Second>::id(world_));
471 }
472
473 template <typename... T, typename... Args>
474 bool owns(Args... args) const {
475 return ecs_owns_id(world_, id_, _::make_id<T...>(world_, args...).id);
476 }
477
478 template <typename Second>
479 bool owns_second(flecs::entity_t first) const {
480 return owns(first, _::type<Second>::id(world_));
481 }
482
483 template <typename... T, typename... Args>
484 bool enabled(Args... args) const {
485 return ecs_is_enabled_id(world_, id_, _::make_id<T...>(world_, args...).id);
486 }
487
488 /** Clone an entity.
489 * Create a copy of the current entity with all of its components.
490 *
491 * @param clone_value If true, clone component values. If false, only clone the entity's type.
492 * @param dst_id If nonzero, clone to this entity ID instead of creating a new one.
493 * @return The cloned entity.
494 */
495 flecs::entity clone(bool clone_value = true, flecs::entity_t dst_id = 0) const;
496
497 /** Return a mutable entity handle for the current stage.
498 * When an entity handle created from the world is used while the world is
499 * in staged mode, it will only allow for read-only operations since
500 * structural changes are not allowed on the world while in staged mode.
501 *
502 * To do mutations on the entity, this operation provides a handle to the
503 * entity that uses the stage instead of the actual world.
504 *
505 * Note that staged entity handles should never be stored persistently, in
506 * components or elsewhere. An entity handle should always point to the
507 * main world.
508 *
509 * Also note that this operation is not necessary when doing mutations on an
510 * entity outside of a system. It is allowed to do entity operations
511 * directly on the world, as long as the world is not in staged mode.
512 *
513 * @param stage The current stage.
514 * @return An entity handle that allows for mutations in the current stage.
515 */
516 flecs::entity mut(const flecs::world& stage) const;
517
518 /** Same as mut(world), but for an iterator.
519 * This operation allows for the construction of a mutable entity handle
520 * from an iterator.
521 *
522 * @param it An iterator that contains a reference to the world or stage.
523 * @return An entity handle that allows for mutations in the current stage.
524 */
525 flecs::entity mut(const flecs::iter& it) const;
526
527 /** Same as mut(world), but for an entity.
528 * This operation allows for the construction of a mutable entity handle
529 * from another entity. This is useful in each() functions, which only
530 * provide a handle to the entity being iterated over.
531 *
532 * @param e Another mutable entity.
533 * @return An entity handle that allows for mutations in the current stage.
534 */
535 flecs::entity mut(const flecs::entity_view& e) const;
536
537# ifdef FLECS_JSON
539# endif
540# ifdef FLECS_DOC
542# endif
543# ifdef FLECS_ALERTS
545# endif
546
549
550private:
551 flecs::entity set_stage(world_t *stage);
552};
553
554}
555
556/** @} */
Alerts entity mixin.
Doc entity view mixin.
Utilities to fetch components as tuples from entities.
Enum entity view mixin.
Event entity mixin.
ecs_id_t id_t
ID type.
Definition c_types.hpp:20
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
ecs_world_t world_t
World type.
Definition c_types.hpp:18
bool ecs_children_next(ecs_iter_t *it)
Progress an iterator created with ecs_children().
ecs_iter_t ecs_children_w_rel(const ecs_world_t *world, ecs_entity_t relationship, ecs_entity_t parent)
Same as ecs_children(), but with a custom relationship argument.
bool ecs_is_enabled_id(const ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Test if a component is enabled.
bool ecs_owns_id(const ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Test if an entity owns a component.
int32_t ecs_get_depth(const ecs_world_t *world, ecs_entity_t entity, ecs_entity_t rel)
Return the depth for an entity in the tree for the specified relationship.
bool ecs_has_id(const ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Test if an entity has a component.
bool ecs_is_valid(const ecs_world_t *world, ecs_entity_t e)
Test whether an entity is valid.
bool ecs_is_alive(const ecs_world_t *world, ecs_entity_t e)
Test whether an entity is alive.
char * ecs_get_path_w_sep(const ecs_world_t *world, ecs_entity_t parent, ecs_entity_t child, const char *sep, const char *prefix)
Get a path identifier for an entity.
const char * ecs_get_symbol(const ecs_world_t *world, ecs_entity_t entity)
Get the symbol of an entity.
const char * ecs_get_name(const ecs_world_t *world, ecs_entity_t entity)
Get the name of an entity.
const ecs_world_t * ecs_get_world(const ecs_poly_t *poly)
Get the world from a poly.
JSON entity mixin.
Iterator.
Definition flecs.h:1191
entity_view(entity_t id)
Implicit conversion from flecs::entity_t to flecs::entity_view.
int32_t depth(flecs::entity_t rel) const
Get the depth for a given relationship.
flecs::string_view name() const
Return the entity name.
bool is_valid() const
Check if entity is valid.
flecs::string path(const char *sep="::", const char *init_sep="::") const
Return the entity path.
flecs::string_view symbol() const
Return the entity symbol.
void each(const Func &func) const
Iterate targets for a given relationship.
int32_t depth() const
Get the depth for a given relationship.
entity_view(flecs::world_t *world, flecs::id_t id)
Wrap an existing entity ID.
void children(Func &&func) const
Iterate children for an entity.
flecs::string path_from(flecs::entity_t parent, const char *sep="::", const char *init_sep="::") const
Return the entity path relative to a parent.
bool enabled() const
Check if entity is enabled (does not have the Disabled tag).
flecs::entity parent() const
Get parent of entity.
Definition impl.hpp:68
entity_view()
Default constructor.
void each(const Func &func) const
Iterate (component) IDs of an entity.
Definition impl.hpp:155
bool is_alive() const
Check if entity is alive.
void children(Func &&func) const
Iterate children for an entity.
entity_t id() const
Get entity ID.
flecs::string path_from(const char *sep="::", const char *init_sep="::") const
Return the entity path relative to a typed parent.
void children(flecs::entity_t rel, Func &&func) const
Iterate children for an entity.
Entity.
Definition entity.hpp:30
flecs::world world() const
Get the world.
Definition impl.hpp:60
flecs::id_t id_
The raw ID value.
Definition decl.hpp:154
flecs::entity second() const
Get second element from a pair.
Definition impl.hpp:31
flecs::world_t * world_
World is optional, but guarantees that entity identifiers extracted from the ID are valid.
Definition decl.hpp:152
flecs::entity first() const
Get first element from a pair.
Definition impl.hpp:20
Class for iterating over query results.
Definition iter.hpp:68
Non-owning string view.
Definition string.hpp:169
Owned string wrapper.
Definition string.hpp:15
Table range.
Definition table.hpp:205
Table.
Definition table.hpp:23
table()
Default constructor.
Definition table.hpp:25
Builds tuple types for a given number of component types.
Type class.
Definition type.hpp:21
type()
Default constructor.
Definition type.hpp:23
The world.
Definition world.hpp:129
void each(Func &&func) const
Iterate over all entities with components in the argument list of the function.
world()
Create a world.
Definition world.hpp:132