Class Entity¶
Defined in File entity.h
Class Documentation¶
-
class Entity¶
Lightweight wrapper around EnTT’s handle providing Portal’s component access API.
The Entity class wraps entt::handle (which combines an entity ID with a registry reference) and provides Portal-specific component manipulation and parent-child hierarchy support. Entity objects are value types that can be freely copied and passed around - they don’t own the underlying entity data, just reference it.
Key features:
Component management (add, remove, get, patch)
Parent-child hierarchy relationships via RelationshipComponent
Iteration over children and descendants
Type-safe component access with compile-time checks
All entities created through Registry automatically receive default components:
See also
Registry for entity creation and destruction
- Example Usage:
// Entity is obtained from Registry, not constructed directly auto player = registry.create_entity(STRING_ID("player")); // Add components player.add_component<HealthComponent>(100.0f); player.add_component<VelocityComponent>(vec3{0, 0, 0}); // Access components auto& health = player.get_component<HealthComponent>(); health.value -= 10.0f; // Optional access if (auto* armor = player.try_get_component<ArmorComponent>()) { armor->durability -= 5; } // Check component existence if (player.has_component<TransformComponent>()) { // All entities have Transform by default } // Parent-child hierarchy auto weapon = registry.create_entity(STRING_ID("sword")); weapon.set_parent(player); // Iterate children for (auto child : player.children()) { // Process direct children }
Note
Entity is a handle - it doesn’t own the entity data and can become invalid if the entity is destroyed. Use is_valid() to check validity.
Note
Component access methods assert in debug builds if the component doesn’t exist.
Public Functions
-
Entity() = default¶
Constructs an invalid (null) entity.
Default-constructed entities are invalid and cannot be used until assigned a valid entity handle.
-
Entity(entt::entity entity, entt::registry ®)¶
Constructs an Entity wrapper from a raw entity ID and registry.
Note
This is typically called by Registry methods, not user code.
- Parameters:
entity – The raw EnTT entity identifier
reg – Reference to the registry containing the entity
-
Entity(entt::handle handle)¶
Constructs an Entity wrapper from an EnTT handle.
Note
This is typically called by Registry methods, not user code.
- Parameters:
handle – The EnTT handle (entity + registry)
-
template<typename T, typename ...Args>
inline T &add_component(Args&&... args)¶ Adds a component to this entity with constructor arguments.
Constructs the component in-place using the provided arguments and attaches it to this entity. Asserts if the component already exists.
- Example:
auto& health = entity.add_component<HealthComponent>(100.0f); entity.add_component<VelocityComponent>(vec3{1, 0, 0});
Note
Asserts in debug builds if the component already exists.
- Template Parameters:
T – The component type to add
Args – Argument types for the component constructor
- Parameters:
args – Arguments forwarded to the component constructor
- Returns:
Reference to the newly created component
-
template<typename T>
inline void add_component()¶ Adds an empty (tag) component to this entity.
Specialized overload for empty component types (tags) that don’t require constructor arguments. Useful for marking entities with specific properties.
- Example:
entity.add_component<PlayerTag>(); entity.add_component<TransformDirtyTag>();
Note
Asserts in debug builds if the component already exists.
- Template Parameters:
T – The empty component type to add (must satisfy std::is_empty_v)
-
template<typename T, typename ...Func>
inline T &patch_component(Func&&... func)¶ Modifies a component through EnTT’s patch mechanism.
Applies the provided functors to the component, triggering EnTT’s update signal. This allows systems to register callbacks (via on_component_changed) that react to component modifications.
- Example:
// Modify transform and trigger dirty flag entity.patch_component<TransformComponent>([](auto& t) { t.position += vec3{1, 0, 0}; });
Note
Asserts if the component doesn’t exist.
Note
Use this instead of direct modification when you want change detection.
- Template Parameters:
T – The component type to patch
Func – Functor types that accept T& or const T&
- Parameters:
func – One or more functors to apply to the component
- Returns:
Reference to the modified component
-
template<typename T>
inline void remove_component() const¶ Removes a component from this entity.
Destroys the component and removes it from the entity. Triggers EnTT’s destruction signal, allowing systems to clean up via on_component_removed.
- Example:
if (entity.has_component<TemporaryEffectComponent>()) { entity.remove_component<TemporaryEffectComponent>(); }
Note
Asserts if the component doesn’t exist.
- Template Parameters:
T – The component type to remove
-
void set_parent(Entity parent)¶
Sets the parent of this entity in the hierarchy.
Establishes a parent-child relationship by updating RelationshipComponent. If this entity already has a parent, it’s first removed from that parent’s child list before being added to the new parent.
See also
- Example:
auto player = registry.create_entity(STRING_ID("player")); auto weapon = registry.create_entity(STRING_ID("sword")); weapon.set_parent(player); // weapon is now child of player
- Parameters:
parent – The entity to become this entity’s parent
-
bool remove_child(Entity child)¶
Removes a child from this entity’s child list.
Breaks the parent-child relationship, making the child a top-level entity. The child entity itself is not destroyed, only orphaned.
- Example:
if (player.remove_child(weapon)) { // weapon is no longer attached to player }
- Parameters:
child – The child entity to remove
- Returns:
true if the child was found and removed, false otherwise
-
template<typename T>
inline T &get_component()¶ Retrieves a reference to a component.
Returns a reference to the specified component type. The component must exist or an assertion will fire in debug builds.
- Example:
auto& transform = entity.get_component<TransformComponent>(); transform.position = vec3{10, 0, 0};
Note
Asserts if the component doesn’t exist. Use try_get_component() for optional access.
- Template Parameters:
T – The component type to retrieve
- Returns:
Reference to the component
-
template<typename T>
inline const T &get_component() const¶ Retrieves a const reference to a component.
Note
Asserts if the component doesn’t exist.
- Template Parameters:
T – The component type to retrieve
- Returns:
Const reference to the component
-
template<typename T>
inline T *try_get_component()¶ Attempts to retrieve a pointer to a component.
Returns a pointer to the component if it exists, or nullptr if not. This is the safe way to access optional components without assertions.
- Example:
if (auto* armor = entity.try_get_component<ArmorComponent>()) { armor->durability -= damage; } else { // Entity has no armor, apply damage directly to health }
- Template Parameters:
T – The component type to retrieve
- Returns:
Pointer to the component, or nullptr if not found
-
template<typename T>
inline const T *try_get_component() const¶ Attempts to retrieve a const pointer to a component.
- Template Parameters:
T – The component type to retrieve
- Returns:
Const pointer to the component, or nullptr if not found
-
template<typename ...T>
inline bool has_component() const¶ Checks if the entity has all specified components.
Returns true only if the entity possesses all of the specified component types. Supports checking multiple components at once.
- Example:
if (entity.has_component<TransformComponent, RenderComponent>()) { // Entity is renderable }
- Template Parameters:
T – Component types to check for
- Returns:
true if all components exist, false otherwise
-
template<typename ...T>
inline bool has_any() const¶ Checks if the entity has any of the specified components.
Returns true if the entity possesses at least one of the specified component types.
- Example:
if (entity.has_any<HealthComponent, ShieldComponent>()) { // Entity has some form of protection }
- Template Parameters:
T – Component types to check for
- Returns:
true if any component exists, false otherwise
-
bool is_valid() const¶
Checks if this entity handle is valid.
An entity is invalid if it’s default-constructed or if the underlying entity has been destroyed.
- Returns:
true if the entity is valid, false otherwise
-
entt::entity get_id() const¶
Returns the raw EnTT entity identifier.
- Returns:
The underlying entt::entity ID
-
StringId get_name() const¶
Returns the entity’s name.
- Returns:
The entity’s StringId name, or “Unnamed” if no NameComponent exists
-
operator uint32_t() const¶
Converts the entity to its numeric ID.
- Returns:
The entity ID as uint32_t
-
operator entt::entity() const¶
Converts to the raw EnTT entity type.
- Returns:
The underlying entt::entity
-
operator bool() const¶
Checks validity via bool conversion.
- Returns:
true if the entity is valid
-
bool operator==(const Entity &other) const¶
Compares two entities for equality.
- Parameters:
other – The entity to compare against
- Returns:
true if both entities refer to the same underlying entity
-
Entity get_parent() const¶
Returns this entity’s parent.
- Returns:
The parent entity, or an invalid entity if no parent exists
-
entt::entity get_parent_id() const¶
Returns the raw EnTT ID of this entity’s parent.
- Returns:
The parent’s entity ID, or entt::null if no parent
-
ChildRange children() const¶
Returns a range of direct children.
Provides an iterable range over this entity’s immediate children. Uses ChildIterator which traverses the sibling linked list.
See also
- Example:
for (auto child : entity.children()) { child.get_component<TransformComponent>().update(); }
- Returns:
ChildRange for use with range-based for loops
-
RecursiveChildRange descendants() const¶
Returns a range of all descendants (recursive).
Provides an iterable range over this entity’s entire subtree using depth-first traversal. Uses RecursiveChildIterator with internal stack.
See also
- Example:
// Disable all entities in the subtree for (auto descendant : entity.descendants()) { descendant.add_component<DisabledTag>(); }
- Returns:
RecursiveChildRange for use with range-based for loops
-
bool is_ancestor_of(Entity other) const¶
Checks if this entity is an ancestor of another.
- Parameters:
other – The potential descendant
- Returns:
true if other is a descendant of this entity
-
bool is_descendant_of(Entity other) const¶
Checks if this entity is a descendant of another.
- Parameters:
other – The potential ancestor
- Returns:
true if this entity is a descendant of other
-
entt::registry &get_registry() const¶
Returns the registry containing this entity.
- Returns:
Reference to the entt::registry