mindustry logic execution, map- and schematic- parsing and rendering
-rw-r--r--src/block/logic.rs14
-rw-r--r--src/block/mod.rs35
-rw-r--r--src/block/power.rs6
-rw-r--r--src/block/simple.rs6
-rw-r--r--src/data/schematic.rs15
5 files changed, 59 insertions, 17 deletions
diff --git a/src/block/logic.rs b/src/block/logic.rs
index 84c97b6..fa77f7d 100644
--- a/src/block/logic.rs
+++ b/src/block/logic.rs
@@ -6,7 +6,7 @@ use std::string::FromUtf8Error;
use flate2::{Compress, CompressError, Compression, Decompress, DecompressError, FlushCompress, FlushDecompress, Status};
-use crate::block::{BlockLogic, DeserializeError, make_register, SerializeError};
+use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError};
use crate::block::simple::{SimpleBlock, state_impl};
use crate::data::{self, DataRead, DataWrite, GridPos};
use crate::data::dynamic::{DynData, DynType};
@@ -43,9 +43,9 @@ impl BlockLogic for MessageLogic
true
}
- fn data_from_i32(&self, _: i32, _: GridPos) -> DynData
+ fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError>
{
- DynData::Empty
+ Ok(DynData::Empty)
}
fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError>
@@ -88,9 +88,9 @@ impl BlockLogic for SwitchLogic
true
}
- fn data_from_i32(&self, _: i32, _: GridPos) -> DynData
+ fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError>
{
- DynData::Empty
+ Ok(DynData::Empty)
}
fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError>
@@ -136,9 +136,9 @@ impl BlockLogic for ProcessorLogic
true
}
- fn data_from_i32(&self, _: i32, _: GridPos) -> DynData
+ fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError>
{
- DynData::Empty
+ Ok(DynData::Empty)
}
fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError>
diff --git a/src/block/mod.rs b/src/block/mod.rs
index df37940..449c834 100644
--- a/src/block/mod.rs
+++ b/src/block/mod.rs
@@ -28,7 +28,7 @@ pub trait BlockLogic
fn is_symmetric(&self) -> bool;
- fn data_from_i32(&self, config: i32, pos: GridPos) -> DynData;
+ fn data_from_i32(&self, config: i32, pos: GridPos) -> Result<DynData, DataConvertError>;
fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError>;
@@ -38,6 +38,37 @@ pub trait BlockLogic
}
#[derive(Debug)]
+pub struct DataConvertError(pub Box<dyn Error>);
+
+impl DataConvertError
+{
+ pub fn forward<T, E: Error + 'static>(result: Result<T, E>) -> Result<T, Self>
+ {
+ match result
+ {
+ Ok(v) => Ok(v),
+ Err(e) => Err(Self(Box::new(e))),
+ }
+ }
+}
+
+impl fmt::Display for DataConvertError
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
+ {
+ self.0.fmt(f)
+ }
+}
+
+impl Error for DataConvertError
+{
+ fn source(&self) -> Option<&(dyn Error + 'static)>
+ {
+ Some(self.0.as_ref())
+ }
+}
+
+#[derive(Debug)]
pub enum DeserializeError
{
InvalidType{have: DynType, expect: DynType},
@@ -148,7 +179,7 @@ impl Block
self.logic.is_symmetric()
}
- pub fn data_from_i32(&self, config: i32, pos: GridPos) -> DynData
+ pub fn data_from_i32(&self, config: i32, pos: GridPos) -> Result<DynData, DataConvertError>
{
self.logic.data_from_i32(config, pos)
}
diff --git a/src/block/power.rs b/src/block/power.rs
index 04c9607..5996d87 100644
--- a/src/block/power.rs
+++ b/src/block/power.rs
@@ -2,7 +2,7 @@ use std::any::Any;
use std::error::Error;
use std::fmt;
-use crate::block::{BlockLogic, DeserializeError, make_register, SerializeError};
+use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError};
use crate::block::simple::{SimpleBlock, state_impl};
use crate::data::GridPos;
use crate::data::dynamic::{DynData, DynType};
@@ -69,9 +69,9 @@ impl BlockLogic for ConnectorBlock
true
}
- fn data_from_i32(&self, _: i32, _: GridPos) -> DynData
+ fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError>
{
- DynData::Empty
+ Ok(DynData::Empty)
}
fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError>
diff --git a/src/block/simple.rs b/src/block/simple.rs
index 46b0b23..49f7151 100644
--- a/src/block/simple.rs
+++ b/src/block/simple.rs
@@ -1,6 +1,6 @@
use std::any::{Any, type_name};
-use crate::block::{BlockLogic, DeserializeError, SerializeError};
+use crate::block::{BlockLogic, DataConvertError, DeserializeError, SerializeError};
use crate::data::GridPos;
use crate::data::dynamic::DynData;
@@ -59,9 +59,9 @@ impl BlockLogic for SimpleBlock
self.symmetric
}
- fn data_from_i32(&self, _: i32, _: GridPos) -> DynData
+ fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError>
{
- DynData::Empty
+ Ok(DynData::Empty)
}
fn deserialize_state(&self, _: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError>
diff --git a/src/data/schematic.rs b/src/data/schematic.rs
index 53c73fd..7c43ad2 100644
--- a/src/data/schematic.rs
+++ b/src/data/schematic.rs
@@ -11,7 +11,7 @@ use flate2::{Compress, CompressError, Compression, Decompress, DecompressError,
use crate::block::{self, Block, BlockRegistry, Rotation};
use crate::data::{self, DataRead, DataWrite, GridPos, Serializer};
use crate::data::base64;
-use crate::data::dynamic::{self, DynSerializer, DynData};
+use crate::data::dynamic::{self, DynData, DynSerializer};
pub const MAX_DIMENSION: u16 = 128;
pub const MAX_BLOCKS: u32 = 128 * 128;
@@ -798,7 +798,7 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l>
let block = block_table[idx as usize];
let config = if version < 1
{
- block.data_from_i32(rbuff.read_i32()?, pos)
+ block.data_from_i32(rbuff.read_i32()?, pos)?
}
else {DynSerializer.deserialize(&mut rbuff)?};
let rot = Rotation::from(rbuff.read_u8()?);
@@ -937,6 +937,7 @@ pub enum ReadError
NoSuchBlock(String),
BlockCount(i32),
BlockIndex(i8, usize),
+ BlockConfig(block::DataConvertError),
BlockState(dynamic::ReadError),
Placement(PlaceError),
}
@@ -965,6 +966,14 @@ impl From<dynamic::ReadError> for ReadError
}
}
+impl From<block::DataConvertError> for ReadError
+{
+ fn from(value: block::DataConvertError) -> Self
+ {
+ Self::BlockConfig(value)
+ }
+}
+
impl From<PlaceError> for ReadError
{
fn from(value: PlaceError) -> Self
@@ -989,6 +998,7 @@ impl fmt::Display for ReadError
ReadError::NoSuchBlock(name) => write!(f, "unknown block {name:?}"),
ReadError::BlockCount(cnt) => write!(f, "invalid total block count ({cnt})"),
ReadError::BlockIndex(idx, cnt) => write!(f, "invalid block index ({idx} / {cnt})"),
+ ReadError::BlockConfig(e) => e.fmt(f),
ReadError::BlockState(e) => e.fmt(f),
ReadError::Placement(e) => e.fmt(f),
}
@@ -1003,6 +1013,7 @@ impl Error for ReadError
{
ReadError::Read(e) => Some(e),
ReadError::Decompress(e) => Some(e),
+ ReadError::BlockConfig(e) => Some(e),
ReadError::BlockState(e) => Some(e),
ReadError::Placement(e) => Some(e),
_ => None,