mindustry logic execution, map- and schematic- parsing and rendering
-rw-r--r--src/access.rs128
-rw-r--r--src/block/mod.rs12
-rw-r--r--src/main.rs1
3 files changed, 133 insertions, 8 deletions
diff --git a/src/access.rs b/src/access.rs
new file mode 100644
index 0000000..9b8cc58
--- /dev/null
+++ b/src/access.rs
@@ -0,0 +1,128 @@
+use std::borrow::Borrow;
+use std::cmp::Ordering;
+use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::ops::Deref;
+
+pub type BoxAccess<'a, D> = Access<'a, Box<D>, D>;
+
+// Similar to Cow but doesn't require ToOwned
+#[derive(Clone, Debug)]
+pub enum Access<'a, T: AsRef<B>, B: ?Sized>
+{
+ Borrowed(&'a B),
+ Owned(T),
+}
+
+impl<'a, T: AsRef<B>, B> Access<'a, T, B>
+{
+ pub const fn is_borrowed(&self) -> bool
+ {
+ match self
+ {
+ Access::Borrowed(..) => true,
+ _ => false,
+ }
+ }
+
+ pub const fn is_owned(&self) -> bool
+ {
+ match self
+ {
+ Access::Owned(..) => true,
+ _ => false,
+ }
+ }
+}
+
+impl<'a, T: AsRef<B>, B: ?Sized> From<T> for Access<'a, T, B>
+{
+ fn from(value: T) -> Self
+ {
+ Self::Owned(value)
+ }
+}
+
+impl<'a, T: AsRef<B>, B: ?Sized> AsRef<B> for Access<'a, T, B>
+{
+ fn as_ref(&self) -> &B
+ {
+ self
+ }
+}
+
+impl<'a, T: AsRef<B>, B: ?Sized> Borrow<B> for Access<'a, T, B>
+{
+ fn borrow(&self) -> &B
+ {
+ match self
+ {
+ Access::Borrowed(r) => *r,
+ Access::Owned(v) => v.as_ref(),
+ }
+ }
+}
+
+impl<'a, T: AsRef<B> + Default, B: ?Sized> Default for Access<'a, T, B>
+{
+ fn default() -> Self
+ {
+ Self::Owned(T::default())
+ }
+}
+
+impl<'a, T: AsRef<B>, B: ?Sized> Deref for Access<'a, T, B>
+{
+ type Target = B;
+
+ fn deref(&self) -> &Self::Target
+ {
+ match self
+ {
+ Access::Borrowed(r) => *r,
+ Access::Owned(v) => v.as_ref(),
+ }
+ }
+}
+
+impl<'a, T: AsRef<B>, B: ?Sized + fmt::Display> fmt::Display for Access<'a, T, B>
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
+ {
+ B::fmt(self, f)
+ }
+}
+
+impl<'a, T: AsRef<B>, B: ?Sized + Eq> Eq for Access<'a, T, B> {}
+
+impl<'a, T: AsRef<B>, B: ?Sized + Hash> Hash for Access<'a, T, B>
+{
+ fn hash<H: Hasher>(&self, state: &mut H)
+ {
+ B::hash(self, state)
+ }
+}
+
+impl<'a, T: AsRef<B>, B: ?Sized + Ord> Ord for Access<'a, T, B>
+{
+ fn cmp(&self, other: &Self) -> Ordering
+ {
+ B::cmp(self, other)
+ }
+}
+
+impl<'a, 'b, T: AsRef<B>, B: ?Sized + PartialEq<C>, U: AsRef<C>, C: ?Sized> PartialEq<Access<'b, U, C>> for Access<'a, T, B>
+{
+ fn eq(&self, other: &Access<'b, U, C>) -> bool
+ {
+ B::eq(self, other)
+ }
+}
+
+impl<'a, 'b, T: AsRef<B>, B: ?Sized + PartialOrd<C>, U: AsRef<C>, C: ?Sized> PartialOrd<Access<'b, U, C>> for Access<'a, T, B>
+{
+ fn partial_cmp(&self, other: &Access<'b, U, C>) -> Option<Ordering>
+ {
+ B::partial_cmp(self, other)
+ }
+}
diff --git a/src/block/mod.rs b/src/block/mod.rs
index 074e431..1a32b6b 100644
--- a/src/block/mod.rs
+++ b/src/block/mod.rs
@@ -2,6 +2,7 @@ use std::borrow::Cow;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
+use crate::access::BoxAccess;
use crate::data::dynamic::DynData;
pub trait BlockLogic
@@ -22,12 +23,12 @@ pub trait BlockLogic
pub struct Block
{
name: Cow<'static, str>,
- logic: Box<dyn BlockLogic>,
+ logic: BoxAccess<'static, dyn BlockLogic + Sync>,
}
impl Block
{
- pub fn new(name: Cow<'static, str>, logic: Box<dyn BlockLogic>) -> Self
+ pub const fn new(name: Cow<'static, str>, logic: BoxAccess<'static, dyn BlockLogic + Sync>) -> Self
{
Self{name, logic}
}
@@ -152,12 +153,7 @@ impl<'l> BlockRegistry<'l>
pub fn register(&mut self, block: &'l Block) -> Result<&'l Block, &'l Block>
{
- let key = match block.name
- {
- Cow::Borrowed(r) => r,
- Cow::Owned(ref s) => s,
- };
- match self.blocks.entry(key)
+ match self.blocks.entry(&block.name)
{
Entry::Occupied(e) => Err(e.get()),
Entry::Vacant(e) => Ok(*e.insert(block)),
diff --git a/src/main.rs b/src/main.rs
index b11c58e..90d8d48 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,4 @@
+pub mod access;
pub mod args;
pub mod block;
pub mod data;