update example project entity system component store usage

i think i prefer this style. it's not _technically_ as safe as it was
before, but i prefer the explicitness of it (and it results in a little
bit less nesting in system functions which is nice).

i don't much like the need for an explicit `unwrap()` call however
but that's the tradeoff!
This commit is contained in:
Gered 2023-01-01 12:22:03 -05:00
parent 2b33a64120
commit ed754cb9ac
4 changed files with 389 additions and 371 deletions

View file

@ -95,7 +95,7 @@ fn new_ball_entity(entities: &mut Entities) {
} }
fn update_system_movement(context: &mut Context) { fn update_system_movement(context: &mut Context) {
if let Some(mut positions) = context.entities.components_mut::<Position>() { let mut positions = context.entities.components_mut::<Position>().unwrap();
let velocities = context.entities.components::<Velocity>(); let velocities = context.entities.components::<Velocity>();
for (entity, position) in positions.iter_mut() { for (entity, position) in positions.iter_mut() {
@ -103,15 +103,14 @@ fn update_system_movement(context: &mut Context) {
position.0 += velocity.0 * context.delta; position.0 += velocity.0 * context.delta;
} }
} }
}
} }
fn update_system_collision(context: &mut Context) { fn update_system_collision(context: &mut Context) {
if let Some(bounceable) = context.entities.components::<BouncesAgainstEdge>() { let bounceables = context.entities.components::<BouncesAgainstEdge>().unwrap();
let mut positions = context.entities.components_mut::<Position>(); let mut positions = context.entities.components_mut::<Position>();
let mut velocities = context.entities.components_mut::<Velocity>(); let mut velocities = context.entities.components_mut::<Velocity>();
for (entity, _) in bounceable.iter() { for (entity, _) in bounceables.iter() {
let mut position = positions.get_mut(&entity).unwrap(); let mut position = positions.get_mut(&entity).unwrap();
let mut velocity = velocities.get_mut(&entity).unwrap(); let mut velocity = velocities.get_mut(&entity).unwrap();
@ -130,23 +129,20 @@ fn update_system_collision(context: &mut Context) {
context.event_publisher.queue(Event::CollideAgainstEdge(*entity)); context.event_publisher.queue(Event::CollideAgainstEdge(*entity));
} }
} }
}
} }
fn update_system_lifetime(context: &mut Context) { fn update_system_lifetime(context: &mut Context) {
if let Some(mut lifetimes) = context.entities.components_mut::<LifeLeft>() { let mut lifetimes = context.entities.components_mut::<LifeLeft>().unwrap();
for (entity, lifetime) in lifetimes.iter_mut() { for (entity, lifetime) in lifetimes.iter_mut() {
lifetime.life -= context.delta; lifetime.life -= context.delta;
if lifetime.life < 0.0 { if lifetime.life < 0.0 {
context.event_publisher.queue(Event::Kill(*entity)); context.event_publisher.queue(Event::Kill(*entity));
} }
} }
}
} }
fn update_system_leave_particle_trail(context: &mut Context) { fn update_system_leave_particle_trail(context: &mut Context) {
if let Some(mut leaves_trails) = context.entities.components_mut::<LeavesTrail>() { let mut leaves_trails = context.entities.components_mut::<LeavesTrail>().unwrap();
let positions = context.entities.components::<Position>(); let positions = context.entities.components::<Position>();
for (entity, leaves_trail) in leaves_trails.iter_mut() { for (entity, leaves_trail) in leaves_trails.iter_mut() {
@ -161,12 +157,10 @@ fn update_system_leave_particle_trail(context: &mut Context) {
context.event_publisher.queue(Event::LeaveTrail(trail_position)); context.event_publisher.queue(Event::LeaveTrail(trail_position));
} }
} }
}
} }
fn render_system_sprites(context: &mut Context) { fn render_system_sprites(context: &mut Context) {
if let Some(sprite_indices) = context.entities.components::<SpriteIndex>() { let sprite_indices = context.entities.components::<SpriteIndex>().unwrap();
let positions = context.entities.components::<Position>(); let positions = context.entities.components::<Position>();
for (entity, sprite_index) in sprite_indices.iter() { for (entity, sprite_index) in sprite_indices.iter() {
@ -178,12 +172,10 @@ fn render_system_sprites(context: &mut Context) {
position.0.y as i32 position.0.y as i32
); );
} }
}
} }
fn render_system_particles(context: &mut Context) { fn render_system_particles(context: &mut Context) {
if let Some(particles) = context.entities.components::<Particle>() { let particles = context.entities.components::<Particle>().unwrap();
let positions = context.entities.components::<Position>(); let positions = context.entities.components::<Position>();
let colors = context.entities.components::<Color>(); let colors = context.entities.components::<Color>();
let colors_by_lifetime = context.entities.components::<ColorByLifeTime>(); let colors_by_lifetime = context.entities.components::<ColorByLifeTime>();
@ -217,7 +209,6 @@ fn render_system_particles(context: &mut Context) {
context.system.video.set_pixel(position.0.x as i32, position.0.y as i32, color); context.system.video.set_pixel(position.0.x as i32, position.0.y as i32, color);
} }
} }
}
} }
fn event_handler(event: &Event, context: &mut Context) -> bool { fn event_handler(event: &Event, context: &mut Context) -> bool {
@ -241,6 +232,16 @@ fn event_handler(event: &Event, context: &mut Context) -> bool {
} }
pub fn init_entities(entities: &mut Entities) { pub fn init_entities(entities: &mut Entities) {
entities.init_components::<Position>();
entities.init_components::<Velocity>();
entities.init_components::<SpriteIndex>();
entities.init_components::<BouncesAgainstEdge>();
entities.init_components::<Particle>();
entities.init_components::<Color>();
entities.init_components::<LifeLeft>();
entities.init_components::<LeavesTrail>();
entities.init_components::<ColorByLifeTime>();
entities.remove_all_entities(); entities.remove_all_entities();
for _ in 0..NUM_BALLS { for _ in 0..NUM_BALLS {
new_ball_entity(entities); new_ball_entity(entities);

View file

@ -395,12 +395,45 @@ pub fn init_everything(context: &mut Game, map_file: &Path, min_spawn_time: f32,
} }
pub fn init_entities(entities: &mut Entities) { pub fn init_entities(entities: &mut Entities) {
entities.remove_all_entities(); entities.init_components::<Player>();
entities.init_components::<Weapon>(); entities.init_components::<Slime>();
entities.init_components::<Activity>();
entities.init_components::<AnimationDef>();
entities.init_components::<AnimationInstance>();
entities.init_components::<AnimateByActivity>();
entities.init_components::<KillWhenAnimationFinishes>();
entities.init_components::<Position>();
entities.init_components::<Velocity>();
entities.init_components::<Forces>();
entities.init_components::<Bounds>();
entities.init_components::<FacingDirection>();
entities.init_components::<IgnoresCollision>();
entities.init_components::<IgnoresFriction>();
entities.init_components::<Particle>();
entities.init_components::<LifeTime>();
entities.init_components::<Pixel>();
entities.init_components::<Sprite>();
entities.init_components::<RandomlyWalksAround>();
entities.init_components::<WalkingTime>(); entities.init_components::<WalkingTime>();
entities.init_components::<MovementSpeed>();
entities.init_components::<World>();
entities.init_components::<SpawnTimer>();
entities.init_components::<Camera>();
entities.init_components::<Pushable>(); entities.init_components::<Pushable>();
entities.init_components::<Pusher>(); entities.init_components::<Pusher>();
entities.init_components::<AttachedTo>();
entities.init_components::<Attachment>();
entities.init_components::<AttachmentOffset>();
entities.init_components::<AttachmentOffsetByDirection>();
entities.init_components::<Attackable>();
entities.init_components::<SpriteIndexByDirection>();
entities.init_components::<Weapon>();
entities.init_components::<Life>();
entities.init_components::<TimedFlicker>(); entities.init_components::<TimedFlicker>();
entities.init_components::<HitParticleColor>();
entities.init_components::<Pickupable>();
entities.init_components::<Pickuper>();
entities.remove_all_entities();
} }
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -267,7 +267,7 @@ pub fn pickup(context: &mut Core, picked_up_by: EntityId, picked_up: EntityId) {
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
fn update_system_movement(context: &mut Core) { fn update_system_movement(context: &mut Core) {
if let Some(mut positions) = context.entities.components_mut::<Position>() { let mut positions = context.entities.components_mut::<Position>().unwrap();
let velocities = context.entities.components::<Velocity>(); let velocities = context.entities.components::<Velocity>();
let forces = context.entities.components::<Forces>(); let forces = context.entities.components::<Forces>();
let bounds = context.entities.components::<Bounds>(); let bounds = context.entities.components::<Bounds>();
@ -294,11 +294,10 @@ fn update_system_movement(context: &mut Core) {
} }
} }
} }
}
} }
fn update_system_friction(context: &mut Core) { fn update_system_friction(context: &mut Core) {
if let Some(mut velocities) = context.entities.components_mut::<Velocity>() { let mut velocities = context.entities.components_mut::<Velocity>().unwrap();
let ignores_friction = context.entities.components::<IgnoresFriction>(); let ignores_friction = context.entities.components::<IgnoresFriction>();
for (entity, velocity) in velocities.iter_mut() { for (entity, velocity) in velocities.iter_mut() {
@ -309,15 +308,13 @@ fn update_system_friction(context: &mut Core) {
} }
} }
} }
}
} }
fn update_system_force_decay(context: &mut Core) { fn update_system_force_decay(context: &mut Core) {
if let Some(mut forces) = context.entities.components_mut::<Forces>() { let mut forces = context.entities.components_mut::<Forces>().unwrap();
for (_, force) in forces.iter_mut() { for (_, force) in forces.iter_mut() {
force.decay(); force.decay();
} }
}
} }
fn update_system_pushing(context: &mut Core) { fn update_system_pushing(context: &mut Core) {
@ -355,18 +352,17 @@ fn update_system_pushing(context: &mut Core) {
} }
fn update_system_lifetime(context: &mut Core) { fn update_system_lifetime(context: &mut Core) {
if let Some(mut lifetimes) = context.entities.components_mut::<LifeTime>() { let mut lifetimes = context.entities.components_mut::<LifeTime>().unwrap();
for (entity, lifetime) in lifetimes.iter_mut() { for (entity, lifetime) in lifetimes.iter_mut() {
lifetime.0 -= context.delta; lifetime.0 -= context.delta;
if lifetime.0 < 0.0 { if lifetime.0 < 0.0 {
context.event_publisher.queue(Event::Remove(*entity)); context.event_publisher.queue(Event::Remove(*entity));
} }
} }
}
} }
fn update_system_animation(context: &mut Core) { fn update_system_animation(context: &mut Core) {
if let Some(mut animations) = context.entities.components_mut::<AnimationInstance>() { let mut animations = context.entities.components_mut::<AnimationInstance>().unwrap();
let kill_when_animation_finishes = context.entities.components::<KillWhenAnimationFinishes>(); let kill_when_animation_finishes = context.entities.components::<KillWhenAnimationFinishes>();
for (entity, animation) in animations.iter_mut() { for (entity, animation) in animations.iter_mut() {
@ -402,11 +398,10 @@ fn update_system_animation(context: &mut Core) {
} }
} }
} }
}
} }
fn update_system_set_sprite_index_from_animation(context: &mut Core) { fn update_system_set_sprite_index_from_animation(context: &mut Core) {
if let Some(animations) = context.entities.components::<AnimationInstance>() { let animations = context.entities.components::<AnimationInstance>().unwrap();
let mut sprites = context.entities.components_mut::<Sprite>(); let mut sprites = context.entities.components_mut::<Sprite>();
let facing_directions = context.entities.components::<FacingDirection>(); let facing_directions = context.entities.components::<FacingDirection>();
@ -425,11 +420,10 @@ fn update_system_set_sprite_index_from_animation(context: &mut Core) {
sprite.index = index; sprite.index = index;
} }
} }
}
} }
fn update_system_set_sprite_index_by_direction(context: &mut Core) { fn update_system_set_sprite_index_by_direction(context: &mut Core) {
if let Some(sprite_index_by_directions) = context.entities.components::<SpriteIndexByDirection>() { let sprite_index_by_directions = context.entities.components::<SpriteIndexByDirection>().unwrap();
let mut sprites = context.entities.components_mut::<Sprite>(); let mut sprites = context.entities.components_mut::<Sprite>();
let facing_directions = context.entities.components::<FacingDirection>(); let facing_directions = context.entities.components::<FacingDirection>();
@ -440,11 +434,10 @@ fn update_system_set_sprite_index_by_direction(context: &mut Core) {
} }
} }
} }
}
} }
fn update_system_walking_time(context: &mut Core) { fn update_system_walking_time(context: &mut Core) {
if let Some(mut walking_times) = context.entities.components_mut::<WalkingTime>() { let mut walking_times = context.entities.components_mut::<WalkingTime>().unwrap();
let activities = context.entities.components::<Activity>(); let activities = context.entities.components::<Activity>();
for (entity, walking_time) in walking_times.iter_mut() { for (entity, walking_time) in walking_times.iter_mut() {
@ -462,11 +455,10 @@ fn update_system_walking_time(context: &mut Core) {
// remove walking time components whose timers have elapsed // remove walking time components whose timers have elapsed
walking_times.retain(|_, comp| comp.0 > 0.0); walking_times.retain(|_, comp| comp.0 > 0.0);
}
} }
fn update_system_randomly_walk_around(context: &mut Core) { fn update_system_randomly_walk_around(context: &mut Core) {
if let Some(mut randomly_walk_arounds) = context.entities.components_mut::<RandomlyWalksAround>() { let mut randomly_walk_arounds = context.entities.components_mut::<RandomlyWalksAround>().unwrap();
let activities = context.entities.components::<Activity>(); let activities = context.entities.components::<Activity>();
let mut walking_times = context.entities.components_mut::<WalkingTime>().unwrap(); let mut walking_times = context.entities.components_mut::<WalkingTime>().unwrap();
@ -490,11 +482,10 @@ fn update_system_randomly_walk_around(context: &mut Core) {
} }
} }
} }
}
} }
fn update_system_current_entity_activity(context: &mut Core) { fn update_system_current_entity_activity(context: &mut Core) {
if let Some(activities) = context.entities.components::<Activity>() { let activities = context.entities.components::<Activity>().unwrap();
let velocities = context.entities.components::<Velocity>(); let velocities = context.entities.components::<Velocity>();
for (entity, activity) in activities.iter() { for (entity, activity) in activities.iter() {
@ -516,7 +507,6 @@ fn update_system_current_entity_activity(context: &mut Core) {
} }
} }
} }
}
} }
fn update_system_randomly_spawn_slimes(context: &mut Core) { fn update_system_randomly_spawn_slimes(context: &mut Core) {
@ -557,7 +547,7 @@ fn update_system_camera_follows_player(context: &mut Core) {
} }
fn update_system_turn_attached_entities(context: &mut Core) { fn update_system_turn_attached_entities(context: &mut Core) {
if let Some(attachments) = context.entities.components::<Attachment>() { let attachments = context.entities.components::<Attachment>().unwrap();
let mut facing_directions = context.entities.components_mut::<FacingDirection>(); let mut facing_directions = context.entities.components_mut::<FacingDirection>();
for (parent_entity, attachment) in attachments.iter() { for (parent_entity, attachment) in attachments.iter() {
@ -575,11 +565,10 @@ fn update_system_turn_attached_entities(context: &mut Core) {
facing_direction.0 = parent_facing_direction; facing_direction.0 = parent_facing_direction;
} }
} }
}
} }
fn update_system_position_attached_entities(context: &mut Core) { fn update_system_position_attached_entities(context: &mut Core) {
if let Some(attachments) = context.entities.components::<Attachment>() { let attachments = context.entities.components::<Attachment>().unwrap();
let mut positions = context.entities.components_mut::<Position>(); let mut positions = context.entities.components_mut::<Position>();
let facing_directions = context.entities.components::<FacingDirection>(); let facing_directions = context.entities.components::<FacingDirection>();
let offsets = context.entities.components::<AttachmentOffset>(); let offsets = context.entities.components::<AttachmentOffset>();
@ -610,21 +599,18 @@ fn update_system_position_attached_entities(context: &mut Core) {
} }
} }
} }
}
} }
fn update_system_timed_flicker(context: &mut Core) { fn update_system_timed_flicker(context: &mut Core) {
if let Some(mut timed_flicker) = context.entities.components_mut::<TimedFlicker>() { let mut timed_flickers = context.entities.components_mut::<TimedFlicker>().unwrap();
for (_, flicker) in timed_flicker.iter_mut() { for (_, flicker) in timed_flickers.iter_mut() {
flicker.update(context.delta); flicker.update(context.delta);
} }
timed_flickers.retain(|_, flicker| flicker.timer > 0.0);
timed_flicker.retain(|_, flicker| flicker.timer > 0.0);
}
} }
fn update_system_pickups(context: &mut Core) { fn update_system_pickups(context: &mut Core) {
if let Some(mut pickupables) = context.entities.components_mut::<Pickupable>() { let mut pickupables = context.entities.components_mut::<Pickupable>().unwrap();
let pickupers = context.entities.components::<Pickuper>().unwrap(); let pickupers = context.entities.components::<Pickuper>().unwrap();
let positions = context.entities.components::<Position>(); let positions = context.entities.components::<Position>();
let bounds = context.entities.components::<Bounds>(); let bounds = context.entities.components::<Bounds>();
@ -663,7 +649,6 @@ fn update_system_pickups(context: &mut Core) {
} }
} }
} }
}
} }
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -671,11 +656,11 @@ fn update_system_pickups(context: &mut Core) {
fn render_system_sprites(context: &mut Core) { fn render_system_sprites(context: &mut Core) {
context.sprite_render_list.clear(); context.sprite_render_list.clear();
if let Some(sprites) = context.entities.components::<Sprite>() { let sprites = context.entities.components::<Sprite>().unwrap();
if let Some((_, camera)) = context.entities.components::<Camera>().single() {
let positions = context.entities.components::<Position>().unwrap(); let positions = context.entities.components::<Position>().unwrap();
let timed_flickers = context.entities.components::<TimedFlicker>().unwrap(); let timed_flickers = context.entities.components::<TimedFlicker>().unwrap();
if let Some((_, camera)) = context.entities.components::<Camera>().single() {
// build up list of entities to be rendered with their positions so we can sort them // build up list of entities to be rendered with their positions so we can sort them
// and render these entities with a proper y-based sort order // and render these entities with a proper y-based sort order
for (entity, _) in sprites.iter() { for (entity, _) in sprites.iter() {
@ -716,14 +701,13 @@ fn render_system_sprites(context: &mut Core) {
); );
} }
} }
}
} }
fn render_system_pixels(context: &mut Core) { fn render_system_pixels(context: &mut Core) {
if let Some(pixels) = context.entities.components::<Pixel>() { let pixels = context.entities.components::<Pixel>().unwrap();
if let Some((_, camera)) = context.entities.components::<Camera>().single() {
let positions = context.entities.components::<Position>(); let positions = context.entities.components::<Position>();
if let Some((_, camera)) = context.entities.components::<Camera>().single() {
for (entity, pixel) in pixels.iter() { for (entity, pixel) in pixels.iter() {
if let Some(position) = positions.get(entity) { if let Some(position) = positions.get(entity) {
context.system.video.set_pixel( context.system.video.set_pixel(
@ -734,7 +718,6 @@ fn render_system_pixels(context: &mut Core) {
} }
} }
} }
}
} }
pub fn init_component_system(cs: &mut ComponentSystems<Core, Core>) { pub fn init_component_system(cs: &mut ComponentSystems<Core, Core>) {

View file

@ -50,35 +50,32 @@ pub struct Color(u8);
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
pub fn update_system_movement(context: &mut Core) { pub fn update_system_movement(context: &mut Core) {
if let Some(mut positions) = context.entities.components_mut::<Position>() { let mut positions = context.entities.components_mut::<Position>().unwrap();
let velocities = context.entities.components::<Velocity>().unwrap(); let velocities = context.entities.components::<Velocity>().unwrap();
for (entity, position) in positions.iter_mut() { for (entity, position) in positions.iter_mut() {
let velocity = velocities.get(entity).unwrap(); let velocity = velocities.get(entity).unwrap();
position.0 += velocity.0 * context.delta; position.0 += velocity.0 * context.delta;
} }
}
} }
pub fn update_system_remove_offscreen(context: &mut Core) { pub fn update_system_remove_offscreen(context: &mut Core) {
if let Some(positions) = context.entities.components::<Position>() { let positions = context.entities.components::<Position>().unwrap();
for (entity, position) in positions.iter() { for (entity, position) in positions.iter() {
if !context.system.video.is_xy_visible(position.0.x as i32, position.0.y as i32) { if !context.system.video.is_xy_visible(position.0.x as i32, position.0.y as i32) {
context.event_publisher.queue(Event::Remove(*entity)); context.event_publisher.queue(Event::Remove(*entity));
} }
} }
}
} }
pub fn render_system_pixels(context: &mut Core) { pub fn render_system_pixels(context: &mut Core) {
if let Some(positions) = context.entities.components::<Position>() { let positions = context.entities.components::<Position>().unwrap();
let colors = context.entities.components::<Color>().unwrap(); let colors = context.entities.components::<Color>().unwrap();
for (entity, position) in positions.iter() { for (entity, position) in positions.iter() {
let color = colors.get(entity).unwrap(); let color = colors.get(entity).unwrap();
context.system.video.set_pixel(position.0.x as i32, position.0.y as i32, color.0); context.system.video.set_pixel(position.0.x as i32, position.0.y as i32, color.0);
} }
}
} }
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
@ -87,6 +84,10 @@ pub struct DemoState;
impl DemoState { impl DemoState {
fn init(&mut self, context: &mut Game) { fn init(&mut self, context: &mut Game) {
context.core.entities.init_components::<Position>();
context.core.entities.init_components::<Velocity>();
context.core.entities.init_components::<Color>();
context.component_systems.reset(); context.component_systems.reset();
context.component_systems.add_update_system(update_system_movement); context.component_systems.add_update_system(update_system_movement);
context.component_systems.add_update_system(update_system_remove_offscreen); context.component_systems.add_update_system(update_system_remove_offscreen);