veloren/server/src/sys/wiring.rs

79 lines
2.4 KiB
Rust
Raw Normal View History

2021-04-15 16:28:16 +00:00
use crate::wiring::{Circuit, WiringElement};
use common::{
comp::{LightEmitter, PhysicsState},
event::{EventBus, ServerEvent},
};
use common_ecs::{Job, Origin, Phase, System};
use hashbrown::HashMap;
use specs::{
join::Join, shred::ResourceId, Entities, Entity, Read, ReadStorage, SystemData, World,
WriteStorage,
};
mod compute_outputs;
use compute_outputs::compute_outputs;
mod dispatch_actions;
use dispatch_actions::dispatch_actions;
#[derive(SystemData)]
pub struct WiringData<'a> {
pub circuits: ReadStorage<'a, Circuit>,
pub wiring_elements: WriteStorage<'a, WiringElement>,
2021-05-05 14:13:38 +00:00
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>>,
2021-04-15 16:28:16 +00:00
}
/// This system is responsible for handling wiring (signals and wiring systems)
#[derive(Default)]
pub struct Sys;
impl<'a> System<'a> for Sys {
type SystemData = WiringData<'a>;
const NAME: &'static str = "wiring";
const ORIGIN: Origin = Origin::Server;
const PHASE: Phase = Phase::Create;
fn run(_job: &mut Job<Self>, mut system_data: Self::SystemData) {
// Calculate new outputs using inputs (those inputs are calculated and populated
// in previous tick) Take inputs and wiring_element.outputs and with
// that compute new outputs
let computed_outputs = compute_outputs(&system_data);
// Pass new outputs as inputs for the next tick
dispatch_circuit_transport(&computed_outputs, &mut system_data);
// Using inputs dispatch actions
dispatch_actions(&mut system_data);
}
}
fn dispatch_circuit_transport<'a>(
computed_outputs: &HashMap<Entity, HashMap<String, f32>>,
system_data: &mut WiringData<'a>,
) {
let WiringData {
circuits,
wiring_elements,
..
} = system_data;
(circuits)
.join()
.map(|circuit| circuit.wires.iter())
.flatten()
.for_each(|wire| {
let input_value = computed_outputs
.get(&wire.input_entity)
.and_then(|e| e.get(&wire.input_field))
.unwrap_or(&0.0);
if let Some(wiring_element) = wiring_elements.get_mut(wire.output_entity) {
wiring_element
.inputs
.insert(wire.output_field.clone(), *input_value);
}
});
}