|
|
|
@ -169,8 +169,38 @@ impl Tile for Sender {
|
|
|
|
|
// TODO: read self.signals to determine the state of each char
|
|
|
|
|
// TODO: automated test
|
|
|
|
|
fn draw(&self, x: i32, y: i32, _state: State, surface: &mut TextSurface) {
|
|
|
|
|
let (x, y) = if self.path.len() > 0 {
|
|
|
|
|
(x - self.path[0].0, y - self.path[0].1)
|
|
|
|
|
} else {
|
|
|
|
|
(x, y)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut count = 0;
|
|
|
|
|
|
|
|
|
|
let mut get_state = || {
|
|
|
|
|
let mut found_exact = false;
|
|
|
|
|
let mut found_next = false;
|
|
|
|
|
for (_sig, n) in self.signals.iter() {
|
|
|
|
|
if *n == count {
|
|
|
|
|
found_exact = true;
|
|
|
|
|
} else if *n == count + 1 {
|
|
|
|
|
found_next = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
count += 1;
|
|
|
|
|
|
|
|
|
|
if found_exact {
|
|
|
|
|
State::Active
|
|
|
|
|
} else if found_next {
|
|
|
|
|
State::Dormant
|
|
|
|
|
} else {
|
|
|
|
|
State::Idle
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (prev, next) in self.path.iter().zip(self.path.iter().skip(1)) {
|
|
|
|
|
if prev.0 != next.0 {
|
|
|
|
|
let (line_char, dx, dy) = if prev.0 != next.0 {
|
|
|
|
|
// Draw the diode of the corner
|
|
|
|
|
let ch = if next.0 > prev.0 { '>' } else { '<' };
|
|
|
|
|
let x2 = x + prev.0;
|
|
|
|
@ -180,22 +210,16 @@ impl Tile for Sender {
|
|
|
|
|
surface.set(
|
|
|
|
|
x2 as usize,
|
|
|
|
|
y2 as usize,
|
|
|
|
|
TextChar::from_state(ch, State::Idle),
|
|
|
|
|
TextChar::from_state(ch, get_state()),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw the horizontal line
|
|
|
|
|
// Draw an 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(
|
|
|
|
|
x2 as usize,
|
|
|
|
|
y2 as usize,
|
|
|
|
|
TextChar::from_state('-', State::Idle),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if prev.0 < next.0 {
|
|
|
|
|
('-', 1, 0)
|
|
|
|
|
} else {
|
|
|
|
|
('-', -1, 0)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Draw the diode of the corner
|
|
|
|
@ -207,27 +231,44 @@ impl Tile for Sender {
|
|
|
|
|
surface.set(
|
|
|
|
|
x2 as usize,
|
|
|
|
|
y2 as usize,
|
|
|
|
|
TextChar::from_state(ch, State::Idle),
|
|
|
|
|
TextChar::from_state(ch, get_state()),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw the vertical line
|
|
|
|
|
// Draw a vertical line
|
|
|
|
|
|
|
|
|
|
for dy in (prev.1 + 1)..(next.1) {
|
|
|
|
|
let x2 = x + prev.0;
|
|
|
|
|
let y2 = y + dy;
|
|
|
|
|
if prev.1 < next.1 {
|
|
|
|
|
('|', 0, 1)
|
|
|
|
|
} else {
|
|
|
|
|
('|', 0, -1)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Draw the line
|
|
|
|
|
for (x2, y2) in std::iter::successors(
|
|
|
|
|
Some(*prev),
|
|
|
|
|
|&curr| {
|
|
|
|
|
let res = (curr.0.checked_add(dx)?, curr.1.checked_add(dy)?);
|
|
|
|
|
if res == *next {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
Some(res)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
).skip(1) {
|
|
|
|
|
let x2 = x + x2;
|
|
|
|
|
let y2 = y + y2;
|
|
|
|
|
if x2 >= 0 && y2 >= 0 {
|
|
|
|
|
surface.set(
|
|
|
|
|
x2 as usize,
|
|
|
|
|
y2 as usize,
|
|
|
|
|
TextChar::from_state('-', State::Idle),
|
|
|
|
|
TextChar::from_state(line_char, get_state()),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod test {
|
|
|
|
|