mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/block/mod.rs')
| -rw-r--r-- | src/block/mod.rs | 73 |
1 files changed, 65 insertions, 8 deletions
diff --git a/src/block/mod.rs b/src/block/mod.rs index 822de05..5e3bd50 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -4,7 +4,6 @@ //! //! with the exception of sandbox, that is. use bobbin_bits::U4::{self, B0000, B0001, B0010, B0100, B1000}; -use std::any::Any; use std::error::Error; use std::fmt; @@ -112,7 +111,71 @@ disp! { DoorBlock, } -pub type State = Box<dyn Any + Sync + Send>; +pub trait Cast { + fn downcast_ref(state: &State) -> Option<&Self>; + fn downcast_mut(state: &mut State) -> Option<&mut Self>; +} + +macro_rules! stater { + ($($k: ident($v: ty),)+) => { + #[derive(Debug, Clone)] + pub enum State { + $($k($v),)+ + } + + $( + impl From<$v> for State { + fn from(v: $v) -> State { State::$k(v) } + } + + impl Cast for $v { + fn downcast_ref(state: &State) -> Option<&Self> { + match state { + State::$k(v) => Some(v), + _ => None, + } + } + fn downcast_mut(state: &mut State) -> Option<&mut Self> { + match state { + State::$k(v) => Some(v), + _ => None, + } + } + } + )+ + } +} + +stater! { + // TODO deoptionize + String(String), + Item(Option<crate::item::Type>), + Fluid(Option<crate::fluid::Type>), + Image(image::RgbImage), + Point(Option<(i32, i32)>), + Bool(bool), + Processor(logic::ProcessorState), + Payload(payload::Payload), + Power(Vec<(i16, i16)>), + Color(power::Rgba), + Command(Option<crate::data::command::UnitCommand>), + Unit(Option<crate::unit::Type>), +} + +impl State { + pub fn downcast_ref<T: Cast>(&self) -> Option<&T> { + T::downcast_ref(self) + } + + pub fn downcast_mut<T: Cast>(&mut self) -> Option<&mut T> { + T::downcast_mut(self) + } + + pub fn new<T: Into<Self>>(from: T) -> Self { + from.into() + } +} + #[enum_dispatch::enum_dispatch(BlockLogicEnum)] pub trait BlockLogic { /// mindustry blocks are the same width and height @@ -126,8 +189,6 @@ pub trait BlockLogic { fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError>; - fn clone_state(&self, state: &State) -> State; - #[allow(unused_variables)] fn mirror_state(&self, state: &mut State, horizontally: bool, vertically: bool) {} @@ -331,10 +392,6 @@ impl Block { self.logic.deserialize_state(data) } - pub(crate) fn clone_state(&self, state: &State) -> State { - self.logic.clone_state(state) - } - pub(crate) fn mirror_state(&self, state: &mut State, horizontally: bool, vertically: bool) { self.logic.mirror_state(state, horizontally, vertically); } |