You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.3 KiB

//! 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)
}
}
fn schema(&self) -> TileSchema {
// TODO: add Vec<Signal>?
TileSchema::map()
.add(
"invert",
TileSchema::value("Invert", "Bool")
)
}
}