mindustry logic execution, map- and schematic- parsing and rendering
| -rw-r--r-- | src/block/logic.rs | 101 | ||||
| -rw-r--r-- | src/block/simple.rs | 25 | ||||
| -rw-r--r-- | src/data/dynamic.rs | 38 |
3 files changed, 160 insertions, 4 deletions
diff --git a/src/block/logic.rs b/src/block/logic.rs index f9c6094..bc35a60 100644 --- a/src/block/logic.rs +++ b/src/block/logic.rs @@ -1,10 +1,13 @@ -use crate::block::make_register; -use crate::block::simple::SimpleBlock; +use std::any::{Any, type_name}; + +use crate::block::{BlockLogic, make_register}; +use crate::block::simple::{SimpleBlock, state_impl}; +use crate::data::dynamic::DynData; make_register! ( - MESSAGE: "message" => SimpleBlock::new(1, true); // TODO config: message - SWITCH: "switch" => SimpleBlock::new(1, true); // TODO config: enabled + MESSAGE: "message" => MessageLogic; + SWITCH: "switch" => SwitchLogic; MICRO_PROCESSOR: "micro-processor" => SimpleBlock::new(1, true); // TODO config: code & links LOGIC_PROCESSOR: "logic-processor" => SimpleBlock::new(2, true); // TODO config: code & links HYPER_PROCESSOR: "hyper-processor" => SimpleBlock::new(3, true); // TODO config: code & links @@ -13,3 +16,93 @@ make_register! LOGIC_DISPLAY: "logic-display" => SimpleBlock::new(3, true); LARGE_LOGIC_DISPLAY: "large-logic-display" => SimpleBlock::new(6, true); ); + +pub struct MessageLogic; + +impl MessageLogic +{ + state_impl!(pub String); +} + +impl BlockLogic for MessageLogic +{ + fn get_size(&self) -> u8 + { + 1 + } + + fn is_symmetric(&self) -> bool + { + true + } + + fn data_from_i32(&self, _: i32) -> DynData + { + DynData::Empty + } + + fn deserialize_state(&self, data: DynData) -> Option<Box<dyn Any>> + { + match data + { + DynData::Empty | DynData::String(None) => Some(Self::create_state(String::new())), + DynData::String(Some(s)) => Some(Self::create_state(s)), + _ => panic!("{} cannot use data of {:?}", type_name::<Self>(), data.get_type()), + } + } + + fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> + { + Box::new(Self::get_state(state).clone()) + } + + fn serialize_state(&self, state: &dyn Any) -> DynData + { + DynData::String(Some(Self::get_state(state).clone())) + } +} + +pub struct SwitchLogic; + +impl SwitchLogic +{ + state_impl!(pub bool); +} + +impl BlockLogic for SwitchLogic +{ + fn get_size(&self) -> u8 + { + 1 + } + + fn is_symmetric(&self) -> bool + { + true + } + + fn data_from_i32(&self, _: i32) -> DynData + { + DynData::Empty + } + + fn deserialize_state(&self, data: DynData) -> Option<Box<dyn Any>> + { + match data + { + DynData::Empty => Some(Self::create_state(true)), + DynData::Boolean(enabled) => Some(Self::create_state(enabled)), + _ => panic!("{} cannot use data of {:?}", type_name::<Self>(), data.get_type()), + } + } + + fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> + { + Box::new(Self::get_state(state).clone()) + } + + fn serialize_state(&self, state: &dyn Any) -> DynData + { + DynData::Boolean(*Self::get_state(state)) + } +} diff --git a/src/block/simple.rs b/src/block/simple.rs index 330ee7f..c363064 100644 --- a/src/block/simple.rs +++ b/src/block/simple.rs @@ -29,6 +29,31 @@ macro_rules!gen_state_empty }; } +macro_rules!state_impl +{ + ($vis:vis $type:ty) => + { + $vis fn get_state<'l>(state: &'l dyn Any) -> &'l $type + where Self: Sized + { + state.downcast_ref::<$type>().unwrap() + } + + $vis fn get_state_mut<'l>(state: &'l mut dyn Any) -> &'l mut $type + where Self: Sized + { + state.downcast_mut::<$type>().unwrap() + } + + fn create_state(val: $type) -> Box<dyn Any> + where Self: Sized + { + Box::new(val) + } + }; +} +pub(crate) use state_impl; + pub struct SimpleBlock { size: u8, diff --git a/src/data/dynamic.rs b/src/data/dynamic.rs index 4ccafcb..0b4e3fb 100644 --- a/src/data/dynamic.rs +++ b/src/data/dynamic.rs @@ -69,6 +69,44 @@ pub enum DynData Team(Team), } +impl DynData +{ + pub fn get_type(&self) -> DynType + { + match self + { + DynData::Empty => DynType::Empty, + DynData::Int(..) => DynType::Int, + DynData::Long(..) => DynType::Long, + DynData::Float(..) => DynType::Float, + DynData::String(..) => DynType::String, + DynData::Content(..) => DynType::Content, + DynData::IntArray(..) => DynType::IntArray, + DynData::Point2(..) => DynType::Point2, + DynData::Point2Array(..) => DynType::Point2Array, + DynData::TechNode(..) => DynType::TechNode, + DynData::Boolean(..) => DynType::Boolean, + DynData::Double(..) => DynType::Double, + DynData::Building(..) => DynType::Building, + DynData::LogicField(..) => DynType::LogicField, + DynData::ByteArray(..) => DynType::ByteArray, + DynData::UnitCommand(..) => DynType::UnitCommand, + DynData::BoolArray(..) => DynType::BoolArray, + DynData::Unit(..) => DynType::Unit, + DynData::Vec2Array(..) => DynType::Vec2Array, + DynData::Vec2(..) => DynType::Vec2, + DynData::Team(..) => DynType::Team, + } + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum DynType +{ + Empty, Int, Long, Float, String, Content, IntArray, Point2, Point2Array, TechNode, Boolean, Double, Building, + LogicField, ByteArray, UnitCommand, BoolArray, Unit, Vec2Array, Vec2, Team, +} + pub struct DynSerializer; impl Serializer<DynData> for DynSerializer |