parent
a816da6062
commit
7175e65570
@ -0,0 +1,55 @@
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct World {
|
||||
panes: HashMap<String, Pane>,
|
||||
}
|
||||
|
||||
impl World {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
panes: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step(&mut self) {
|
||||
let mut outbound_signals = Vec::new();
|
||||
|
||||
for (_, pane) in self.panes.iter_mut() {
|
||||
let mut res = pane.step();
|
||||
outbound_signals.append(&mut res.outbound_signals);
|
||||
}
|
||||
|
||||
for ((name, x, y), signal) in outbound_signals {
|
||||
if let Some(pane) = self.get_pane_mut(&name) {
|
||||
let _ = pane.set_signal((x, y), signal); // Errors are ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_pane(&mut self, name: String, pane: Pane) {
|
||||
self.panes.insert(name, pane);
|
||||
}
|
||||
|
||||
pub fn get_pane<'b>(&'b self, name: &str) -> Option<&'b Pane> {
|
||||
self.panes.get(name)
|
||||
}
|
||||
|
||||
pub fn get_pane_mut<'b>(&'b mut self, name: &str) -> Option<&'b mut Pane> {
|
||||
self.panes.get_mut(name)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_world_set_pane() {
|
||||
let mut world = World::new();
|
||||
|
||||
world.set_pane(String::from("main"), Pane::empty(10, 10).unwrap());
|
||||
|
||||
assert!(world.get_pane("main").is_some());
|
||||
}
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
//! 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));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue