add fancy progress bar :D
This commit is contained in:
parent
04197d4256
commit
517a64156a
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue