Class Registry

Inheritance Relationships

Base Type

  • public Module<>

Class Documentation

class Registry : public Module<>

Central registry for all entity and component operations in the Portal ECS.

The Registry class wraps EnTT’s registry and provides Portal-specific patterns and conventions for entity management. It serves as the source of truth for all entity creation, component storage, and system registration.

Key responsibilities:

  • Entity lifecycle management (creation, destruction, lookup)

  • Component storage and access

  • System registration and management

  • Default component configuration (components attached to all entities)

  • Parent-child entity hierarchy support

The Registry automatically attaches default components to all created entities:

See also

Entity for component access and manipulation

See also

System for defining game logic that operates on entities

Example Usage:
Registry registry;

// Create a top-level entity
auto player = registry.create_entity(STRING_ID("player"));
player.add_component<HealthComponent>(100.0f);

// Create a child entity (e.g., weapon attached to player)
auto weapon = registry.create_child_entity(player, STRING_ID("sword"));

// Register a system
auto& physics_system = registry.register_system<PhysicsSystem>();

// Access components via views
for (auto entity : registry.view<TransformComponent, RenderComponent>()) {
    auto& transform = entity.get_component<TransformComponent>();
    // Process entity...
}

Note

All entity creation methods ensure default components are attached automatically.

Note

The Registry maintains an “env” entity for global/environmental state.

Public Functions

Registry(ModuleStack &stack)

Constructs the Registry and initializes the ECS.

Creates the environment entity and configures default components (RelationshipComponent, TransformComponent) to be attached to all subsequently created entities.

~Registry() override

Destroys the Registry and all associated entities.

Entity entity_from_id(entt::entity id)

Wraps a raw EnTT entity ID in a Portal Entity handle.

Note

This method does not validate that the entity exists.

Parameters:

id – The raw EnTT entity identifier

Returns:

Entity wrapper providing Portal’s component access API

Entity find_or_create(const StringId &entity_name)

Finds an entity by name, or creates it if it doesn’t exist.

Searches for an entity with the specified name in the registry. If found, returns the existing entity. If not found, creates a new top-level entity with that name.

See also

find_or_create_child for scoped creation under a parent

Note

This creates a top-level entity (no parent) if creation is needed.

Parameters:

entity_name – The unique identifier for the entity

Returns:

The found or newly created entity

template<typename ...Components>
inline Entity create_entity(const StringId &name = INVALID_STRING_ID, Components&&... components)

Creates a new top-level entity.

Creates an entity with no default components, only a name component if a name is provided

Example:
auto player = registry.create_entity(STRING_ID("player"));
auto unnamed = registry.create_entity(); // Anonymous entity

Parameters:
  • name – Optional unique identifier for the entity (defaults to INVALID_STRING_ID)

  • components – An optional list of additional components to add to the entity

Returns:

The newly created entity

Entity find_or_create_child(Entity parent, const StringId &entity_name)

Finds a child entity by name, or creates it if it doesn’t exist.

Searches for an entity with the specified name among the children of the given parent. If found, returns the existing child. If not found, creates a new child entity with that name.

Note

The search is scoped to direct children only, not descendants.

Parameters:
  • parent – The parent entity to search under

  • entity_name – The unique identifier for the child entity

Returns:

The found or newly created child entity

Entity create_child_entity(Entity parent, const StringId &entity_name = INVALID_STRING_ID)

Creates a new entity as a child of the specified parent.

Creates an entity and establishes it as a child in the parent-child hierarchy. The entity receives default components and is automatically linked into the parent’s child list via RelationshipComponent.

See also

Entity::set_parent for reparenting existing entities

Example:
auto player = registry.create_entity(STRING_ID("player"));
auto weapon = registry.create_child_entity(player, STRING_ID("sword"));
auto shield = registry.create_child_entity(player, STRING_ID("shield"));

Parameters:
  • parent – The parent entity

  • entity_name – Optional unique identifier for the child entity

Returns:

The newly created child entity

Entity get_env_entity() const

Returns the special environment entity.

The environment entity is a special entity created during Registry construction that holds global or environmental state. It’s useful for singleton components that don’t belong to any particular game entity.

Example:
auto env = registry.get_env_entity();
env.add_component<SomeGlobalComponent>(settings);

Returns:

The environment entity

void destroy_entity(Entity entity, bool exclude_children = false)

Destroys an entity and optionally its children.

Removes the entity from the registry, destroying all its components and breaking its relationships with parent and siblings. By default, all children are also destroyed recursively.

Parameters:
  • entity – The entity to destroy

  • exclude_children – If true, children are orphaned but not destroyed. If false (default), children are destroyed recursively.

void clear()

Clears the entire registy.

Destroys all entites and components from the registry

template<typename C>
inline void clear()

Removes all instances of a component type from the registry.

Destroys all components of the specified type across all entities. This is useful for bulk cleanup or resetting specific component pools.

Example:
// Remove all physics bodies from all entities
registry.clear<PhysicsBodyComponent>();

Note

This does not destroy the entities themselves, only the specified component.

Template Parameters:

C – The component type to clear

template<typename ...T>
inline auto view() const

Creates a view for iterating entities with specific components.

Returns a lazy-evaluated view that iterates all entities possessing all specified component types. Views are not cached and have minimal overhead.

See also

group for cached, optimized iteration

Example:
// Iterate all entities with both Transform and Render components
for (auto entity : registry.view<TransformComponent, RenderComponent>()) {
    auto& transform = entity.get_component<TransformComponent>();
    auto& render = entity.get_component<RenderComponent>();
    // Process entity...
}

Note

Views are lightweight and can be created on-demand each frame.

Note

For performance-critical iteration, consider using groups instead.

Template Parameters:

T – Component types to include in the view

Returns:

A range of Entity objects that can be used with range-based for loops

template<typename ...T>
inline auto group()

Creates an EnTT group for optimized component iteration.

Returns a group that provides cache-friendly iteration over entities with the specified components. Groups maintain sorted storage for maximum performance and are cached internally by EnTT.

See also

group(V&&…) for owned/viewed component distinction

Note

Groups are more efficient than views for frequent iteration.

Note

This overload does not distinguish between owned and viewed components.

Template Parameters:

T – Component types to include in the group

Returns:

An EnTT group object

template<typename ...T, ComponentView... V>
inline auto group(V&&... views)

Creates an EnTT group with owned and viewed component distinction.

Returns a group that optimizes storage layout based on component ownership semantics. Owned components are packed together for cache locality, while viewed components are accessed via indirection.

See also

System for how systems use owned/viewed semantics

Example:
// Group with Transform owned, Render viewed
auto grp = registry.group<TransformComponent>(Views<RenderComponent>{});
for (auto entity : grp) {
    // Efficient iteration over transforms, with render access
}

Note

This is typically called automatically by System::group().

Template Parameters:
  • T – Owned component types (drive iteration, packed storage)

  • V – Viewed component types (accessed but not optimized)

Parameters:

views – Views<Component> wrappers for the viewed components

Returns:

An EnTT group object optimized for the specified ownership pattern

template<typename ...T, typename ...V>
inline auto group(V&&... views)
template<typename C, typename ...Args>
inline void add_default_component(Args&&... args)

Registers a component to be added to all created entities.

Configures the registry to automatically attach the specified component type to every entity created after this call. Arguments are forwarded to the component’s constructor.

Example:
// Make all entities receive a HealthComponent with 100 HP
registry.add_default_component<HealthComponent>(100.0f);

// All entities created after this point will have HealthComponent
auto player = registry.create_entity(STRING_ID("player"));
assert(player.has_component<HealthComponent>());

Note

This only applies to entities created after this function is called.

Note

By default, Registry already adds RelationshipComponent and TransformComponent.

Template Parameters:
  • C – The component type to add by default

  • Args – Argument types for the component constructor

Parameters:

args – Arguments forwarded to the component constructor

template<SystemConcept S, typename ...Args>
inline S register_system(Args&&... args)

Constructs and registers a system with the registry.

Creates a new system instance, registers it with the registry, and returns the system by value.

See also

register_system(S&) for registering existing system instances

Example:
// Register a physics system with Sequential execution
auto physics = registry.register_system<PhysicsSystem>(ExecutionPolicy::Sequential);

// Register a system with custom parameters
auto ai = registry.register_system<AISystem>(difficulty_level);

Note

The system’s register_to() method is called automatically.

Template Parameters:
  • S – The system type (must satisfy SystemConcept)

  • Args – Argument types for the system constructor

Parameters:

args – Arguments forwarded to the system constructor

Returns:

The newly constructed and registered system

template<SystemConcept S>
inline void register_system(S &system)

Registers an existing system instance with the registry.

Calls the system’s register_to() method, which establishes the system’s EnTT group for optimized iteration and connects component lifecycle callbacks.

Example:
MySystem system(ExecutionPolicy::Parallel);
registry.register_system(system);
// System is now registered and ready to execute

Note

This is called automatically by register_system(Args&&…).

Template Parameters:

S – The system type (must satisfy SystemConcept)

Parameters:

system – Reference to the system to register

inline entt::registry &get_raw_registry()

Returns the underlying EnTT registry.

Provides direct access to the wrapped entt::registry for advanced use cases that require EnTT-specific functionality not exposed by the Portal API.

Note

Use this only when Portal’s API is insufficient.

Note

Prefer Portal’s Entity and Registry methods for typical usage.

Returns:

Reference to the internal entt::registry

Public Static Attributes

static constexpr auto ENV_ENTITY_ID = "env"

Protected Functions

template<typename ...Components>
inline Entity make_entity(Components&&... components)