mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/block/logic.rs')
-rw-r--r--src/block/logic.rs121
1 files changed, 33 insertions, 88 deletions
diff --git a/src/block/logic.rs b/src/block/logic.rs
index ccfd8a0..43cf83b 100644
--- a/src/block/logic.rs
+++ b/src/block/logic.rs
@@ -10,7 +10,9 @@ use flate2::{
};
use crate::block::simple::{cost, state_impl, BuildCost, SimpleBlock};
-use crate::block::{make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError};
+use crate::block::{
+ impl_block, make_register, BlockLogic, DataConvertError, DeserializeError, SerializeError,
+};
use crate::data::dynamic::{DynData, DynType};
use crate::data::{self, DataRead, DataWrite, GridPos};
use crate::item::storage::Storage;
@@ -35,10 +37,9 @@ pub struct MessageLogic {
}
impl MessageLogic {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -50,25 +51,7 @@ impl MessageLogic {
}
impl BlockLogic for MessageLogic {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
@@ -105,10 +88,9 @@ pub struct SwitchLogic {
}
impl SwitchLogic {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -120,25 +102,7 @@ impl SwitchLogic {
}
impl BlockLogic for SwitchLogic {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
@@ -156,7 +120,7 @@ impl BlockLogic for SwitchLogic {
}
fn clone_state(&self, state: &dyn Any) -> Box<dyn Any> {
- Box::new(Self::get_state(state).clone())
+ Box::new(*Self::get_state(state))
}
fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool) {}
@@ -175,10 +139,9 @@ pub struct ProcessorLogic {
}
impl ProcessorLogic {
+ #[must_use]
pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self {
- if size == 0 {
- panic!("invalid size");
- }
+ assert!(size != 0, "invalid size");
Self {
size,
symmetric,
@@ -190,25 +153,7 @@ impl ProcessorLogic {
}
impl BlockLogic for ProcessorLogic {
- fn get_size(&self) -> u8 {
- self.size
- }
-
- fn is_symmetric(&self) -> bool {
- self.symmetric
- }
-
- fn create_build_cost(&self) -> Option<Storage> {
- if !self.build_cost.is_empty() {
- let mut storage = Storage::new();
- for (ty, cnt) in self.build_cost {
- storage.add(*ty, *cnt, u32::MAX);
- }
- Some(storage)
- } else {
- None
- }
- }
+ impl_block!();
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
@@ -216,7 +161,7 @@ impl BlockLogic for ProcessorLogic {
fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError> {
match data {
- DynData::Empty => Ok(Some(Self::create_state(ProcessorState::new()))),
+ DynData::Empty => Ok(Some(Self::create_state(ProcessorState::default()))),
DynData::ByteArray(arr) => {
let mut input = arr.as_ref();
let mut dec = Decompress::new(true);
@@ -257,7 +202,7 @@ impl BlockLogic for ProcessorLogic {
}
let code_len = ProcessorDeserializeError::forward(buff.read_i32())?;
- if code_len < 0 || code_len > 500 * 1024 {
+ if !(0..=500 * 1024).contains(&code_len) {
return Err(DeserializeError::Custom(Box::new(
ProcessorDeserializeError::CodeLength(code_len),
)));
@@ -298,7 +243,7 @@ impl BlockLogic for ProcessorLogic {
}
fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool) {
- for link in Self::get_state_mut(state).links.iter_mut() {
+ for link in &mut Self::get_state_mut(state).links {
if horizontally {
link.x = -link.x;
}
@@ -309,7 +254,7 @@ impl BlockLogic for ProcessorLogic {
}
fn rotate_state(&self, state: &mut dyn Any, clockwise: bool) {
- for link in Self::get_state_mut(state).links.iter_mut() {
+ for link in &mut Self::get_state_mut(state).links {
let (cdx, cdy) = link.get_pos();
link.x = if clockwise { cdy } else { -cdy };
link.y = if clockwise { -cdx } else { cdx };
@@ -318,14 +263,14 @@ impl BlockLogic for ProcessorLogic {
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError> {
let state = Self::get_state(state);
- let mut rbuff = DataWrite::new();
+ let mut rbuff = DataWrite::default();
ProcessorSerializeError::forward(rbuff.write_u8(1))?;
assert!(state.code.len() < 500 * 1024);
ProcessorSerializeError::forward(rbuff.write_i32(state.code.len() as i32))?;
ProcessorSerializeError::forward(rbuff.write_bytes(state.code.as_bytes()))?;
assert!(state.links.len() < i32::MAX as usize);
ProcessorSerializeError::forward(rbuff.write_i32(state.links.len() as i32))?;
- for link in state.links.iter() {
+ for link in &state.links {
ProcessorSerializeError::forward(rbuff.write_utf(&link.name))?;
ProcessorSerializeError::forward(rbuff.write_i16(link.x))?;
ProcessorSerializeError::forward(rbuff.write_i16(link.y))?;
@@ -478,7 +423,7 @@ impl Error for ProcessorSerializeError {
}
}
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, PartialEq, Default)]
pub struct ProcessorLink {
name: String,
x: i16,
@@ -486,10 +431,13 @@ pub struct ProcessorLink {
}
impl ProcessorLink {
+ #[must_use]
pub fn new(name: Cow<'_, str>, x: i16, y: i16) -> Self {
- if name.len() > u16::MAX as usize {
- panic!("name too long ({})", name.len());
- }
+ assert!(
+ u16::try_from(name.len()).is_ok(),
+ "name too long ({})",
+ name.len()
+ );
Self {
name: name.into_owned(),
x,
@@ -497,29 +445,25 @@ impl ProcessorLink {
}
}
+ #[must_use]
pub fn get_name(&self) -> &str {
&self.name
}
+ #[must_use]
pub fn get_pos(&self) -> (i16, i16) {
(self.x, self.y)
}
}
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, PartialEq, Default)]
pub struct ProcessorState {
code: String,
links: Vec<ProcessorLink>,
}
impl ProcessorState {
- pub fn new() -> Self {
- Self {
- code: String::new(),
- links: Vec::new(),
- }
- }
-
+ #[must_use]
pub fn get_code(&self) -> &str {
&self.code
}
@@ -539,6 +483,7 @@ impl ProcessorState {
Ok(())
}
+ #[must_use]
pub fn get_links(&self) -> &[ProcessorLink] {
&self.links
}
@@ -552,8 +497,8 @@ impl ProcessorState {
if name.len() > u16::MAX as usize {
return Err(CreateError::NameLength(name.len()));
}
- for curr in self.links.iter() {
- if &name == &curr.name {
+ for curr in &self.links {
+ if name == curr.name {
return Err(CreateError::DuplicateName(name));
}
if x == curr.x && y == curr.y {