🔥 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 y = y as i32 + dy + self.position.1 as i32;
if x >= 0 && y >= 0 {
tile.draw(x as usize, y as usize, surface);
}
tile.draw(x, y, surface);
}
}
}

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

@ -88,7 +88,7 @@ impl FullTile {
/// Draws itself on a [`TextSurface`] at `(x, y)`.
/// 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 {
Some(ref cell) => cell.draw(x, y, self.state, surface),
None => {}

@ -156,51 +156,24 @@ pub trait Tile: std::clone::Clone + std::fmt::Debug + Serialize + for<'d> Deseri
/// Should draw itself on a [`TextSurface`].
/// 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
#[inline]
#[allow(unused_variables)]
fn draw(&self, x: usize, y: usize, state: State, surface: &mut TextSurface) {
// noop
fn draw(&self, x: i32, y: i32, state: State, surface: &mut TextSurface) {
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 {
// #[inline]
// fn clone(&self) -> Self {
// Self(clone_box(self.0.as_ref()))
// }
// }
// impl<T: Tile + 'static> From<T> for AnyTile {
// fn from(tile: T) -> AnyTile {
// AnyTile(Box::new(tile))
// }
// }
/// Used by the default implementation of `draw`,
#[inline]
#[allow(unused_variables)]
fn draw_simple(&self, state: State) -> TextChar {
TextChar::default()
}
}
pub mod prelude {
pub use crate::prelude::*;

@ -25,3 +25,14 @@ fn test_diode_loop() {
run!(world, 4);
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) {
surface.set(x, y, TextChar::from_state('P', state));
fn draw_simple(&self, state: State) -> TextChar {
TextChar::from_state('P', state)
}
}
@ -166,53 +166,71 @@ impl Tile for Sender {
// TODO: read self.signals to determine the state of each char
// 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)) {
if prev.0 != next.0 {
// Draw the diode of the corner
let ch = if next.0 > prev.0 { '>' } else { '<' };
let x2 = x + prev.0;
let y2 = y + prev.1;
if x2 >= 0 && y2 >= 0 {
surface.set(
(x as i32 + prev.0) as usize,
(y as i32 + prev.1) as usize,
x2 as usize,
y2 as usize,
TextChar::from_state(ch, State::Idle),
);
}
// Draw the horizontal line
for dx in (prev.0 + 1)..(next.0) {
let x2 = x + dx;
let y2 = y + prev.1;
if x2 >= 0 && y2 >= 0 {
surface.set(
(x as i32 + dx) as usize,
(y as i32 + prev.1) as usize,
x2 as usize,
y2 as usize,
TextChar::from_state('-', State::Idle),
);
}
}
} else {
// Draw the diode of the corner
let ch = if next.1 > prev.1 { 'v' } else { '^' };
let x2 = x + prev.0;
let y2 = y + prev.1;
if x2 >= 0 && y2 >= 0 {
surface.set(
(x as i32 + prev.0) as usize,
(y as i32 + prev.1) as usize,
x2 as usize,
y2 as usize,
TextChar::from_state(ch, State::Idle),
);
}
// Draw the vertical line
for dy in (prev.1 + 1)..(next.1) {
let x2 = x + prev.0;
let y2 = y + dy;
if x2 >= 0 && y2 >= 0 {
surface.set(
(y as i32 + prev.0) as usize,
(y as i32 + dy) as usize,
TextChar::from_state('|', State::Idle),
x2 as usize,
y2 as usize,
TextChar::from_state('-', State::Idle),
);
}
}
}
}
}
}
#[cfg(test)]
mod test {
use super::*;
use veccell::{VecRef, VecRefMut};
use veccell::{VecRef};
#[test]
fn test_teleporter_transmit_same_pane() {

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

Loading…
Cancel
Save