Template Class System

Nested Relationships

Nested Types

Inheritance Relationships

Base Type

Class Documentation

template<typename Derived, ComponentOwnership... Components>
class System : public portal::ecs::SystemBase

CRTP base class for ECS systems that operate on entities with specific components.

System provides a template-based framework for defining game logic that operates on entities possessing certain components. It uses the Curiously Recurring Template Pattern (CRTP) to achieve static polymorphism without virtual dispatch overhead.

The class template accepts a Derived type (the system implementation) and a pack of ComponentOwnership wrappers (Owns<T> or Views<T>) that specify which components the system operates on and their access semantics.

See also

SystemBase for execution policy management

See also

Owns for owned component wrapper

See also

Views for viewed component wrapper

Component Ownership:

  • Owns<T>: EnTT packs these components for cache-efficient iteration

  • Views<T>: Components accessed but not layout-optimized

Execution Policies:

  • Sequential: void execute(Registry&) or void execute(FrameContext&, Registry&)

  • Parallel: Job<> execute(Registry&, Scheduler&) or variants with FrameContext/Counter

Example - Sequential System:
class MySystem : public System<MySystem, Owns<TransformComponent>> {
public:
    MySystem() : System(ExecutionPolicy::Sequential) {}
    static StringId get_name() { return STRING_ID("MySystem"); }

    void execute(Registry& registry) {
        for (auto [entity, transform] : group(registry).each()) {
            // Process entities
        }
    }
};

Template Parameters:
  • Derived – The derived system class (CRTP parameter)

  • Components – Pack of Owns<T> or Views<T> wrappers specifying component ownership

Public Functions

inline explicit System(const ExecutionPolicy policy = ExecutionPolicy::Sequential)

Constructs a system with the specified execution policy.

Parameters:

policy – The execution policy (Sequential or Parallel). Defaults to Sequential.

inline void register_to(Registry &registry)

Registers the system with the registry.

Sets up the system’s EnTT group for optimized component iteration and registers component lifecycle callbacks if the derived class implements them.

Note

Called automatically by Registry::register_system().

Parameters:

registry – The registry to register with

inline void _execute(FrameContext &context, Registry &registry, jobs::Scheduler &scheduler, jobs::Counter *counter)

Internal execution dispatcher (called by system orchestrator).

Dispatches to the derived system’s execute() method based on the current execution policy and detected method signatures. Handles both sequential and parallel execution, with automatic wrapping of sequential systems as jobs when running in parallel mode.

Note

This is an internal method called by the system orchestrator. do not call it yourself.

Parameters:
  • context – Frame timing and resource context

  • registry – The ECS registry

  • scheduler – Job scheduler for parallel execution

  • counter – Optional job counter for synchronization

Protected Attributes

StringId name

Protected Static Functions

static inline auto group(Registry &registry)

Creates an EnTT group for iterating entities with the system’s components.

Returns a cached EnTT group that provides cache-friendly iteration over entities possessing all components specified in the system’s template parameters. The group is created based on the component ownership semantics (Owns vs Views).

Components wrapped in Owns<T> are treated as owned (packed together for cache locality), while components wrapped in Views<T> are treated as viewed (accessed via indirection).

Example:
class MySystem : public System<
    MySystem,
    Owns<TransformComponent>,
    Views<RenderComponent>
> {
    void execute(Registry& registry) {
        // group() returns entities with both components
        for (auto [entity, transform, render] : group(registry).each()) {
            // TransformComponent access is cache-optimized
            // RenderComponent access may be slower
        }
    }
};

Note

The group is cached by EnTT - subsequent calls return the same optimized view.

Note

This method is called automatically by register_to() to set up storage optimization.

Parameters:

registry – The registry to create the group from

Returns:

EnTT group object for iteration