Specs is an Entity-Component System written in Rust. It aims for parallel systems execution with high ergonomics and flexibility. The name can be interpret in a number of ways: - "SPECS Parallel ECS" - "Super Powerful ECS" - "Special ECS"
According to ECS Design Crossroads, specs
fulfills all the requirements, has In-place modification updates, and Generational ID entities.
See ecs_bench for single- and multi-threaded performance comparisons.
Component
)! Neither Copy
or even Clone
bounds are needed.rust
let mut planner = {
let mut w = specs::World::new();
// All components types should be registered before working with them
w.register::<Position>();
w.register::<Speed>();
// create_now() of World provides with an EntityBuilder to add components to an Entity
w.create_now().with(Position(0)).with(Speed(2)).build();
w.create_now().with(Position(-1)).with(Speed(100)).build();
w.create_now().with(Position(127)).build();
// Planner is used to run systems on the specified world with as many
// threads as virtual cpus
specs::Planner::new(w)
};
In order to run a system, you can either use a convenience-function (runXwYr
) or a custom one (see below in the section "Custom system" and the examples in the /examples
directory). Convencience-functions are used to request a defined number of mutable and immutable components on an entity. X and Y stand for the number of parameters respectively. run1w1r
will allow you to use one mutable and one immutable component requirement respectively, as you can see below. Run-functions always iterate over all entities of a world with the requested components.
rust
planner.run1w1r(|p: &mut Position, s: &Speed| {
*p += *s;
});
rust
impl System<u32> for MySystem {
fn run(&mut self, arg: RunArg, context: u32) {
let mut numbers = arg.fetch(|w| w.write::<u32>());
for n in (&numbers).join() {
*n += context;
}
}
}