pub mod terminal;
pub mod train;
pub mod smoke;
pub mod config;
pub mod render;
pub mod debug;
use crate::terminal::{Terminal, InputAction};
use crate::config::Config;
use crate::render::render_frame;
use std::thread;
use std::time::Duration;
use std::io;
const FRAME_TIME_MS: u64 = 40;
pub fn run<I, T>(args: I) -> io::Result<()>
where
I: IntoIterator<Item = T>,
T: AsRef<str>,
{
run_with_token(args, None)
}
pub fn run_with_token<I, T>(args: I, cancel_token: Option<wasibox_core::CancellationToken>) -> io::Result<()>
where
I: IntoIterator<Item = T>,
T: AsRef<str>,
{
let config = Config::from_args(args);
let terminal = Terminal::new()?;
let width = terminal.width() as i32;
let max_length = if config.logo { 40 } else if config.c51 { 95 } else { 83 };
let mut pattern = 0usize;
let mut paused = false;
for x in (-(max_length + 10)..=(width + 10)).rev() {
if let Some(token) = &cancel_token {
if token.is_cancelled() {
break;
}
}
match terminal.check_input()? {
InputAction::Quit => break,
InputAction::Pause => {
paused = !paused;
if paused {
eprintln!("⏸️ PAUSED - Press Space or P to resume, Ctrl+C to quit");
}
}
InputAction::None => {}
}
while paused {
if let Some(token) = &cancel_token {
if token.is_cancelled() {
return Ok(());
}
}
thread::sleep(Duration::from_millis(100));
match terminal.check_input()? {
InputAction::Pause => {
paused = false;
eprintln!("▶️ RESUMED");
}
InputAction::Quit => return Ok(()),
InputAction::None => {}
}
}
render_frame(&terminal, x, pattern, &config)?;
pattern = (pattern + 1) % 6;
thread::sleep(Duration::from_millis(FRAME_TIME_MS));
}
Ok(())
}