#entity #ecs #es #event-handling #game #ces

nightly entity_rust

Event driven CES framework for Rust with a macro DSL

8 releases

Uses old Rust 2015

0.0.8 Jul 10, 2016
0.0.7 Jun 25, 2016
0.0.1 Apr 5, 2016

#1549 in Rust patterns

37 downloads per month

MIT license

585KB
1.5K SLoC

JavaScript 837 SLoC // 0.2% comments Rust 558 SLoC // 0.0% comments

Entity Rust

This project is just starting to form into something functional. Look in the tests directory for examples on how to use it.

General Idea

General Idea

The project is a DSL and framework for defining components and systems in the traditional ECS style. The systems are event-driven and treat components as resources that are subscribed to. Because the framework is aware of the components that are used by each event handler it can (in theory) schedule events to be handled efficiently in parallel. The DSL and Rust together enforce concurrency- and typesafety of the systems. It should be highly performant (i.e. I wrote this with the goal of implementing massive simulation games like Simcity or Dwarf Fortress). But tests should prove whether I actually achieved this.


lib.rs:

Goal

We want to define components, store them in an efficient manner and make them accessible to systems.

We want to define events along with their types and make them available to systems.

We want to define systems that operate on lists of components, are triggered by other systems through events.

Implementation

For each component type there will be a list that is a tuple of an entity ID and the component values. There will also be a map from entity IDs to component list indexes.

A system will consist of state, iterators over components its subscribed to and any number of functions that are triggered by events.

Syntax

component! { Physics, body: physics.RigidBody, physics_id: physics.ID }

// event! { GameStarted } // This one is implicitly defined
event! { PhysicsTick, dt: u64 }
event! { Bump, e1: EntityID, e2: EntityID }

system! { PhysicsSystem,

  state! { world: physics.World }

  on! { GameStarted, {
     state.world = physics.World::new(event.name);
     state.world.on_collision = |e1, e2| {
       unwrap_entity = |e| { e.user_data.downcast_ref<EntityID>() }
       trigger! { Bump, unwrap_entity(e1), unwrap_entity(e2) }
     };
  }}

  on! { PhysicsTick, {
    state.world.step(event.dt);
  }}

  component_added! { Physics, {
    let id = state.world.add_body(component.body);
    component.physics_id = id;
  }}

  component_removed! { Physics, {
    state.world.remove_body(component.physics_id);
  }}

}

system! { BumpSystem, {
  on! { Bump, {
    println!("Entity {:?} bumped into entity {:?}!", e1, e2);
  }}
}}

Dependencies