Crate trex [] [src]

An entity component system inspired by entityx.

Examples

A simple 2D physics simulation.

#[macro_use]
extern crate trex;

use trex::*;

// The components used in the simulation.
pub struct Position { pub x: f32, pub y: f32 }
pub struct Velocity { pub dx: f32, pub dy: f32 }
pub struct Acceleration { pub ddx: f32, pub ddy: f32 }

components!(Position, Velocity, Acceleration);

pub struct PhysicsSystem {
    filter: ComponentFilter, // Used to select entities with the components of interest to this
                             // system.
}

impl PhysicsSystem {
    pub fn new() -> PhysicsSystem {
        PhysicsSystem {
            filter: ComponentFilter::new()
                .with::<Position>()
                .with::<Velocity>()
                .with::<Acceleration>(),
        }
    }
}

impl System for PhysicsSystem {
    fn update(&mut self, world: &mut World, queue: &EventQueue, emitter: &mut EventEmitter, dt: f32) {
        let dt_secs = dt / 1000.0;
        for entity in world.filter(&self.filter) {
            assert!(world.has::<Position>(entity));
            assert!(world.has::<Velocity>(entity));
            assert!(world.has::<Acceleration>(entity));
            let (dx, dy) = {
                let &Acceleration { ddx, ddy } = world.get::<Acceleration>(entity).unwrap();
                let mut vel = world.get_mut::<Velocity>(entity).unwrap();
                vel.dx += ddx * dt_secs;
                vel.dy += ddy * dt_secs;
                (vel.dx, vel.dy)
            };
            let mut pos = world.get_mut::<Position>(entity).unwrap();
            pos.x += dx * dt_secs;
            pos.y += dy * dt_secs;
        }
        emitter.emit(trex::Halt);
    }
}

struct TestSystem;

impl System for TestSystem {
    fn update(&mut self, world: &mut World, _queue: &EventQueue, _emitter: &mut EventEmitter, _dt: f32) {
        let entity = world.lookup("Test").unwrap();
        let pos = world.get::<Position>(entity).unwrap();
        assert_eq!(pos.x, 9.0);
        assert_eq!(pos.y, 12.0);
    }
}

fn main() {
    let world = {
        let mut world = World::new();
        world.register::<Position>();
        world.register::<Velocity>();
        world.register::<Acceleration>();

        // Create an entity that accelerates in the x and y directions.
        let entity = world.create();
        world.tag(entity, "Test");
        world.add(entity, Position { x: 1.0, y: 2.0 });
        world.add(entity, Velocity { dx: 3.0, dy: 4.0 });
        world.add(entity, Acceleration { ddx: 5.0, ddy: 6.0 });
        world
    };

    let mut queue = EventQueue::new();
    let mut emitter = EventEmitter::new();

    let mut simulation = Simulation::new(world, queue, emitter);
    simulation.register(PhysicsSystem::new());
    simulation.register(TestSystem);

    // Run a single iteration of the simulation.
    simulation.update(1000.0);
    assert!(simulation.halt());
}

Macros

components

Defines the component family.

events

Defines the event family.

Structs

ComponentFilter

Used to filter the list of entities based on the components that are attached to them.

EventEmitter

Used to emit registered events.

EventQueue

Used to receive registered events.

Halt

Internal event used to stop the Simulation. This event is automatically registered.

Simulation

Responsible for updating and passing events between systems.

World

Contains all entities and their components.

Traits

FamilyMember

Used to identify types that are members of a group of types.

System

Trait that must be implemented by all systems in the Simulation.

Functions

calc_millis

Helper function for calculating the time in milliseconds since the last update.

Type Definitions

Entity

Used to group components.

Family

A unique identifier for a type that is a member of group of types.