(Wiring) Switch to using maybes

This commit is contained in:
Daniel Mizerski 2021-05-05 16:13:38 +02:00
parent 3ddbb479f2
commit a2a0329440
4 changed files with 99 additions and 81 deletions

View File

@ -1750,27 +1750,36 @@ fn handle_spawn_wiring(
let builder2 = server let builder2 = server
.state .state
.create_wiring(pos, comp::object::Body::Coins, WiringElement { .create_wiring(pos, comp::object::Body::Coins, WiringElement {
actions: vec![WiringAction { actions: vec![
formula: wiring::OutputFormula::Input { WiringAction {
name: String::from("color"), formula: wiring::OutputFormula::Input {
}, name: String::from("color"),
threshold: 1.0, },
effects: vec![ threshold: 1.0,
// Another demo: effects: vec![WiringActionEffect::SpawnProjectile {
// 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 {
constr: comp::ProjectileConstructor::Arrow { constr: comp::ProjectileConstructor::Arrow {
damage: 1.0, damage: 1.0,
energy_regen: 0.0, energy_regen: 0.0,
knockback: 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(), inputs: HashMap::new(),
outputs: HashMap::new(), outputs: HashMap::new(),
}); });

View File

@ -16,12 +16,15 @@ use dispatch_actions::dispatch_actions;
#[derive(SystemData)] #[derive(SystemData)]
pub struct WiringData<'a> { pub struct WiringData<'a> {
pub entities: Entities<'a>,
pub event_bus: Read<'a, EventBus<ServerEvent>>,
pub circuits: ReadStorage<'a, Circuit>, pub circuits: ReadStorage<'a, Circuit>,
pub wiring_elements: WriteStorage<'a, WiringElement>, 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<ServerEvent>>,
} }
/// This system is responsible for handling wiring (signals and wiring systems) /// This system is responsible for handling wiring (signals and wiring systems)

View File

@ -2,7 +2,7 @@ use super::WiringData;
use crate::wiring::OutputFormula; use crate::wiring::OutputFormula;
use common::comp::PhysicsState; use common::comp::PhysicsState;
use hashbrown::HashMap; use hashbrown::HashMap;
use specs::{join::Join, Entity, ReadStorage}; use specs::{join::Join, Entity};
use tracing::warn; use tracing::warn;
pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<String, f32>> { pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<String, f32>> {
@ -12,9 +12,9 @@ pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<Stri
physics_states, physics_states,
.. ..
} = system_data; } = system_data;
(&*entities, wiring_elements) (&*entities, wiring_elements, physics_states.maybe())
.join() .join()
.map(|(entity, wiring_element)| { .map(|(entity, wiring_element, physics_state)| {
( (
entity, entity,
wiring_element wiring_element
@ -26,8 +26,7 @@ pub fn compute_outputs(system_data: &WiringData) -> HashMap<Entity, HashMap<Stri
key, key,
output_formula, output_formula,
&wiring_element.inputs, &wiring_element.inputs,
entity, physics_state,
physics_states,
) )
}, // (String, f32) }, // (String, f32)
) )
@ -44,20 +43,18 @@ pub fn compute_output_with_key(
key: &str, key: &str,
output_formula: &OutputFormula, output_formula: &OutputFormula,
inputs: &HashMap<String, f32>, inputs: &HashMap<String, f32>,
entity: Entity, physics_state: Option<&PhysicsState>,
physics_states: &ReadStorage<PhysicsState>,
) -> (String, f32) { ) -> (String, f32) {
( (
key.to_string(), key.to_string(),
compute_output(output_formula, inputs, entity, physics_states), compute_output(output_formula, inputs, physics_state),
) )
} }
pub fn compute_output( pub fn compute_output(
output_formula: &OutputFormula, output_formula: &OutputFormula,
inputs: &HashMap<String, f32>, inputs: &HashMap<String, f32>,
entity: Entity, physics_state: Option<&PhysicsState>,
physics_states: &ReadStorage<PhysicsState>,
) -> f32 { ) -> f32 {
match output_formula { match output_formula {
OutputFormula::Constant { value } => *value, OutputFormula::Constant { value } => *value,
@ -70,9 +67,7 @@ pub fn compute_output(
warn!("Not implemented OutputFormula::SineWave"); warn!("Not implemented OutputFormula::SineWave");
0.0 0.0
}, },
OutputFormula::OnCollide { value } => { OutputFormula::OnCollide { value } => output_formula_on_collide(value, physics_state),
output_formula_on_collide(value, entity, physics_states)
},
OutputFormula::OnInteract { .. } => { OutputFormula::OnInteract { .. } => {
warn!("Not implemented OutputFormula::OnInteract"); warn!("Not implemented OutputFormula::OnInteract");
0.0 0.0
@ -80,12 +75,8 @@ pub fn compute_output(
} }
} }
fn output_formula_on_collide( fn output_formula_on_collide(value: &f32, physics_state: Option<&PhysicsState>) -> f32 {
value: &f32, if let Some(ps) = physics_state {
entity: Entity,
physics_states: &ReadStorage<PhysicsState>,
) -> f32 {
if let Some(ps) = physics_states.get(entity) {
if !ps.touch_entities.is_empty() { if !ps.touch_entities.is_empty() {
return *value; return *value;
} }

View File

@ -1,3 +1,5 @@
use std::ops::DerefMut;
use super::{compute_outputs::compute_output, WiringData}; use super::{compute_outputs::compute_output, WiringData};
use crate::wiring::{OutputFormula, WiringActionEffect}; use crate::wiring::{OutputFormula, WiringActionEffect};
use common::{ use common::{
@ -6,7 +8,7 @@ use common::{
util::Dir, util::Dir,
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
use specs::{join::Join, Entity, ReadStorage, WriteStorage}; use specs::{join::Join, Entity};
use tracing::warn; use tracing::warn;
use vek::Rgb; use vek::Rgb;
@ -15,47 +17,54 @@ pub fn dispatch_actions(system_data: &mut WiringData) {
entities, entities,
event_bus, event_bus,
wiring_elements, wiring_elements,
light_emitters,
physics_states, physics_states,
light_emitters,
.. ..
} = system_data; } = system_data;
let mut server_emitter = event_bus.emitter(); let mut server_emitter = event_bus.emitter();
(&*entities, wiring_elements) (
&*entities,
wiring_elements,
physics_states.maybe(),
light_emitters.maybe(),
)
.join() .join()
.for_each(|(entity, wiring_element)| { .for_each(
wiring_element |(entity, wiring_element, physics_state, mut light_emitter)| {
.actions wiring_element
.iter() .actions
.filter(|wiring_action| { .iter()
compute_output( .filter(|wiring_action| {
&wiring_action.formula, compute_output(
&wiring_element.inputs, &wiring_action.formula,
entity, &wiring_element.inputs,
physics_states, physics_state,
) >= wiring_action.threshold ) >= wiring_action.threshold
}) })
.for_each(|wiring_action| { .for_each(|wiring_action| {
dispatch_action( dispatch_action(
entity, entity,
&wiring_element.inputs, &wiring_element.inputs,
&wiring_action.effects, &wiring_action.effects,
&mut server_emitter, &mut server_emitter,
light_emitters, &mut light_emitter,
physics_states, physics_state,
); );
}) })
}) },
)
} }
fn dispatch_action( fn dispatch_action(
entity: Entity, entity: Entity,
source: &HashMap<String, f32>, inputs: &HashMap<String, f32>,
action_effects: &[WiringActionEffect], action_effects: &[WiringActionEffect],
server_emitter: &mut Emitter<ServerEvent>, server_emitter: &mut Emitter<ServerEvent>,
light_emitters: &mut WriteStorage<LightEmitter>,
physics_states: &ReadStorage<PhysicsState>, light_emitter: &mut Option<impl DerefMut<Target = LightEmitter>>,
physics_state: Option<&PhysicsState>,
) { ) {
action_effects action_effects
.iter() .iter()
@ -66,9 +75,14 @@ fn dispatch_action(
WiringActionEffect::SpawnProjectile { constr } => { WiringActionEffect::SpawnProjectile { constr } => {
dispatch_action_spawn_projectile(entity, constr, server_emitter) dispatch_action_spawn_projectile(entity, constr, server_emitter)
}, },
WiringActionEffect::SetLight { r, g, b } => { WiringActionEffect::SetLight { r, g, b } => dispatch_action_set_light(
dispatch_action_set_light(entity, source, r, g, b, light_emitters, physics_states) 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( fn dispatch_action_set_light(
entity: Entity, inputs: &HashMap<String, f32>,
source: &HashMap<String, f32>,
r: &OutputFormula, r: &OutputFormula,
g: &OutputFormula, g: &OutputFormula,
b: &OutputFormula, b: &OutputFormula,
light_emitters: &mut WriteStorage<LightEmitter>, light_emitter: &mut Option<&mut LightEmitter>,
physics_states: &ReadStorage<PhysicsState>,
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, inputs, physics_state);
let computed_r = compute_output(r, source, entity, physics_states); let computed_g = compute_output(g, inputs, physics_state);
let computed_g = compute_output(g, source, entity, physics_states); let computed_b = compute_output(b, inputs, physics_state);
let computed_b = compute_output(b, source, entity, physics_states);
light_emitter.col = Rgb::new(computed_r, computed_g, computed_b); light_emitter.col = Rgb::new(computed_r, computed_g, computed_b);
}
} }