🔥 Tile::draw accepts i32, Tile::draw_simple

main
Shad Amethyst 2 years ago
parent d4a6522d07
commit be259cc6f5
Signed by: amethyst
GPG Key ID: D970C8DD1D6DEE36

@ -514,9 +514,7 @@ impl Pane {
let x = x as i32 + dx + self.position.0 as i32; let x = x as i32 + dx + self.position.0 as i32;
let y = y as i32 + dy + self.position.1 as i32; let y = y as i32 + dy + self.position.1 as i32;
if x >= 0 && y >= 0 { tile.draw(x, y, surface);
tile.draw(x as usize, y as usize, surface);
}
} }
} }
} }

@ -65,6 +65,7 @@ pub struct TextSurface {
impl TextSurface { impl TextSurface {
pub fn new(width: usize, height: usize) -> Self { pub fn new(width: usize, height: usize) -> Self {
// TODO: return None if width or height don't fit in an i32
Self { Self {
width, width,
height, height,

@ -88,7 +88,7 @@ impl FullTile {
/// Draws itself on a [`TextSurface`] at `(x, y)`. /// Draws itself on a [`TextSurface`] at `(x, y)`.
/// If the tile is empty, does nothing /// If the tile is empty, does nothing
pub fn draw(&self, x: usize, y: usize, surface: &mut TextSurface) { pub fn draw(&self, x: i32, y: i32, surface: &mut TextSurface) {
match self.cell { match self.cell {
Some(ref cell) => cell.draw(x, y, self.state, surface), Some(ref cell) => cell.draw(x, y, self.state, surface),
None => {} None => {}

@ -156,51 +156,24 @@ pub trait Tile: std::clone::Clone + std::fmt::Debug + Serialize + for<'d> Deseri
/// Should draw itself on a [`TextSurface`]. /// Should draw itself on a [`TextSurface`].
/// The `Tile` is allowed to draw outside of its coordinates, although doing so might cause glitches. /// The `Tile` is allowed to draw outside of its coordinates, although doing so might cause glitches.
///
/// By default, draws a single character at the tile's location, determined by [`Tile::draw_simple`]
// TODO: Use a 2d slice type // TODO: Use a 2d slice type
#[inline] #[inline]
#[allow(unused_variables)] #[allow(unused_variables)]
fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) { fn draw(&self, x: i32, y: i32, state: State, surface: &mut TextSurface) {
// noop if let (Ok(x), Ok(y)) = (x.try_into(), y.try_into()) {
surface.set(x, y, self.draw_simple(state));
}
} }
}
// #[derive(Debug)]
// pub struct AnyTile(Box<dyn Tile>);
// impl AnyTile {
// #[inline]
// pub fn new<T: Tile + 'static>(tile: T) -> Self {
// Self(Box::new(tile))
// }
// #[inline]
// pub fn update<'b>(&'b mut self, ctx: UpdateContext<'b>) {
// self.0.update(ctx)
// }
// #[inline]
// pub fn accepts_signal(&self, direction: Direction) -> bool {
// self.0.accepts_signal(direction)
// }
// #[inline]
// pub fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) {
// self.0.draw(x, y, state, surface);
// }
// }
// impl Clone for AnyTile { /// Used by the default implementation of `draw`,
// #[inline] #[inline]
// fn clone(&self) -> Self { #[allow(unused_variables)]
// Self(clone_box(self.0.as_ref())) fn draw_simple(&self, state: State) -> TextChar {
// } TextChar::default()
// } }
}
// impl<T: Tile + 'static> From<T> for AnyTile {
// fn from(tile: T) -> AnyTile {
// AnyTile(Box::new(tile))
// }
// }
pub mod prelude { pub mod prelude {
pub use crate::prelude::*; pub use crate::prelude::*;

@ -25,3 +25,14 @@ fn test_diode_loop() {
run!(world, 4); run!(world, 4);
assert_signal!(world, 1, 1); assert_signal!(world, 1, 1);
} }
#[test]
fn test_display_oob() {
let world = load_test!("tests/wire/diode-loop.json");
println!("{}", world);
let mut surface = TextSurface::new(0, 0);
world.draw(0, 0, &mut surface);
world.draw(-1000, -1000, &mut surface);
}

@ -28,8 +28,8 @@ impl Tile for Teleporter {
} }
} }
fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) { fn draw_simple(&self, state: State) -> TextChar {
surface.set(x, y, TextChar::from_state('P', state)); TextChar::from_state('P', state)
} }
} }
@ -166,43 +166,61 @@ impl Tile for Sender {
// TODO: read self.signals to determine the state of each char // TODO: read self.signals to determine the state of each char
// TODO: automated test // TODO: automated test
fn draw(&self, x: usize, y: usize, _state: State, surface: &mut TextSurface) { fn draw(&self, x: i32, y: i32, _state: State, surface: &mut TextSurface) {
for (prev, next) in self.path.iter().zip(self.path.iter().skip(1)) { for (prev, next) in self.path.iter().zip(self.path.iter().skip(1)) {
if prev.0 != next.0 { if prev.0 != next.0 {
// Draw the diode of the corner // Draw the diode of the corner
let ch = if next.0 > prev.0 { '>' } else { '<' }; let ch = if next.0 > prev.0 { '>' } else { '<' };
surface.set( let x2 = x + prev.0;
(x as i32 + prev.0) as usize, let y2 = y + prev.1;
(y as i32 + prev.1) as usize,
TextChar::from_state(ch, State::Idle), if x2 >= 0 && y2 >= 0 {
); surface.set(
x2 as usize,
y2 as usize,
TextChar::from_state(ch, State::Idle),
);
}
// Draw the horizontal line // Draw the horizontal line
for dx in (prev.0 + 1)..(next.0) { for dx in (prev.0 + 1)..(next.0) {
surface.set( let x2 = x + dx;
(x as i32 + dx) as usize, let y2 = y + prev.1;
(y as i32 + prev.1) as usize, if x2 >= 0 && y2 >= 0 {
TextChar::from_state('-', State::Idle), surface.set(
); x2 as usize,
y2 as usize,
TextChar::from_state('-', State::Idle),
);
}
} }
} else { } else {
// Draw the diode of the corner // Draw the diode of the corner
let ch = if next.1 > prev.1 { 'v' } else { '^' }; let ch = if next.1 > prev.1 { 'v' } else { '^' };
surface.set( let x2 = x + prev.0;
(x as i32 + prev.0) as usize, let y2 = y + prev.1;
(y as i32 + prev.1) as usize,
TextChar::from_state(ch, State::Idle), if x2 >= 0 && y2 >= 0 {
); surface.set(
x2 as usize,
y2 as usize,
TextChar::from_state(ch, State::Idle),
);
}
// Draw the vertical line // Draw the vertical line
for dy in (prev.1 + 1)..(next.1) { for dy in (prev.1 + 1)..(next.1) {
surface.set( let x2 = x + prev.0;
(y as i32 + prev.0) as usize, let y2 = y + dy;
(y as i32 + dy) as usize, if x2 >= 0 && y2 >= 0 {
TextChar::from_state('|', State::Idle), surface.set(
); x2 as usize,
y2 as usize,
TextChar::from_state('-', State::Idle),
);
}
} }
} }
} }
@ -212,7 +230,7 @@ impl Tile for Sender {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use veccell::{VecRef, VecRefMut}; use veccell::{VecRef};
#[test] #[test]
fn test_teleporter_transmit_same_pane() { fn test_teleporter_transmit_same_pane() {

@ -34,14 +34,14 @@ impl Tile for Wire {
self.0.contains(direction) self.0.contains(direction)
} }
fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) { fn draw_simple(&self, state: State) -> TextChar {
let ch = match self.0 { let ch = match self.0 {
Orientation::Horizontal => '-', Orientation::Horizontal => '-',
Orientation::Vertical => '|', Orientation::Vertical => '|',
Orientation::Any => '+', Orientation::Any => '+',
}; };
surface.set(x, y, TextChar::from_state(ch, state)); TextChar::from_state(ch, state)
} }
} }
@ -76,7 +76,7 @@ impl Tile for Diode {
direction.opposite() != self.0 direction.opposite() != self.0
} }
fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) { fn draw_simple(&self, state: State) -> TextChar {
let ch = match self.0 { let ch = match self.0 {
Direction::Up => '^', Direction::Up => '^',
Direction::Down => 'v', Direction::Down => 'v',
@ -84,7 +84,7 @@ impl Tile for Diode {
Direction::Right => '>', Direction::Right => '>',
}; };
surface.set(x, y, TextChar::from_state(ch, state)); TextChar::from_state(ch, state)
} }
} }
@ -121,7 +121,7 @@ impl Tile for Resistor {
} }
} }
fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) { fn draw_simple(&self, state: State) -> TextChar {
let ch = match self.direction { let ch = match self.direction {
Direction::Up => '\u{2191}', // Upwards Arrow Direction::Up => '\u{2191}', // Upwards Arrow
Direction::Down => '\u{2193}', // Downwards Arrow Direction::Down => '\u{2193}', // Downwards Arrow
@ -129,7 +129,7 @@ impl Tile for Resistor {
Direction::Right => '\u{2192}', // Rightwards Arrow Direction::Right => '\u{2192}', // Rightwards Arrow
}; };
surface.set(x, y, TextChar::from_state(ch, state)); TextChar::from_state(ch, state)
} }
} }

Loading…
Cancel
Save