mindustry logic execution, map- and schematic- parsing and rendering
make state Send + Sync
bendn 2023-06-29
parent 08e123a · commit 37fdf10
-rw-r--r--Cargo.toml2
-rw-r--r--src/block/distribution.rs25
-rw-r--r--src/block/liquid.rs19
-rw-r--r--src/block/logic.rs32
-rw-r--r--src/block/mod.rs25
-rw-r--r--src/block/payload.rs22
-rw-r--r--src/block/power.rs22
-rw-r--r--src/block/simple.rs21
-rw-r--r--src/block/walls.rs13
-rw-r--r--src/data/schematic.rs25
10 files changed, 99 insertions, 107 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 0116b57..df50d07 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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())?;