use firework::{drawing::Drawable, types::Drawables};
use std::{
io::{Error, Stdout, Write},
sync::mpsc::Receiver,
thread,
time::Duration,
};
use termion::{color::Rgb, cursor::Goto};
use crate::firework;
pub fn start(stdout: &mut Stdout, regen_buffer: Receiver<Drawables>, end_signal: Receiver<bool>) {
write!(stdout, "{}{}", termion::clear::All, termion::cursor::Hide)
.expect("Unable to clear terminal for writing");
let (mut prev_length, mut prev_width) = terminal_length_width();
loop {
let to_draw = regen_buffer.recv().expect("Renderer unexpectedly died!");
output_grid(&to_draw, stdout, prev_length, prev_width)
.expect("Unable to write to terminal. Exiting.");
let (length, width) = terminal_length_width();
prev_length = length;
prev_width = width;
if let Ok(v) = end_signal.try_recv() {
if v {
for _ in regen_buffer.iter() {
}
write!(stdout, "{}{}", termion::clear::All, termion::cursor::Show)
.expect("Unable to restore terminal");
return;
}
}
thread::sleep(Duration::from_millis(65));
}
}
fn output_grid(
drawables: &[Box<dyn Drawable>],
stdout: &mut Stdout,
prev_length: u16,
prev_width: u16,
) -> Result<(), Error> {
let (length, width) = terminal_length_width();
if length != prev_length || width != prev_width {
write!(stdout, "{}", termion::clear::All)?;
} else {
for drawable in drawables.iter() {
let points = drawable.clear();
for point in points.iter() {
if point.y < width {
write!(
stdout,
"{}{} ",
Goto(point.x % length, width - point.y),
termion::cursor::Hide,
)?;
}
}
let points = drawable.draw();
for point in points.iter() {
if point.y < width {
write!(
stdout,
"{}{}{}*",
Goto(point.x % length, width - point.y),
termion::cursor::Hide,
Rgb(
point.pixel_color.r,
point.pixel_color.g,
point.pixel_color.b
)
.fg_string()
)?;
}
}
}
}
stdout.flush()?;
Ok(())
}
fn terminal_length_width() -> (u16, u16) {
termion::terminal_size().expect("Unable to get terminal size")
}