add fancy progress bar :D

This commit is contained in:
tali 2023-04-14 13:25:29 -04:00
parent 04197d4256
commit 517a64156a
1 changed files with 54 additions and 9 deletions

View File

@ -3,7 +3,7 @@ use rand::RngCore as _;
use std::io::{Read, Write};
use std::path::Path;
use std::sync::{atomic, mpsc, Arc};
use std::time::Duration;
use std::time::{Duration, Instant};
use fish::bot;
use tidepool::{cli, config, output, sim};
@ -75,14 +75,21 @@ fn single(args: cli::SingleRun) -> Result<()> {
tracing::debug!("heartbeat");
}
Msg::Status(_id, status) => {
if !args.io.quiet {
let ps = status.pieces;
let ll = status.lines_left;
let pps = ps as f64 / status.time.as_secs_f64();
eprintln!("#{ps}, {ll} lines left, {pps:.2} pps");
if exit_early.load(atomic::Ordering::Relaxed) {
continue;
}
write_progress_bar(
&args.io,
status.pieces,
status.lines_left,
config.game.goal,
status.time,
)?;
}
Msg::Done(_id, output) => {
// dropping rx early does two things here: 1) removing any of the 'break's
// in this block become a compile error, 2) interrupts will not be able to
// be sent so the ctrl-c handler will abort the program
std::mem::drop(rx);
if output.cleared < config.game.goal {
@ -144,6 +151,44 @@ fn write_output(io_args: &cli::IoArgs, path: Option<&Path>, output: &output::Out
}
}
fn write_progress_bar(
io_args: &cli::IoArgs,
pieces: usize,
lines_left: usize,
goal: usize,
time: Duration,
) -> std::io::Result<()> {
if io_args.quiet {
return Ok(());
}
let width = 40; // TODO: get terminal size?
let cleared = goal - lines_left;
let pps = pieces as f64 / time.as_secs_f64().max(0.001);
let pace = pieces * 100 / cleared.max(1);
let writer = std::io::stderr().lock();
let mut writer = std::io::BufWriter::new(writer);
write!(writer, "\r[")?;
for i in 0..width {
if goal * i <= cleared * (width - 1) {
write!(writer, "#")
} else {
write!(writer, " ")
}?;
}
write!(
writer,
"] {cleared}/{goal} #{pieces}, {pps:.2} pps, {pace} pace"
)?;
if cleared == goal {
writeln!(writer)
} else {
writer.flush()
}
}
fn prompt_yn(io_args: &cli::IoArgs, msg: &str) -> bool {
if io_args.noninteractive {
return true;
@ -174,7 +219,7 @@ fn run_simulation(
};
let mut sim = sim::Simul::new(seed, sim_opts);
let time_start = std::time::Instant::now();
let time_start = Instant::now();
while sim.lines_left() > 0 {
if exit_early.load(atomic::Ordering::Relaxed) {
@ -213,14 +258,14 @@ fn run_simulation(
let status = Status {
lines_left: sim.lines_left(),
pieces: sim.pieces(),
time: std::time::Instant::now() - time_start,
time: Instant::now() - time_start,
};
if tx.send(Msg::Status(id, status.into())).is_err() {
break;
}
}
let time_end = std::time::Instant::now();
let time_end = Instant::now();
let profile = data_args.profile.then(|| output::Profile {
time: time_end - time_start,