mindustry logic execution, map- and schematic- parsing and rendering
Implement block state for power connectors
| -rw-r--r-- | src/block/power.rs | 118 | ||||
| -rw-r--r-- | src/block/simple.rs | 4 |
2 files changed, 116 insertions, 6 deletions
diff --git a/src/block/power.rs b/src/block/power.rs index d2a8743..1b4d2ff 100644 --- a/src/block/power.rs +++ b/src/block/power.rs @@ -1,11 +1,16 @@ -use crate::block::make_register; -use crate::block::simple::SimpleBlock; +use std::any::Any; +use std::error::Error; +use std::fmt; + +use crate::block::{BlockLogic, DeserializeError, make_register, SerializeError}; +use crate::block::simple::{SimpleBlock, state_impl}; +use crate::data::dynamic::{DynData, DynType}; make_register! ( - POWER_NODE: "power-node" => SimpleBlock::new(1, true); // TODO config: destination - POWER_NODE_LARGE: "power-node-large" => SimpleBlock::new(2, true); // TODO config: destination - SURGE_TOWER: "surge-tower" => SimpleBlock::new(2, true); // TODO config: destination + POWER_NODE: "power-node" => ConnectorBlock::new(1, 10); + POWER_NODE_LARGE: "power-node-large" => ConnectorBlock::new(2, 15); + SURGE_TOWER: "surge-tower" => ConnectorBlock::new(2, 2); DIODE: "diode" => SimpleBlock::new(1, false); BATTERY: "battery" => SimpleBlock::new(1, true); BATTERY_LARGE: "battery-large" => SimpleBlock::new(3, true); @@ -18,6 +23,107 @@ make_register! SOLAR_PANEL_LARGE: "solar-panel-large" => SimpleBlock::new(3, true); THORIUM_REACTOR: "thorium-reactor" => SimpleBlock::new(3, true); IMPACT_REACTOR: "impact-reactor" => SimpleBlock::new(4, true); - POWER_SOURCE: "power-source" => SimpleBlock::new(1, true); // TODO config: destination + POWER_SOURCE: "power-source" => ConnectorBlock::new(1, 100); POWER_VOID: "power-void" => SimpleBlock::new(1, true); ); + +pub struct ConnectorBlock +{ + size: u8, + max: u8, +} + +impl ConnectorBlock +{ + pub const fn new(size: u8, max: u8) -> Self + { + if size == 0 + { + panic!("invalid size"); + } + if max == 0 || max > i8::MAX as u8 + { + panic!("invalid maximum link count"); + } + Self{size, max} + } + + pub fn get_max_links(&self) -> u8 + { + self.max + } + + state_impl!(pub Vec<(i16, i16)>); +} + +impl BlockLogic for ConnectorBlock +{ + fn get_size(&self) -> u8 + { + self.size + } + + fn is_symmetric(&self) -> bool + { + true + } + + fn data_from_i32(&self, _: i32) -> DynData + { + DynData::Empty + } + + fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> + { + match data + { + DynData::Empty => Ok(Some(Self::create_state(Vec::new()))), + DynData::Point2Array(s) => + { + Ok(Some(Self::create_state(s))) + }, + _ => Err(DeserializeError::InvalidType{have: data.get_type(), expect: DynType::Boolean}), + } + } + + fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> + { + Box::new(Self::get_state(state).clone()) + } + + fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> + { + Ok(DynData::Point2Array(Self::get_state(state).clone())) + } +} + +#[derive(Debug)] +pub enum ConnectorDeserializeError +{ + LinkCount{have: usize, max: u8}, +} + +impl ConnectorDeserializeError +{ + pub fn forward<T, E: Into<Self>>(result: Result<T, E>) -> Result<T, DeserializeError> + { + match result + { + Ok(v) => Ok(v), + Err(e) => Err(DeserializeError::Custom(Box::new(e.into()))), + } + } +} + +impl fmt::Display for ConnectorDeserializeError +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + match self + { + Self::LinkCount{have, max} => write!(f, "Too many links ({have} but only {max} supported)"), + } + } +} + +impl Error for ConnectorDeserializeError {} diff --git a/src/block/simple.rs b/src/block/simple.rs index 87f631f..b45e2bf 100644 --- a/src/block/simple.rs +++ b/src/block/simple.rs @@ -64,6 +64,10 @@ impl SimpleBlock { pub const fn new(size: u8, symmetric: bool) -> Self { + if size == 0 + { + panic!("invalid size"); + } Self{size, symmetric} } } |