//! Logical operations: if, etc. use crate::prelude::*; use crate::tile::prelude::*; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct If { invert: bool, } impl If { pub fn new(invert: bool) -> Self { Self { invert } } } impl Tile for If { fn update<'b>(&'b mut self, mut context: UpdateContext<'b>) { if let Some(mut signal) = context.take_signal() { let truthy = match signal.pop() { Some(Value::Number(x)) => x != 0.0, Some(Value::String(s)) => !s.is_empty(), _ => false }; let reorient = if self.invert { truthy } else { !truthy }; if reorient { if matches!(signal.direction(), Direction::Left | Direction::Right) { if let Some(up) = context.offset((0, -1)) { let _ = context.send(up, Direction::Up, signal.clone()); } if let Some(down) = context.offset((0, 1)) { let _ = context.send(down, Direction::Down, signal); } } else { if let Some(left) = context.offset((-1, 0)) { let _ = context.send(left, Direction::Left, signal.clone()); } if let Some(right) = context.offset((1, 0)) { let _ = context.send(right, Direction::Right, signal); } } } else { if let Some(target_position) = context.offset(signal.direction().into_offset()) { let _ = context.send(target_position, signal.direction(), signal); } } } if context.state() != State::Idle { context.next_state(); } } fn draw_simple(&self, ctx: DrawContext) -> TextChar { if self.invert { TextChar::from_state('¿', ctx.state) } else { TextChar::from_state('?', ctx.state) } } }