From a2a03294403627e3ce6a4e9d8976c7a6c5e5c7e0 Mon Sep 17 00:00:00 2001 From: Daniel Mizerski Date: Wed, 5 May 2021 16:13:38 +0200 Subject: [PATCH] (Wiring) Switch to using maybes --- server/src/cmd.rs | 41 ++++++---- server/src/sys/wiring.rs | 11 ++- server/src/sys/wiring/compute_outputs.rs | 29 +++---- server/src/sys/wiring/dispatch_actions.rs | 99 +++++++++++++---------- 4 files changed, 99 insertions(+), 81 deletions(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 4828c36c4c..20b5d05b6d 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1750,27 +1750,36 @@ fn handle_spawn_wiring( let builder2 = server .state .create_wiring(pos, comp::object::Body::Coins, WiringElement { - actions: vec![WiringAction { - formula: wiring::OutputFormula::Input { - name: String::from("color"), - }, - threshold: 1.0, - effects: vec![ - // Another demo: - // WiringActionEffect::SetLight { - // r: wiring::OutputFormula::Input { name: String::from("color") }, - // g: wiring::OutputFormula::Input { name: String::from("color") }, - // b: wiring::OutputFormula::Input { name: String::from("color") } - // }, - WiringActionEffect::SpawnProjectile { + actions: vec![ + WiringAction { + formula: wiring::OutputFormula::Input { + name: String::from("color"), + }, + threshold: 1.0, + effects: vec![WiringActionEffect::SpawnProjectile { constr: comp::ProjectileConstructor::Arrow { damage: 1.0, energy_regen: 0.0, knockback: 0.0, }, - }, - ], - }], + }], + }, + WiringAction { + formula: wiring::OutputFormula::Constant { value: 1.0 }, + threshold: 1.0, + effects: vec![WiringActionEffect::SetLight { + r: wiring::OutputFormula::Input { + name: String::from("color"), + }, + g: wiring::OutputFormula::Input { + name: String::from("color"), + }, + b: wiring::OutputFormula::Input { + name: String::from("color"), + }, + }], + }, + ], inputs: HashMap::new(), outputs: HashMap::new(), }); diff --git a/server/src/sys/wiring.rs b/server/src/sys/wiring.rs index 257e440177..9049755000 100644 --- a/server/src/sys/wiring.rs +++ b/server/src/sys/wiring.rs @@ -16,12 +16,15 @@ use dispatch_actions::dispatch_actions; #[derive(SystemData)] pub struct WiringData<'a> { - pub entities: Entities<'a>, - pub event_bus: Read<'a, EventBus>, pub circuits: ReadStorage<'a, Circuit>, pub wiring_elements: WriteStorage<'a, WiringElement>, - pub light_emitters: WriteStorage<'a, LightEmitter>, - pub physics_states: ReadStorage<'a, PhysicsState>, + + pub entities: Entities<'a>, + + pub light_emitters: WriteStorage<'a, LightEmitter>, // maybe + pub physics_states: ReadStorage<'a, PhysicsState>, // maybe + + pub event_bus: Read<'a, EventBus>, } /// This system is responsible for handling wiring (signals and wiring systems) diff --git a/server/src/sys/wiring/compute_outputs.rs b/server/src/sys/wiring/compute_outputs.rs index 34faac7e66..d4d8e44f01 100644 --- a/server/src/sys/wiring/compute_outputs.rs +++ b/server/src/sys/wiring/compute_outputs.rs @@ -2,7 +2,7 @@ use super::WiringData; use crate::wiring::OutputFormula; use common::comp::PhysicsState; use hashbrown::HashMap; -use specs::{join::Join, Entity, ReadStorage}; +use specs::{join::Join, Entity}; use tracing::warn; pub fn compute_outputs(system_data: &WiringData) -> HashMap> { @@ -12,9 +12,9 @@ pub fn compute_outputs(system_data: &WiringData) -> HashMap HashMap, - entity: Entity, - physics_states: &ReadStorage, + physics_state: Option<&PhysicsState>, ) -> (String, f32) { ( key.to_string(), - compute_output(output_formula, inputs, entity, physics_states), + compute_output(output_formula, inputs, physics_state), ) } pub fn compute_output( output_formula: &OutputFormula, inputs: &HashMap, - entity: Entity, - physics_states: &ReadStorage, + physics_state: Option<&PhysicsState>, ) -> f32 { match output_formula { OutputFormula::Constant { value } => *value, @@ -70,9 +67,7 @@ pub fn compute_output( warn!("Not implemented OutputFormula::SineWave"); 0.0 }, - OutputFormula::OnCollide { value } => { - output_formula_on_collide(value, entity, physics_states) - }, + OutputFormula::OnCollide { value } => output_formula_on_collide(value, physics_state), OutputFormula::OnInteract { .. } => { warn!("Not implemented OutputFormula::OnInteract"); 0.0 @@ -80,12 +75,8 @@ pub fn compute_output( } } -fn output_formula_on_collide( - value: &f32, - entity: Entity, - physics_states: &ReadStorage, -) -> f32 { - if let Some(ps) = physics_states.get(entity) { +fn output_formula_on_collide(value: &f32, physics_state: Option<&PhysicsState>) -> f32 { + if let Some(ps) = physics_state { if !ps.touch_entities.is_empty() { return *value; } diff --git a/server/src/sys/wiring/dispatch_actions.rs b/server/src/sys/wiring/dispatch_actions.rs index 821b525c38..0518c83660 100644 --- a/server/src/sys/wiring/dispatch_actions.rs +++ b/server/src/sys/wiring/dispatch_actions.rs @@ -1,3 +1,5 @@ +use std::ops::DerefMut; + use super::{compute_outputs::compute_output, WiringData}; use crate::wiring::{OutputFormula, WiringActionEffect}; use common::{ @@ -6,7 +8,7 @@ use common::{ util::Dir, }; use hashbrown::HashMap; -use specs::{join::Join, Entity, ReadStorage, WriteStorage}; +use specs::{join::Join, Entity}; use tracing::warn; use vek::Rgb; @@ -15,47 +17,54 @@ pub fn dispatch_actions(system_data: &mut WiringData) { entities, event_bus, wiring_elements, - light_emitters, physics_states, + light_emitters, .. } = system_data; let mut server_emitter = event_bus.emitter(); - (&*entities, wiring_elements) + ( + &*entities, + wiring_elements, + physics_states.maybe(), + light_emitters.maybe(), + ) .join() - .for_each(|(entity, wiring_element)| { - wiring_element - .actions - .iter() - .filter(|wiring_action| { - compute_output( - &wiring_action.formula, - &wiring_element.inputs, - entity, - physics_states, - ) >= wiring_action.threshold - }) - .for_each(|wiring_action| { - dispatch_action( - entity, - &wiring_element.inputs, - &wiring_action.effects, - &mut server_emitter, - light_emitters, - physics_states, - ); - }) - }) + .for_each( + |(entity, wiring_element, physics_state, mut light_emitter)| { + wiring_element + .actions + .iter() + .filter(|wiring_action| { + compute_output( + &wiring_action.formula, + &wiring_element.inputs, + physics_state, + ) >= wiring_action.threshold + }) + .for_each(|wiring_action| { + dispatch_action( + entity, + &wiring_element.inputs, + &wiring_action.effects, + &mut server_emitter, + &mut light_emitter, + physics_state, + ); + }) + }, + ) } fn dispatch_action( entity: Entity, - source: &HashMap, + inputs: &HashMap, action_effects: &[WiringActionEffect], server_emitter: &mut Emitter, - light_emitters: &mut WriteStorage, - physics_states: &ReadStorage, + + light_emitter: &mut Option>, + physics_state: Option<&PhysicsState>, ) { action_effects .iter() @@ -66,9 +75,14 @@ fn dispatch_action( WiringActionEffect::SpawnProjectile { constr } => { dispatch_action_spawn_projectile(entity, constr, server_emitter) }, - WiringActionEffect::SetLight { r, g, b } => { - dispatch_action_set_light(entity, source, r, g, b, light_emitters, physics_states) - }, + WiringActionEffect::SetLight { r, g, b } => dispatch_action_set_light( + inputs, + r, + g, + b, + &mut light_emitter.as_deref_mut(), + physics_state, + ), }); } @@ -91,21 +105,22 @@ fn dispatch_action_spawn_projectile( } fn dispatch_action_set_light( - entity: Entity, - source: &HashMap, + inputs: &HashMap, r: &OutputFormula, g: &OutputFormula, b: &OutputFormula, - light_emitters: &mut WriteStorage, - physics_states: &ReadStorage, + light_emitter: &mut Option<&mut LightEmitter>, + + physics_state: Option<&PhysicsState>, ) { - let mut light_emitter = light_emitters.get_mut(entity).unwrap(); + if let Some(light_emitter) = light_emitter { + // TODO: make compute_output accept multiple formulas - // TODO: make compute_output accept multiple formulas - let computed_r = compute_output(r, source, entity, physics_states); - let computed_g = compute_output(g, source, entity, physics_states); - let computed_b = compute_output(b, source, entity, physics_states); + let computed_r = compute_output(r, inputs, physics_state); + let computed_g = compute_output(g, inputs, physics_state); + let computed_b = compute_output(b, inputs, physics_state); - light_emitter.col = Rgb::new(computed_r, computed_g, computed_b); + light_emitter.col = Rgb::new(computed_r, computed_g, computed_b); + } }