From 30c92e6647a89f3fd14c07619e4a71a0a8173a45 Mon Sep 17 00:00:00 2001 From: Adrien Burgun Date: Fri, 24 Jun 2022 16:03:55 +0200 Subject: [PATCH] :sparkles: enum_dispatch --- stackline/Cargo.toml | 1 + stackline/benches/dispatch.rs | 37 ++++++++++++---- stackline/src/tile/full.rs | 6 ++- stackline/src/tile/mod.rs | 80 +++++++++++++++++++++-------------- 4 files changed, 83 insertions(+), 41 deletions(-) diff --git a/stackline/Cargo.toml b/stackline/Cargo.toml index a0fab18..2ca276e 100755 --- a/stackline/Cargo.toml +++ b/stackline/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] dyn-clone = "1.0" palette = "0.6" +enum_dispatch = "0.3" [dev-dependencies] colored = "2.0" diff --git a/stackline/benches/dispatch.rs b/stackline/benches/dispatch.rs index 2a924ae..b146838 100644 --- a/stackline/benches/dispatch.rs +++ b/stackline/benches/dispatch.rs @@ -4,16 +4,19 @@ use stackline::tile::*; fn benchmark_step(c: &mut Criterion) { c.bench_function("Pane::step", |b| { - let mut pane = Pane::empty(3, 3).unwrap(); + let mut pane = Pane::empty(4, 4).unwrap(); pane.set_tile((0, 0), Diode::new(Direction::Right)); - pane.set_tile((2, 0), Diode::new(Direction::Down)); - pane.set_tile((2, 2), Diode::new(Direction::Left)); - pane.set_tile((0, 2), Diode::new(Direction::Up)); - pane.set_tile((1, 0), Wire::new(Orientation::Horizontal)); - pane.set_tile((1, 2), Wire::new(Orientation::Horizontal)); - pane.set_tile((0, 1), Wire::new(Orientation::Vertical)); - pane.set_tile((2, 1), Wire::new(Orientation::Vertical)); + pane.set_tile((3, 0), Diode::new(Direction::Down)); + pane.set_tile((3, 3), Diode::new(Direction::Left)); + pane.set_tile((0, 3), Diode::new(Direction::Up)); + + for n in 1..3 { + pane.set_tile((n, 0), Wire::new(Orientation::Horizontal)); + pane.set_tile((n, 3), Wire::new(Orientation::Horizontal)); + pane.set_tile((0, n), Wire::new(Orientation::Vertical)); + pane.set_tile((3, n), Wire::new(Orientation::Vertical)); + } pane.set_signal((0, 0), stackline::signal!( (0, 0), @@ -21,6 +24,24 @@ fn benchmark_step(c: &mut Criterion) { [] )); + pane.set_signal((3, 0), stackline::signal!( + (3, 0), + Direction::Down, + [] + )); + + pane.set_signal((3, 3), stackline::signal!( + (3, 3), + Direction::Left, + [] + )); + + pane.set_signal((0, 3), stackline::signal!( + (0, 3), + Direction::Up, + [] + )); + b.iter(|| pane.step()); }); } diff --git a/stackline/src/tile/full.rs b/stackline/src/tile/full.rs index e9a89e2..af476d1 100644 --- a/stackline/src/tile/full.rs +++ b/stackline/src/tile/full.rs @@ -102,10 +102,12 @@ impl Default for FullTile { } } -impl From for FullTile { +impl From for FullTile +where AnyTile: From +{ #[inline] fn from(tile: T) -> Self { - Self::new(Some(AnyTile::new(tile))) + Self::new(Some(AnyTile::from(tile))) } } diff --git a/stackline/src/tile/mod.rs b/stackline/src/tile/mod.rs index 5d70965..4b08779 100644 --- a/stackline/src/tile/mod.rs +++ b/stackline/src/tile/mod.rs @@ -1,5 +1,6 @@ use super::*; use dyn_clone::{clone_box, DynClone}; +use enum_dispatch::enum_dispatch; mod wire; pub use wire::*; @@ -7,6 +8,17 @@ pub use wire::*; mod full; pub use full::*; +// TODO: implement a build.rs to auto-generate AnyTile + +#[derive(Clone, Debug)] +#[enum_dispatch] +pub enum AnyTile { + Wire(Wire), + Diode(Diode), + Resistor(Resistor), +} + +#[enum_dispatch(AnyTile)] pub trait Tile: DynClone + std::fmt::Debug { /// Function to be called when the tile needs to be updated. #[inline] @@ -31,37 +43,43 @@ pub trait Tile: DynClone + std::fmt::Debug { } } -#[derive(Debug)] -pub struct AnyTile(Box); - -impl AnyTile { - #[inline] - pub fn new(tile: T) -> Self { - Self(Box::new(tile)) - } - - #[inline] - pub fn update<'b>(&'b mut self, ctx: UpdateContext<'b>) { - self.0.update(ctx) - } - - #[inline] - pub fn accepts_signal(&self, direction: Direction) -> bool { - self.0.accepts_signal(direction) - } - - #[inline] - pub fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) { - self.0.draw(x, y, state, surface); - } -} - -impl Clone for AnyTile { - #[inline] - fn clone(&self) -> Self { - Self(clone_box(self.0.as_ref())) - } -} +// #[derive(Debug)] +// pub struct AnyTile(Box); + +// impl AnyTile { +// #[inline] +// pub fn new(tile: T) -> Self { +// Self(Box::new(tile)) +// } + +// #[inline] +// pub fn update<'b>(&'b mut self, ctx: UpdateContext<'b>) { +// self.0.update(ctx) +// } + +// #[inline] +// pub fn accepts_signal(&self, direction: Direction) -> bool { +// self.0.accepts_signal(direction) +// } + +// #[inline] +// pub fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) { +// self.0.draw(x, y, state, surface); +// } +// } + +// impl Clone for AnyTile { +// #[inline] +// fn clone(&self) -> Self { +// Self(clone_box(self.0.as_ref())) +// } +// } + +// impl From for AnyTile { +// fn from(tile: T) -> AnyTile { +// AnyTile(Box::new(tile)) +// } +// } #[cfg(test)] mod crate_macros {