diff --git a/stackline/src/text.rs b/stackline/src/text.rs index caac5d6..ce9ed7b 100644 --- a/stackline/src/text.rs +++ b/stackline/src/text.rs @@ -56,6 +56,7 @@ impl Default for TextChar { } } +#[derive(Clone)] pub struct TextSurface { width: usize, height: usize, @@ -126,6 +127,10 @@ impl TextSurface { self.height } + pub fn iter(&self) -> impl Iterator + '_ { + self.chars.iter().copied() + } + // TODO: resize } diff --git a/stackline/src/tile/mod.rs b/stackline/src/tile/mod.rs index 3f30835..a0fd479 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 std::collections::HashMap; use enum_dispatch::enum_dispatch; use serde::{Deserialize, Serialize}; @@ -184,6 +185,42 @@ pub trait Tile: std::clone::Clone + std::fmt::Debug + Serialize + for<'d> Deseri fn draw_simple(&self, ctx: DrawContext<'_>) -> TextChar { TextChar::default() } + + /// Returns the "schema" of the tile, allowing editors to provide human interfaces for + /// modifying the tile. + fn schema(&self) -> TileSchema { + TileSchema::tuple() + } +} + +/// The description of the fields of a [`Tile`] +pub enum TileSchema { + Tuple(Vec), + Map(HashMap), + Value(String), +} + +impl TileSchema { + pub fn tuple() -> Self { + Self::Tuple(Vec::new()) + } + + pub fn map() -> Self { + Self::Map(HashMap::new()) + } + + pub fn value(name: S) -> Self { + Self::Value(name.to_string()) + } + + pub fn add(mut self, name: S, value: TileSchema) -> Self { + match self { + Self::Map(ref mut map) => map.insert(name.to_string(), value), + _ => panic!("Invalid TileSchema builder: cannot add() to a non-Map"), + }; + + self + } } pub mod prelude { @@ -192,6 +229,7 @@ pub mod prelude { pub use crate::text::*; pub use crate::tile::{AnyTile, FullTile}; pub use crate::utils::State; + pub use super::TileSchema; pub use serde::{Deserialize, Serialize}; } diff --git a/stackline/tiles/storage.rs b/stackline/tiles/storage.rs index d2b06b1..62df5dd 100644 --- a/stackline/tiles/storage.rs +++ b/stackline/tiles/storage.rs @@ -131,7 +131,7 @@ impl Tile for StorageCount { } } -#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Stacker { signal: Option, /// May only be Horizontal or Vertical @@ -151,6 +151,12 @@ impl Stacker { } } +impl Default for Stacker { + fn default() -> Self { + Stacker::new(Orientation::Horizontal) + } +} + impl Tile for Stacker { fn update<'b>(&'b mut self, mut context: UpdateContext<'b>) { if let Some(mut signal) = context.take_signal() { diff --git a/stackline/tiles/transmit.rs b/stackline/tiles/transmit.rs index 4733878..4dc0e05 100644 --- a/stackline/tiles/transmit.rs +++ b/stackline/tiles/transmit.rs @@ -172,7 +172,11 @@ impl Tile for Sender { let (x, y) = if self.path.len() > 0 { (ctx.surface_coords.0 - self.path[0].0, ctx.surface_coords.1 - self.path[0].1) } else { - (ctx.surface_coords.0, ctx.surface_coords.1) + if let (Ok(x), Ok(y)) = (ctx.surface_coords.0.try_into(), ctx.surface_coords.1.try_into()) { + surface.set(x, y, TextChar::from_state('S', ctx.state)); + } + return + // (ctx.surface_coords.0, ctx.surface_coords.1) }; let mut count = 0; diff --git a/stackline/tiles/wire.rs b/stackline/tiles/wire.rs index d4f6ed8..e7e461d 100644 --- a/stackline/tiles/wire.rs +++ b/stackline/tiles/wire.rs @@ -43,6 +43,10 @@ impl Tile for Wire { TextChar::from_state(ch, ctx.state) } + + fn schema(&self) -> TileSchema { + TileSchema::value("Orientation") + } } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] @@ -87,6 +91,10 @@ impl Tile for Diode { TextChar::from_state(ch, ctx.state) } + + fn schema(&self) -> TileSchema { + TileSchema::value("Direction") + } } #[derive(Clone, Debug, Serialize, Deserialize, Default)] @@ -135,6 +143,12 @@ impl Tile for Resistor { TextChar::from_state(ch, ctx.state) } + + fn schema(&self) -> TileSchema { + TileSchema::map() + .add("direction", TileSchema::value("Direction")) + .add("signal", TileSchema::value("Signal|null")) + } } #[cfg(test)]