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.
144 lines
3.5 KiB
144 lines
3.5 KiB
2 years ago
|
//! Transmission tiles: allow for inter-Pane communication
|
||
|
|
||
|
use crate::prelude::*;
|
||
|
|
||
|
/// Instantly sends any incomming signals to `coordinates`
|
||
|
#[derive(Clone, Debug)]
|
||
|
pub struct Portal {
|
||
|
pub coordinates: (String, usize, usize),
|
||
|
}
|
||
|
|
||
|
impl Portal {
|
||
|
pub fn new(name: String, x: usize, y: usize) -> Self {
|
||
|
Self {
|
||
|
coordinates: (name, x, y)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Tile for Portal {
|
||
|
fn update<'b>(&'b mut self, mut context: UpdateContext<'b>) {
|
||
|
if let Some(signal) = context.take_signal() {
|
||
|
context.send_outbound(self.coordinates.clone(), signal);
|
||
|
}
|
||
|
|
||
|
if context.state() != State::Idle {
|
||
|
context.next_state();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) {
|
||
|
surface.set(x, y, TextChar::from_state('P', state));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod test {
|
||
|
use super::*;
|
||
|
|
||
|
#[test]
|
||
|
fn test_portal_transmit_same_pane() {
|
||
|
use crate::{Diode, Wire};
|
||
|
use Direction::*;
|
||
|
use Orientation::*;
|
||
|
|
||
|
let mut main_pane = test_tile_setup!(
|
||
|
3,
|
||
|
3,
|
||
|
[
|
||
|
Diode::new(Right), Portal::new(String::from("main"), 2, 2), (),
|
||
|
(), (), (),
|
||
|
(), (), Wire::new(Any)
|
||
|
]
|
||
|
);
|
||
|
|
||
|
test_set_signal!(main_pane, (0, 0), Right);
|
||
|
|
||
|
let mut world = World::new();
|
||
|
world.set_pane(String::from("main"), main_pane);
|
||
|
|
||
|
world.step();
|
||
|
|
||
|
assert_signal!(world.get_pane("main").unwrap(), (1, 0));
|
||
|
|
||
|
world.step();
|
||
|
|
||
|
assert_no_signal!(world.get_pane("main").unwrap(), (1, 0));
|
||
|
assert_signal!(world.get_pane("main").unwrap(), (2, 2));
|
||
|
|
||
|
world.step();
|
||
|
|
||
|
assert_no_signal!(world.get_pane("main").unwrap(), (0, 0));
|
||
|
assert_no_signal!(world.get_pane("main").unwrap(), (1, 0));
|
||
|
assert_no_signal!(world.get_pane("main").unwrap(), (2, 2));
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_portal_transmit_other_pane() {
|
||
|
use crate::{Diode, Wire};
|
||
|
use Direction::*;
|
||
|
use Orientation::*;
|
||
|
|
||
|
let mut main_pane = test_tile_setup!(
|
||
|
2,
|
||
|
1,
|
||
|
[
|
||
|
Diode::new(Right), Portal::new(String::from("sub"), 0, 0),
|
||
|
]
|
||
|
);
|
||
|
|
||
|
test_set_signal!(main_pane, (0, 0), Right);
|
||
|
|
||
|
let sub_pane = test_tile_setup!(
|
||
|
1,
|
||
|
1,
|
||
|
[
|
||
|
Wire::new(Any),
|
||
|
]
|
||
|
);
|
||
|
|
||
|
let mut world = World::new();
|
||
|
world.set_pane(String::from("main"), main_pane);
|
||
|
world.set_pane(String::from("sub"), sub_pane);
|
||
|
|
||
|
world.step();
|
||
|
|
||
|
assert_signal!(world.get_pane("main").unwrap(), (1, 0));
|
||
|
|
||
|
world.step();
|
||
|
|
||
|
assert_no_signal!(world.get_pane("main").unwrap(), (1, 0));
|
||
|
assert_signal!(world.get_pane("sub").unwrap(), (0, 0));
|
||
|
|
||
|
world.step();
|
||
|
|
||
|
assert_no_signal!(world.get_pane("main").unwrap(), (0, 0));
|
||
|
assert_no_signal!(world.get_pane("main").unwrap(), (1, 0));
|
||
|
assert_no_signal!(world.get_pane("sub").unwrap(), (0, 0));
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_portal_transmit_self() {
|
||
|
use Direction::*;
|
||
|
|
||
|
let mut main_pane = test_tile_setup!(
|
||
|
1,
|
||
|
1,
|
||
|
[
|
||
|
Portal::new(String::from("main"), 0, 0),
|
||
|
]
|
||
|
);
|
||
|
|
||
|
test_set_signal!(main_pane, (0, 0), Right);
|
||
|
|
||
|
let mut world = World::new();
|
||
|
world.set_pane(String::from("main"), main_pane);
|
||
|
|
||
|
for _ in 0..5 {
|
||
|
world.step();
|
||
|
|
||
|
assert_signal!(world.get_pane("main").unwrap(), (0, 0));
|
||
|
}
|
||
|
}
|
||
|
}
|