diff --git a/stackline/Cargo.toml b/stackline/Cargo.toml index 69c685a..c4c0d8a 100755 --- a/stackline/Cargo.toml +++ b/stackline/Cargo.toml @@ -6,13 +6,13 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -# dyn-clone = "1.0" palette = "0.6" enum_dispatch = "0.3" contracts = { version = "0.6.3", features = ["override_debug"] } -veccell = "0.3.0" +veccell = { version = "0.4.0", features = ["serde"] } pathfinding = "3.0" colored = "2.0" +serde = { version = "1", features = ["derive"] } [dev-dependencies] criterion = { version = "0.3.5", features = ["html_reports"] } diff --git a/stackline/build.rs b/stackline/build.rs index 0e0861b..8bfeed9 100644 --- a/stackline/build.rs +++ b/stackline/build.rs @@ -87,7 +87,7 @@ fn main() { } res += &fs::read_to_string("src/tile/anytile.doc.rs").expect("Couldn't read src/tile/anytile.doc.rs"); - res += "#[derive(Clone, Debug)]\n"; + res += "#[derive(Clone, Debug, Serialize, Deserialize)]\n"; res += "#[enum_dispatch]\n"; res += "pub enum AnyTile {\n"; diff --git a/stackline/src/context.rs b/stackline/src/context.rs index 1e79b55..8c23346 100644 --- a/stackline/src/context.rs +++ b/stackline/src/context.rs @@ -26,9 +26,8 @@ use veccell::{VecRef, VecRefMut}; Here is how you would implement a simple "counter" tile: ``` - # use stackline::{*, tile::*, context::*}; - # - #[derive(Clone, Debug)] + # use stackline::tile::prelude::*; + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CounterTile(usize); impl CounterTile { @@ -113,8 +112,8 @@ impl<'a> UpdateContext<'a> { /// # Example /// /// ``` - /// # use stackline::prelude::*; - /// # #[derive(Clone, Debug)] + /// # use stackline::tile::prelude::*; + /// # #[derive(Clone, Debug, Serialize, Deserialize)] /// # pub struct MyTile; /// # impl Tile for MyTile { /// fn update<'b>(&'b mut self, mut ctx: UpdateContext<'b>) { @@ -166,8 +165,8 @@ impl<'a> UpdateContext<'a> { /// # Example /// /// ``` - /// # use stackline::prelude::*; - /// #[derive(Clone, Debug)] + /// # use stackline::tile::prelude::*; + /// #[derive(Clone, Debug, Serialize, Deserialize)] /// pub struct PrintTile; /// /// impl Tile for PrintTile { @@ -278,8 +277,8 @@ impl<'a> UpdateContext<'a> { /// # Example /// /// ``` - /// # use stackline::prelude::*; - /// # #[derive(Clone, Debug)] + /// # use stackline::tile::prelude::*; + /// # #[derive(Clone, Debug, Serialize, Deserialize)] /// # pub struct MyTile; /// # impl Tile for MyTile { /// fn update<'b>(&'b mut self, mut ctx: UpdateContext<'b>) { @@ -382,8 +381,8 @@ impl<'a> UpdateContext<'a> { /// # Example /// /// ``` - /// # use stackline::prelude::*; - /// #[derive(Clone, Debug)] + /// # use stackline::tile::prelude::*; + /// #[derive(Clone, Debug, Serialize, Deserialize)] /// pub struct StorageTile {}; /// /// impl Tile for StorageTile { diff --git a/stackline/src/pane.rs b/stackline/src/pane.rs index 1e720cc..9ac72be 100644 --- a/stackline/src/pane.rs +++ b/stackline/src/pane.rs @@ -1,7 +1,8 @@ use super::*; use veccell::{VecCell, VecRef, VecRefMut}; +use serde::{Serialize, Deserialize}; -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub struct Pane { tiles: VecCell, width: NonZeroUsize, diff --git a/stackline/src/signal.rs b/stackline/src/signal.rs index 68f10f7..1f7cb2e 100644 --- a/stackline/src/signal.rs +++ b/stackline/src/signal.rs @@ -1,6 +1,7 @@ use super::*; +use serde::{Serialize, Deserialize}; -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum Value { Number(f64), String(String), @@ -55,7 +56,7 @@ impl<'a> From<&'a str> for Value { /// - By cloning it, through [`clone_move`](Signal::clone_move) (recommended) or [`clone`](Signal::clone) /// - By creating an empty signal, with [`empty`](Signal::empty) /// - Through the [`stackline::signal!`](crate::signal!) macro -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Signal { direction: Direction, position: (usize, usize), @@ -88,8 +89,8 @@ impl Signal { /// ## Example /// /// ``` - /// # use stackline::prelude::*; - /// # #[derive(Clone, Debug)] + /// # use stackline::tile::prelude::*; + /// # #[derive(Clone, Debug, Serialize, Deserialize)] /// # struct MyTile; /// # impl Tile for MyTile { /// fn update<'b>(&'b mut self, mut ctx: UpdateContext<'b>) { diff --git a/stackline/src/tile/full.rs b/stackline/src/tile/full.rs index 0308898..f52dfc2 100644 --- a/stackline/src/tile/full.rs +++ b/stackline/src/tile/full.rs @@ -1,4 +1,5 @@ use super::*; +use serde::{Serialize, Deserialize}; /** Represents a tile that may be empty and may have a signal. The tile may only have a signal if it isn't empty. Cloning a `FullTile` results in a `FullTile` that does not have any signal. @@ -9,7 +10,7 @@ Cloning a `FullTile` results in a `FullTile` that does not have any signal. - `self.accepts_signal() -> self.cell.is_some()` **/ -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct FullTile { cell: Option, signal: Option, diff --git a/stackline/src/tile/mod.rs b/stackline/src/tile/mod.rs index 5cf3635..dd4b50e 100644 --- a/stackline/src/tile/mod.rs +++ b/stackline/src/tile/mod.rs @@ -5,6 +5,7 @@ * See [its documentation](AnyTile) for more information on the discovery process. */ use super::*; +use serde::{Serialize, Deserialize}; mod full; pub use full::*; @@ -50,8 +51,8 @@ include!(concat!(env!("OUT_DIR"), "/anytile.rs")); /// # use stackline::prelude::*; /// # use stackline::tile::prelude::*; /// -/// // Tiles must implement Clone and Debug -/// #[derive(Clone, Debug)] +/// // Tiles must implement Clone, Debug, Serialize and Deserialize +/// #[derive(Clone, Debug, Serialize, Deserialize)] /// pub struct MyTile { /// // This is where your tile can store its internal state. /// // For this tile, we don't need any! @@ -138,7 +139,7 @@ include!(concat!(env!("OUT_DIR"), "/anytile.rs")); /// } /// ``` #[enum_dispatch(AnyTile)] -pub trait Tile: std::clone::Clone + std::fmt::Debug { +pub trait Tile: std::clone::Clone + std::fmt::Debug + Serialize + for<'d> Deserialize<'d> { /// Function to be called when the tile needs to be updated. #[inline] fn update<'b>(&'b mut self, mut context: UpdateContext<'b>) { @@ -201,8 +202,11 @@ pub trait Tile: std::clone::Clone + std::fmt::Debug { // } pub mod prelude { + pub use crate::prelude::*; pub use crate::tile::{FullTile, AnyTile}; pub use crate::signal::Signal; pub use crate::utils::State; pub use crate::text::*; + + pub use serde::{Serialize, Deserialize}; } diff --git a/stackline/src/utils.rs b/stackline/src/utils.rs index fd22dc0..91246bf 100644 --- a/stackline/src/utils.rs +++ b/stackline/src/utils.rs @@ -1,6 +1,8 @@ +use serde::{Serialize, Deserialize}; + /// Represents one or many undirected orientation(s), since we are in a 2D grid, /// this may either be [Horizontal](Orientation::Horizontal), [Vertical](Orientation::Vertical) or both ([Any](Orientation::Any)) -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[repr(u8)] pub enum Orientation { Horizontal, @@ -9,7 +11,7 @@ pub enum Orientation { } /// Represents one directed orientation -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[repr(u8)] pub enum Direction { Up, @@ -20,7 +22,7 @@ pub enum Direction { /// Represents the state that a cell may be in. The usual state transition schema is `Idle → Active → Dormant → Idle`. /// A tile will only be [`update`d](crate::Tile::update) if it is in the `Active` or `Dormant` state. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[repr(u8)] pub enum State { Idle, diff --git a/stackline/src/world.rs b/stackline/src/world.rs index 61eb725..8e694cd 100644 --- a/stackline/src/world.rs +++ b/stackline/src/world.rs @@ -1,6 +1,8 @@ use super::*; use std::collections::HashMap; +use serde::{Serialize, Deserialize}; +#[derive(Debug, Serialize, Deserialize)] pub struct World { panes: HashMap, } @@ -64,9 +66,9 @@ impl World { self.panes.values().fold((0, 0, 0, 0), |acc, act| { ( acc.0.min(act.position().0), - acc.1.max(act.position().0), + acc.1.max(act.position().0 + act.width().get() as i32), acc.2.min(act.position().1), - acc.3.max(act.position().1), + acc.3.max(act.position().1 + act.height().get() as i32), ) }) } diff --git a/stackline/tiles/transmit.rs b/stackline/tiles/transmit.rs index f532732..f3e91ed 100644 --- a/stackline/tiles/transmit.rs +++ b/stackline/tiles/transmit.rs @@ -1,10 +1,10 @@ //! Transmission tiles: allow for inter-Pane communication use crate::prelude::*; -// use crate::tile::prelude::*; +use crate::tile::prelude::*; /// Instantly sends any incomming signals to `coordinates` -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Teleporter { pub coordinates: (String, usize, usize), } @@ -34,7 +34,7 @@ impl Tile for Teleporter { } /// Sends a signal through a virtual wire towards `coordinates`. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Sender { pub coordinates: (String, usize, usize), pub path: Vec<(i32, i32)>, // x, y diff --git a/stackline/tiles/wire.rs b/stackline/tiles/wire.rs index bfae98a..d7175e3 100644 --- a/stackline/tiles/wire.rs +++ b/stackline/tiles/wire.rs @@ -1,9 +1,8 @@ //! Wires and diodes -use crate::prelude::*; -// use crate::tile::prelude::*; +use crate::tile::prelude::*; -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Wire(Orientation); impl Wire { @@ -46,7 +45,7 @@ impl Tile for Wire { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Diode(Direction); impl Diode { @@ -85,7 +84,7 @@ impl Tile for Diode { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Resistor { direction: Direction, signal: Option,