mindustry logic execution, map- and schematic- parsing and rendering
make state Send + Sync
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/block/distribution.rs | 25 | ||||
| -rw-r--r-- | src/block/liquid.rs | 19 | ||||
| -rw-r--r-- | src/block/logic.rs | 32 | ||||
| -rw-r--r-- | src/block/mod.rs | 25 | ||||
| -rw-r--r-- | src/block/payload.rs | 22 | ||||
| -rw-r--r-- | src/block/power.rs | 22 | ||||
| -rw-r--r-- | src/block/simple.rs | 21 | ||||
| -rw-r--r-- | src/block/walls.rs | 13 | ||||
| -rw-r--r-- | src/data/schematic.rs | 25 |
10 files changed, 99 insertions, 107 deletions
@@ -1,6 +1,6 @@ [package] name = "mindus" -version = "1.0.2" +version = "1.0.3" edition = "2021" description = "A library for working with mindustry data formats (eg schematics) (fork of plandustry)" authors = [ diff --git a/src/block/distribution.rs b/src/block/distribution.rs index 1114115..b6bdbc1 100644 --- a/src/block/distribution.rs +++ b/src/block/distribution.rs @@ -1,5 +1,4 @@ //! conveyors ( & ducts ) -use std::any::Any; use std::error::Error; use std::fmt; @@ -16,6 +15,8 @@ use crate::data::GridPos; use crate::item; use crate::item::storage::Storage; +use super::State; + make_register! { "conveyor" => SimpleBlock::new(1, false, cost!(Copper: 1)); "titanium-conveyor" => SimpleBlock::new(1, false, cost!(Copper: 1, Lead: 1, Titanium: 1)); @@ -77,7 +78,7 @@ impl BlockLogic for ItemBlock { Ok(DynData::Content(content::Type::Item, config as u16)) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty => Ok(Some(Self::create_state(None))), DynData::Content(content::Type::Item, id) => Ok(Some(Self::create_state(Some( @@ -93,23 +94,23 @@ impl BlockLogic for ItemBlock { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { let state = Self::get_state(state); Box::new(Self::create_state(*state)) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {} + fn mirror_state(&self, _: &mut State, _: bool, _: bool) {} - fn rotate_state(&self, _: &mut dyn Any, _: bool) {} + fn rotate_state(&self, _: &mut State, _: bool) {} - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { match Self::get_state(state) { None => Ok(DynData::Empty), Some(item) => Ok(DynData::Content(content::Type::Item, (*item).into())), } } - fn draw(&self, category: &str, name: &str, state: Option<&dyn Any>) -> Option<RgbaImage> { + fn draw(&self, category: &str, name: &str, state: Option<&State>) -> Option<RgbaImage> { if !matches!( name, "unloader" | "item-source" | "sorter" | "inverted-sorter" @@ -237,7 +238,7 @@ impl BlockLogic for BridgeBlock { Ok(DynData::Point2(dx, dy)) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty => Ok(Some(Self::create_state(None))), DynData::Point2(dx, dy) => { @@ -261,12 +262,12 @@ impl BlockLogic for BridgeBlock { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { let state = Self::get_state(state); Box::new(Self::create_state(*state)) } - fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool) { + fn mirror_state(&self, state: &mut State, horizontally: bool, vertically: bool) { match Self::get_state_mut(state) { None => (), Some((dx, dy)) => { @@ -280,7 +281,7 @@ impl BlockLogic for BridgeBlock { } } - fn rotate_state(&self, state: &mut dyn Any, clockwise: bool) { + fn rotate_state(&self, state: &mut State, clockwise: bool) { match Self::get_state_mut(state) { None => (), Some((dx, dy)) => { @@ -291,7 +292,7 @@ impl BlockLogic for BridgeBlock { } } - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { match Self::get_state(state) { None => Ok(DynData::Empty), Some((dx, dy)) => Ok(DynData::Point2(*dx, *dy)), diff --git a/src/block/liquid.rs b/src/block/liquid.rs index 758ff0d..ee7b591 100644 --- a/src/block/liquid.rs +++ b/src/block/liquid.rs @@ -1,8 +1,8 @@ //! liquid related things -use std::any::Any; use std::error::Error; use std::fmt; +use super::State; use crate::block::distribution::BridgeBlock; use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock}; use crate::block::{ @@ -72,7 +72,7 @@ impl BlockLogic for FluidBlock { Ok(DynData::Content(content::Type::Fluid, config as u16)) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty => Ok(Some(Self::create_state(None))), DynData::Content(content::Type::Fluid, id) => Ok(Some(Self::create_state(Some( @@ -88,28 +88,23 @@ impl BlockLogic for FluidBlock { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { let state = Self::get_state(state); Box::new(Self::create_state(*state)) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {} + fn mirror_state(&self, _: &mut State, _: bool, _: bool) {} - fn rotate_state(&self, _: &mut dyn Any, _: bool) {} + fn rotate_state(&self, _: &mut State, _: bool) {} - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { match Self::get_state(state) { None => Ok(DynData::Empty), Some(fluid) => Ok(DynData::Content(content::Type::Fluid, (*fluid).into())), } } - fn draw( - &self, - category: &str, - name: &str, - state: Option<&dyn Any>, - ) -> Option<image::RgbaImage> { + fn draw(&self, category: &str, name: &str, state: Option<&State>) -> Option<image::RgbaImage> { let mut p = load(category, name).unwrap(); if let Some(state) = state { if let Some(s) = Self::get_state(state) { diff --git a/src/block/logic.rs b/src/block/logic.rs index a56b564..a37a97f 100644 --- a/src/block/logic.rs +++ b/src/block/logic.rs @@ -1,5 +1,4 @@ //! logic processors and stuff -use std::any::Any; use std::borrow::Cow; use std::error::Error; use std::fmt; @@ -10,6 +9,7 @@ use flate2::{ FlushDecompress, Status, }; +use super::State; use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock}; use crate::block::{ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError, @@ -59,7 +59,7 @@ impl BlockLogic for MessageLogic { Ok(DynData::Empty) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty | DynData::String(None) => Ok(Some(Self::create_state(String::new()))), DynData::String(Some(s)) => Ok(Some(Self::create_state(s))), @@ -70,15 +70,15 @@ impl BlockLogic for MessageLogic { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { Box::new(Self::get_state(state).clone()) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {} + fn mirror_state(&self, _: &mut State, _: bool, _: bool) {} - fn rotate_state(&self, _: &mut dyn Any, _: bool) {} + fn rotate_state(&self, _: &mut State, _: bool) {} - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { Ok(DynData::String(Some(Self::get_state(state).clone()))) } } @@ -110,7 +110,7 @@ impl BlockLogic for SwitchLogic { Ok(DynData::Empty) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty => Ok(Some(Self::create_state(true))), DynData::Boolean(enabled) => Ok(Some(Self::create_state(enabled))), @@ -121,15 +121,15 @@ impl BlockLogic for SwitchLogic { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { Box::new(*Self::get_state(state)) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {} + fn mirror_state(&self, _: &mut State, _: bool, _: bool) {} - fn rotate_state(&self, _: &mut dyn Any, _: bool) {} + fn rotate_state(&self, _: &mut State, _: bool) {} - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { Ok(DynData::Boolean(*Self::get_state(state))) } } @@ -161,7 +161,7 @@ impl BlockLogic for ProcessorLogic { Ok(DynData::Empty) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty => Ok(Some(Self::create_state(ProcessorState::default()))), DynData::ByteArray(arr) => { @@ -240,11 +240,11 @@ impl BlockLogic for ProcessorLogic { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { Box::new(Self::get_state(state).clone()) } - fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool) { + fn mirror_state(&self, state: &mut State, horizontally: bool, vertically: bool) { for link in &mut Self::get_state_mut(state).links { if horizontally { link.x = -link.x; @@ -255,7 +255,7 @@ impl BlockLogic for ProcessorLogic { } } - fn rotate_state(&self, state: &mut dyn Any, clockwise: bool) { + fn rotate_state(&self, state: &mut State, clockwise: bool) { for link in &mut Self::get_state_mut(state).links { let (cdx, cdy) = link.get_pos(); link.x = if clockwise { cdy } else { -cdy }; @@ -263,7 +263,7 @@ impl BlockLogic for ProcessorLogic { } } - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { let state = Self::get_state(state); let mut rbuff = DataWrite::default(); ProcessorSerializeError::forward(rbuff.write_u8(1))?; diff --git a/src/block/mod.rs b/src/block/mod.rs index 47501cc..7480545 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -29,6 +29,7 @@ pub mod storage; pub mod turrets; pub mod walls; +pub type State = Box<dyn Any + Sync + Send>; pub trait BlockLogic { /// mindustry blocks are the same width and height fn get_size(&self) -> u8; @@ -39,17 +40,17 @@ pub trait BlockLogic { fn data_from_i32(&self, config: i32, pos: GridPos) -> Result<DynData, DataConvertError>; - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError>; + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError>; - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any>; + fn clone_state(&self, state: &State) -> State; - fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool); + fn mirror_state(&self, state: &mut State, horizontally: bool, vertically: bool); - fn rotate_state(&self, state: &mut dyn Any, clockwise: bool); + fn rotate_state(&self, state: &mut State, clockwise: bool); - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>; + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError>; - fn draw(&self, _category: &str, _name: &str, _state: Option<&dyn Any>) -> Option<RgbaImage> { + fn draw(&self, _category: &str, _name: &str, _state: Option<&State>) -> Option<RgbaImage> { None } } @@ -212,7 +213,7 @@ impl Block { } /// draw this block, with this state - pub fn image(&self, state: Option<&dyn Any>) -> RgbaImage { + pub fn image(&self, state: Option<&State>) -> RgbaImage { if let Some(p) = self .logic .as_ref() @@ -250,23 +251,23 @@ impl Block { pub(crate) fn deserialize_state( &self, data: DynData, - ) -> Result<Option<Box<dyn Any>>, DeserializeError> { + ) -> Result<Option<State>, DeserializeError> { self.logic.deserialize_state(data) } - pub(crate) fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + pub(crate) fn clone_state(&self, state: &State) -> State { self.logic.clone_state(state) } - pub(crate) fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool) { + pub(crate) fn mirror_state(&self, state: &mut State, horizontally: bool, vertically: bool) { self.logic.mirror_state(state, horizontally, vertically); } - pub(crate) fn rotate_state(&self, state: &mut dyn Any, clockwise: bool) { + pub(crate) fn rotate_state(&self, state: &mut State, clockwise: bool) { self.logic.rotate_state(state, clockwise); } - pub(crate) fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + pub(crate) fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { self.logic.serialize_state(state) } } diff --git a/src/block/payload.rs b/src/block/payload.rs index 7377d2c..dad89e7 100644 --- a/src/block/payload.rs +++ b/src/block/payload.rs @@ -1,5 +1,4 @@ //! payload related bits and bobs -use std::any::Any; use std::error::Error; use std::fmt; @@ -13,6 +12,7 @@ use crate::data::dynamic::{DynData, DynType}; use crate::data::GridPos; use crate::item::storage::Storage; use crate::unit; +use super::State; const GROUND_UNITS: &[unit::Type] = &[unit::Type::Dagger, unit::Type::Crawler, unit::Type::Nova]; const AIR_UNITS: &[unit::Type] = &[unit::Type::Flare, unit::Type::Mono]; @@ -95,7 +95,7 @@ impl BlockLogic for AssemblerBlock { Ok(DynData::Int(-1)) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty => Ok(Some(Self::create_state(None))), DynData::Int(idx) => { @@ -119,16 +119,16 @@ impl BlockLogic for AssemblerBlock { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { let state = Self::get_state(state); Box::new(Self::create_state(*state)) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {} + fn mirror_state(&self, _: &mut State, _: bool, _: bool) {} - fn rotate_state(&self, _: &mut dyn Any, _: bool) {} + fn rotate_state(&self, _: &mut State, _: bool) {} - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { if let Some(state) = Self::get_state(state) { for (i, curr) in self.valid.iter().enumerate() { if curr == state { @@ -207,7 +207,7 @@ impl BlockLogic for PayloadBlock { Ok(DynData::Empty) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty => Ok(Some(Self::create_state(Payload::Empty))), DynData::Content(content::Type::Block, id) => { @@ -228,16 +228,16 @@ impl BlockLogic for PayloadBlock { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { let state = Self::get_state(state); Box::new(Self::create_state(*state)) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {} + fn mirror_state(&self, _: &mut State, _: bool, _: bool) {} - fn rotate_state(&self, _: &mut dyn Any, _: bool) {} + fn rotate_state(&self, _: &mut State, _: bool) {} - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { match Self::get_state(state) { Payload::Empty => Ok(DynData::Empty), Payload::Block(block) => Ok(DynData::Content(content::Type::Block, (*block).into())), diff --git a/src/block/power.rs b/src/block/power.rs index 397cb62..ad4f520 100644 --- a/src/block/power.rs +++ b/src/block/power.rs @@ -1,8 +1,8 @@ //! power connection and generation -use std::any::Any; use std::error::Error; use std::fmt; +use super::State; use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock}; use crate::block::{ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError, @@ -81,7 +81,7 @@ impl BlockLogic for ConnectorBlock { Ok(DynData::Empty) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Empty => Ok(Some(Self::create_state(Vec::new()))), DynData::Point2Array(s) => Ok(Some(Self::create_state(s))), @@ -92,11 +92,11 @@ impl BlockLogic for ConnectorBlock { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { Box::new(Self::get_state(state).clone()) } - fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool) { + fn mirror_state(&self, state: &mut State, horizontally: bool, vertically: bool) { for (dx, dy) in Self::get_state_mut(state).iter_mut() { if horizontally { *dx = -*dx; @@ -107,7 +107,7 @@ impl BlockLogic for ConnectorBlock { } } - fn rotate_state(&self, state: &mut dyn Any, clockwise: bool) { + fn rotate_state(&self, state: &mut State, clockwise: bool) { for (dx, dy) in Self::get_state_mut(state).iter_mut() { let (cdx, cdy) = (*dx, *dy); *dx = if clockwise { cdy } else { -cdy }; @@ -115,7 +115,7 @@ impl BlockLogic for ConnectorBlock { } } - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { Ok(DynData::Point2Array(Self::get_state(state).clone())) } } @@ -196,7 +196,7 @@ impl BlockLogic for LampBlock { Ok(DynData::Int(config)) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Int(rgba) => Ok(Some(Self::create_state(RGBA::from(rgba as u32)))), _ => Err(DeserializeError::InvalidType { @@ -206,16 +206,16 @@ impl BlockLogic for LampBlock { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { let state = Self::get_state(state); Box::new(Self::create_state(*state)) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {} + fn mirror_state(&self, _: &mut State, _: bool, _: bool) {} - fn rotate_state(&self, _: &mut dyn Any, _: bool) {} + fn rotate_state(&self, _: &mut State, _: bool) {} - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { let state = Self::get_state(state); Ok(DynData::Int(u32::from(*state) as i32)) } diff --git a/src/block/simple.rs b/src/block/simple.rs index c5d22b0..47e115b 100644 --- a/src/block/simple.rs +++ b/src/block/simple.rs @@ -1,6 +1,7 @@ //! type used for basic blocks, eg turrets and factorys -use std::any::{type_name, Any}; +use std::any::type_name; +use super::State; use crate::block::{impl_block, BlockLogic, DataConvertError, DeserializeError, SerializeError}; use crate::data::dynamic::DynData; use crate::data::renderer::{load, read}; @@ -11,19 +12,19 @@ use crate::item::storage::Storage; macro_rules! state_impl { ($vis:vis $type:ty) => { - $vis fn get_state(state: &dyn Any) -> &$type + $vis fn get_state(state: &$crate::block::State) -> &$type where Self: Sized { state.downcast_ref::<$type>().unwrap() } - $vis fn get_state_mut(state: &mut dyn Any) -> &mut $type + $vis fn get_state_mut(state: &mut $crate::block::State) -> &mut $type where Self: Sized { state.downcast_mut::<$type>().unwrap() } - fn create_state(val: $type) -> Box<dyn Any> + fn create_state(val: $type) -> $crate::block::State where Self: Sized { Box::new(val) @@ -60,27 +61,27 @@ impl BlockLogic for SimpleBlock { Ok(DynData::Empty) } - fn deserialize_state(&self, _: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, _: DynData) -> Result<Option<State>, DeserializeError> { Ok(None) } - fn clone_state(&self, _: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, _: &State) -> State { panic!("{} has no custom state", type_name::<Self>()) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) { + fn mirror_state(&self, _: &mut State, _: bool, _: bool) { panic!("{} has no custom state", type_name::<Self>()); } - fn rotate_state(&self, _: &mut dyn Any, _: bool) { + fn rotate_state(&self, _: &mut State, _: bool) { panic!("{} has no custom state", type_name::<Self>()); } - fn serialize_state(&self, _: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, _: &State) -> Result<DynData, SerializeError> { Ok(DynData::Empty) } - fn draw(&self, category: &str, name: &str, _: Option<&dyn Any>) -> Option<RgbaImage> { + fn draw(&self, category: &str, name: &str, _: Option<&State>) -> Option<RgbaImage> { if category != "turrets" { return None; } diff --git a/src/block/walls.rs b/src/block/walls.rs index 2cf3bbc..25dc4f2 100644 --- a/src/block/walls.rs +++ b/src/block/walls.rs @@ -1,6 +1,5 @@ //! walls -use std::any::Any; - +use super::State; use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock}; use crate::block::{ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError, @@ -67,7 +66,7 @@ impl BlockLogic for DoorBlock { Ok(DynData::Boolean(false)) } - fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> { + fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> { match data { DynData::Boolean(opened) => Ok(Some(Self::create_state(opened))), _ => Err(DeserializeError::InvalidType { @@ -77,16 +76,16 @@ impl BlockLogic for DoorBlock { } } - fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> { + fn clone_state(&self, state: &State) -> State { let state = Self::get_state(state); Box::new(Self::create_state(*state)) } - fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {} + fn mirror_state(&self, _: &mut State, _: bool, _: bool) {} - fn rotate_state(&self, _: &mut dyn Any, _: bool) {} + fn rotate_state(&self, _: &mut State, _: bool) {} - fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> { + fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> { let state = Self::get_state(state); Ok(DynData::Boolean(*state)) } diff --git a/src/data/schematic.rs b/src/data/schematic.rs index 8c8f710..d2b8aec 100644 --- a/src/data/schematic.rs +++ b/src/data/schematic.rs @@ -1,5 +1,4 @@ //! schematic parsing -use std::any::Any; use std::collections::hash_map::Entry; use std::collections::HashMap; use std::error::Error; @@ -13,7 +12,7 @@ use flate2::{ }; use image::RgbaImage; -use crate::block::{self, Block, BlockRegistry, Rotation}; +use crate::block::{self, Block, BlockRegistry, Rotation, State}; use crate::data::base64; use crate::data::dynamic::{self, DynData, DynSerializer}; use crate::data::{self, DataRead, DataWrite, GridPos, Serializer}; @@ -30,7 +29,7 @@ pub struct Placement<'l> { pub pos: GridPos, pub block: &'l Block, pub rot: Rotation, - state: Option<Box<dyn Any>>, + state: Option<State>, } impl PartialEq for Placement<'_> { @@ -42,18 +41,18 @@ impl PartialEq for Placement<'_> { impl<'l> Placement<'l> { /// gets the current state of this placement. you can cast it with `placement.block::get_state(placement.get_state()?)?` #[must_use] - pub fn get_state(&self) -> Option<&dyn Any> { + pub fn get_state(&self) -> Option<&State> { match self.state { None => None, - Some(ref b) => Some(b.as_ref()), + Some(ref b) => Some(b), } } /// get mutable state. - pub fn get_state_mut(&mut self) -> Option<&mut dyn Any> { + pub fn get_state_mut(&mut self) -> Option<&mut State> { match self.state { None => None, - Some(ref mut b) => Some(b.as_mut()), + Some(ref mut b) => Some(b), } } @@ -63,10 +62,7 @@ impl<'l> Placement<'l> { } /// set the state - pub fn set_state( - &mut self, - data: DynData, - ) -> Result<Option<Box<dyn Any>>, block::DeserializeError> { + pub fn set_state(&mut self, data: DynData) -> Result<Option<State>, block::DeserializeError> { let state = self.block.deserialize_state(data)?; Ok(std::mem::replace(&mut self.state, state)) } @@ -515,8 +511,7 @@ impl<'l> Schematic<'l> { curr.rot.mirror(horizontally, vertically); } if let Some(ref mut state) = curr.state { - curr.block - .mirror_state(state.as_mut(), horizontally, vertically); + curr.block.mirror_state(state, horizontally, vertically); } } self.rebuild_lookup(); @@ -557,7 +552,7 @@ impl<'l> Schematic<'l> { curr.rot.rotate(clockwise); } if let Some(ref mut state) = curr.state { - curr.block.rotate_state(state.as_mut(), clockwise); + curr.block.rotate_state(state, clockwise); } } self.rebuild_lookup(); @@ -1143,7 +1138,7 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> { rbuff.write_u32(u32::from(curr.pos))?; let data = match curr.state { None => DynData::Empty, - Some(ref s) => curr.block.serialize_state(s.as_ref())?, + Some(ref s) => curr.block.serialize_state(s)?, }; DynSerializer.serialize(&mut rbuff, &data)?; rbuff.write_u8(curr.rot.into())?; |