Crate trex [−] [src]
An entity component system inspired by entityx. The core of trex
is the simulation!
macro,
which wires together all of the components, events, and systems. Entity
s and Component
s are
managed through the World
interface. Events are queued and emitted through the Events
interface, which is automatically generated by the simulation!
macro.
Examples
A simple 2D physics simulation.
// lazy_static must be imported manually since Rust does not yet support re-exporting external // macros. #[macro_use] extern crate lazy_static; #[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 } pub struct PhysicsSystem { filter: ComponentFilter, // Used to select entities with the components of interest to this // system. } impl System<Events> for PhysicsSystem { fn new() -> PhysicsSystem { PhysicsSystem { filter: ComponentFilter::new() .with::<Position>() .with::<Velocity>() .with::<Acceleration>(), } } fn update(&mut self, world: &mut World, events: &mut Events, dt: f32) { let dt_secs = dt / 1000.0; for entity in world.filter_entities(&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; } events.halt.emit(trex::Halt); } } simulation! { // The components section takes a set of `Type`: `STATIC` pairs. This maps the // component type to a unique family` used internally by trex`. components: { Position: POSITION, Velocity: VELOCITY, Acceleration: ACCELERATION }, // The events section takes a set of `field`: `Type` pairs. This creates a new event queue // field on the Events object for the given event type. events: { }, // The systems section takes a set of `field`: `System` pairs. This creates a new field on // the Simulation for the given system. systems: { physics: PhysicsSystem } } fn main() { let mut simulation = Simulation::new(); simulation.setup(|world, events| { // 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 }); }); // Run a single iteration of the simulation. simulation.update(1000.0); let entity = simulation.world.lookup("Test").unwrap(); let pos = simulation.world.get::<Position>(entity).unwrap(); assert_eq!(pos.x, 9.0); assert_eq!(pos.y, 12.0); assert!(simulation.received_halt()); }
Macros
component! |
Used to implement the component trait for a given type. This macro should never be called
manually. Concrete components should be passed into the |
simulation! |
The core wiring for entity component systems built on |
Structs
ComponentFilter |
Used to filter the list of entities based on the components that are attached to them. |
EventQueue |
Allows for emitting events and iterating over them in the order that they were emitted. Events are immutable and queues are not flushed until the end of the frame, so multiple clients can receive events from the same queue. |
Halt |
Internal event used to stop the |
World |
Contains all entities and their components. |
Traits
Component |
Trait implemented by all components in order to distinguish stores of different components.
this trait should never by implemented manually. Concrete components should be passed into the
|
System |
Trait that must be implemented by all systems in the |
Functions
calc_millis |
Helper function for calculating the time in milliseconds since the last update. |
next_family |
Generates the next unique family. This method should never be called manually. Concrete
components should be passed into the |
Type Definitions
Entity |
Used to group components. |
Family |
The unique family of a component. |