mindustry logic execution, map- and schematic- parsing and rendering
Implement block state for power connectors
KosmosPrime 2023-01-12
parent 738bfb7 · commit 34a4c31
-rw-r--r--src/block/power.rs118
-rw-r--r--src/block/simple.rs4
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}
}
}