4 releases
0.2.0 | Aug 20, 2022 |
---|---|
0.1.2 | Sep 22, 2021 |
0.1.1 | Sep 22, 2021 |
0.1.0 | Sep 22, 2021 |
#673 in Game dev
16KB
84 lines
hecs-component-provider
Easily define behavior for sets of components when using the hecs ECS library.
use hecs_component_provider::{
default_trait_impl, gen_tuple_query_component_providers,
ComponentProvider, ComponentProviderMut
};
struct Position(f32, f32);
struct Velocity(f32, f32);
struct Enemy { shot_count: i32 };
// implement a behavior for all entities that provide the required components
#[default_trait_impl]
trait ApplyVelocity: ComponentProviderMut<Position> + ComponentProvider<Velocity> {
fn apply_velocity(&mut self, dt: f32) {
let &Velocity(vx, vy) = self.get();
let position: &mut Position = self.get_mut();
position.0 += vx * dt;
position.1 += vy * dt;
}
}
let mut world = hecs::World::new();
world.spawn((Position(1.0, 2.0), Velocity(0.7, 0.8)));
// prepare a query that returns entities with the components required for the behavior
gen_tuple_query_component_providers!(
MovableQuery,
(&mut Position, &Velocity)
);
let dt = 0.1;
for (_, mut entity) in world.query_mut::<MovableQuery>() {
// apply the behavior to the entity
entity.apply_velocity(dt);
let position = entity.0;
assert_eq!(position.0, 1.07);
assert_eq!(position.1, 2.08);
}
// behaviors can depend on one another
#[default_trait_impl]
trait EnemyBehaviors: ApplyVelocity + ComponentProviderMut<Enemy> {
fn shoot_and_move(&mut self, dt: f32) {
self.shoot();
self.apply_velocity(dt);
}
fn shoot(&mut self) {
let enemy: &mut Enemy = self.get_mut();
enemy.shot_count += 1;
}
}
world.spawn((Enemy { shot_count: 0 }, Position(2.0, 3.0), Velocity(-0.7, -0.8)));
// queries can be prepared using structs instead of tuples
#[derive(hecs::Query, ComponentProvider)]
struct EnemyQuery<'a> {
enemy: &'a mut Enemy,
position: &'a mut Position,
velocity: &'a Velocity,
}
let dt = 0.1;
for (_, mut entity) in world.query_mut::<EnemyQuery>() {
// apply the behavior to the entity
entity.shoot_and_move(dt);
assert_eq!(entity.enemy.shot_count, 1);
assert_eq!(entity.position.0, 1.93);
assert_eq!(entity.position.1, 2.92);
}
Dependencies
~4MB
~75K SLoC