diff --git a/stackline/src/lib.rs b/stackline/src/lib.rs index 805e154..ad8b438 100644 --- a/stackline/src/lib.rs +++ b/stackline/src/lib.rs @@ -39,7 +39,7 @@ pub mod prelude { pub use crate::text::{TextChar, TextSurface}; - pub use crate::context::{UpdateContext, InitContext}; + pub use crate::context::{InitContext, UpdateContext}; pub use crate::signal::{Signal, Value}; pub use crate::tile::Tile; pub use crate::utils::*; diff --git a/stackline/tiles/transmit.rs b/stackline/tiles/transmit.rs index 4acb822..28354ca 100644 --- a/stackline/tiles/transmit.rs +++ b/stackline/tiles/transmit.rs @@ -169,8 +169,38 @@ impl Tile for Sender { // TODO: read self.signals to determine the state of each char // TODO: automated test fn draw(&self, x: i32, y: i32, _state: State, surface: &mut TextSurface) { + let (x, y) = if self.path.len() > 0 { + (x - self.path[0].0, y - self.path[0].1) + } else { + (x, y) + }; + + let mut count = 0; + + let mut get_state = || { + let mut found_exact = false; + let mut found_next = false; + for (_sig, n) in self.signals.iter() { + if *n == count { + found_exact = true; + } else if *n == count + 1 { + found_next = true; + } + } + + count += 1; + + if found_exact { + State::Active + } else if found_next { + State::Dormant + } else { + State::Idle + } + }; + for (prev, next) in self.path.iter().zip(self.path.iter().skip(1)) { - if prev.0 != next.0 { + let (line_char, dx, dy) = if prev.0 != next.0 { // Draw the diode of the corner let ch = if next.0 > prev.0 { '>' } else { '<' }; let x2 = x + prev.0; @@ -180,22 +210,16 @@ impl Tile for Sender { surface.set( x2 as usize, y2 as usize, - TextChar::from_state(ch, State::Idle), + TextChar::from_state(ch, get_state()), ); } - // Draw the horizontal line - - for dx in (prev.0 + 1)..(next.0) { - let x2 = x + dx; - let y2 = y + prev.1; - if x2 >= 0 && y2 >= 0 { - surface.set( - x2 as usize, - y2 as usize, - TextChar::from_state('-', State::Idle), - ); - } + // Draw an horizontal line + + if prev.0 < next.0 { + ('-', 1, 0) + } else { + ('-', -1, 0) } } else { // Draw the diode of the corner @@ -207,23 +231,40 @@ impl Tile for Sender { surface.set( x2 as usize, y2 as usize, - TextChar::from_state(ch, State::Idle), + TextChar::from_state(ch, get_state()), ); } - // Draw the vertical line - - for dy in (prev.1 + 1)..(next.1) { - let x2 = x + prev.0; - let y2 = y + dy; - if x2 >= 0 && y2 >= 0 { - surface.set( - x2 as usize, - y2 as usize, - TextChar::from_state('-', State::Idle), - ); + // Draw a vertical line + + if prev.1 < next.1 { + ('|', 0, 1) + } else { + ('|', 0, -1) + } + }; + + // Draw the line + for (x2, y2) in std::iter::successors( + Some(*prev), + |&curr| { + let res = (curr.0.checked_add(dx)?, curr.1.checked_add(dy)?); + if res == *next { + None + } else { + Some(res) } } + ).skip(1) { + let x2 = x + x2; + let y2 = y + y2; + if x2 >= 0 && y2 >= 0 { + surface.set( + x2 as usize, + y2 as usize, + TextChar::from_state(line_char, get_state()), + ); + } } } }