Skip to main content

System

Trait System 

Source
pub trait System: Send {
    // Required methods
    fn name(&self) -> &'static str;
    fn run(&mut self, world: &mut World);

    // Provided methods
    fn component_access(&self) -> Access { ... }
    fn initialize(&mut self, _world: &mut World) { ... }
    fn should_run(&self, _world: &World) -> bool { ... }
    fn is_read_only(&self) -> bool { ... }
}
Expand description

A trait for types that can be run as systems on a World.

Systems are the behavior layer of the ECS. They operate on entities and components, implementing game logic, physics, rendering, and more.

§Requirements

Systems must be Send to enable future parallel execution. This means all data accessed by the system must be thread-safe.

§Implementing System

For simple systems, implement this trait directly:

use goud_engine::ecs::{World};
use goud_engine::ecs::system::System;

struct CountEntities {
    count: u32,
}

impl System for CountEntities {
    fn name(&self) -> &'static str {
        "CountEntities"
    }

    fn run(&mut self, world: &mut World) {
        self.count = world.entity_count() as u32;
    }
}

§Access Tracking

Override component_access() to declare what components your system reads and writes. This enables the scheduler to detect conflicts and run non-conflicting systems in parallel.

use goud_engine::ecs::{World, Component, ComponentId};
use goud_engine::ecs::system::System;
use goud_engine::ecs::query::Access;

#[derive(Clone, Copy)]
struct Position { x: f32, y: f32 }
impl Component for Position {}

#[derive(Clone, Copy)]
struct Velocity { x: f32, y: f32 }
impl Component for Velocity {}

struct MovementSystem;

impl System for MovementSystem {
    fn name(&self) -> &'static str {
        "MovementSystem"
    }

    fn component_access(&self) -> Access {
        let mut access = Access::new();
        access.add_write(ComponentId::of::<Position>());
        access.add_read(ComponentId::of::<Velocity>());
        access
    }

    fn run(&mut self, world: &mut World) {
        // Movement logic here
    }
}

§Lifecycle

Systems have optional lifecycle hooks:

  • initialize(): Called once when the system is first added
  • run(): Called each time the system executes

§Thread Safety

The Send bound ensures systems can be sent between threads. However, the scheduler ensures only one system runs on a World at a time (for now).

Required Methods§

Source

fn name(&self) -> &'static str

Returns the name of this system.

Used for debugging, logging, and profiling. Should be a short, descriptive name.

Source

fn run(&mut self, world: &mut World)

Runs the system on the given world.

This is called each frame (or each time the system’s stage runs). Implement your system logic here.

§Arguments
  • world - Mutable reference to the world containing all ECS data

Provided Methods§

Source

fn component_access(&self) -> Access

Returns the component access pattern for this system.

Override this to declare which components your system reads and writes. The default implementation returns empty access (no components).

Accurate access information enables:

  • Parallel execution of non-conflicting systems
  • Compile-time verification of system ordering
  • Runtime conflict detection
Source

fn initialize(&mut self, _world: &mut World)

Called once when the system is first added to a scheduler.

Use this for one-time initialization that requires world access. The default implementation does nothing.

§Arguments
  • world - Mutable reference to the world
Source

fn should_run(&self, _world: &World) -> bool

Returns whether this system should run.

Override this to conditionally skip system execution. The default implementation always returns true.

§Arguments
  • world - Reference to the world (for checking conditions)
§Example
use goud_engine::ecs::{World, Component};
use goud_engine::ecs::system::System;

struct GamePaused;
impl Component for GamePaused {}

struct PhysicsSystem;

impl System for PhysicsSystem {
    fn name(&self) -> &'static str { "PhysicsSystem" }

    fn should_run(&self, world: &World) -> bool {
        // Skip physics when game is paused
        // (In a real implementation, you'd check a resource)
        true
    }

    fn run(&mut self, world: &mut World) {
        // Physics logic
    }
}
Source

fn is_read_only(&self) -> bool

Returns true if this system only reads data.

Read-only systems can potentially run in parallel with other read-only systems. The default implementation delegates to component_access().is_read_only().

Implementors§

Source§

impl System for PhysicsStepSystem2D

Source§

impl System for PhysicsStepSystem3D

Source§

impl System for TransformPropagationSystem

Source§

impl<Marker, F> System for FunctionSystem<Marker, F>
where Marker: 'static, F: SystemParamFunction<Marker> + Send + 'static, F::State: Send + Sync,