diff --git a/src/state.rs b/src/state.rs index 8d589dd1..24f6b1fd 100644 --- a/src/state.rs +++ b/src/state.rs @@ -457,16 +457,13 @@ impl ProgressDrawTarget { /// /// Will panic if refresh_rate is `Some(0)`. To disable rate limiting use `None` instead. pub fn term(term: Term, refresh_rate: impl Into>) -> ProgressDrawTarget { - let rate = refresh_rate - .into() - .map(|x| Duration::from_millis(1000 / x)) - .unwrap_or_else(|| Duration::from_secs(0)); ProgressDrawTarget { kind: ProgressDrawTargetKind::Term { term, last_line_count: 0, - rate, - last_draw: Instant::now() - rate, + refresh_rate: refresh_rate.into(), + last_draw: Instant::now(), + leaky_bucket: MAX_GROUP_SIZE, }, } } @@ -507,20 +504,32 @@ impl ProgressDrawTarget { ProgressDrawTargetKind::Term { ref term, ref mut last_line_count, - rate, + refresh_rate, ref mut last_draw, - } if draw_state.finished || draw_state.force_draw || last_draw.elapsed() > rate => { - if !draw_state.lines.is_empty() && draw_state.move_cursor { - term.move_cursor_up(*last_line_count)?; + ref mut leaky_bucket, + } => { + if draw_state.finished || draw_state.force_draw || *leaky_bucket < MAX_GROUP_SIZE { + if !draw_state.lines.is_empty() && draw_state.move_cursor { + term.move_cursor_up(*last_line_count)?; + } else { + term.clear_last_lines(*last_line_count)?; + } + + draw_state.draw_to_term(term)?; + term.flush()?; + *last_line_count = draw_state.lines.len() - draw_state.orphan_lines; + *leaky_bucket += 1.0; + } + if let Some(refresh_rate) = refresh_rate { + let ticks = last_draw.elapsed().as_secs_f64() * (refresh_rate as f64); + *leaky_bucket -= ticks; } else { - term.clear_last_lines(*last_line_count)?; + *leaky_bucket -= 1.0; + } + if *leaky_bucket < 0.0 { + *leaky_bucket = 0.0; } - - draw_state.draw_to_term(term)?; - term.flush()?; - *last_line_count = draw_state.lines.len() - draw_state.orphan_lines; *last_draw = Instant::now(); - Ok(()) } ProgressDrawTargetKind::Remote { idx, ref state, .. } => { @@ -555,13 +564,16 @@ impl ProgressDrawTarget { }; } } + +const MAX_GROUP_SIZE: f64 = 32.0; #[derive(Debug)] pub(crate) enum ProgressDrawTargetKind { Term { term: Term, last_line_count: usize, - rate: Duration, + refresh_rate: Option, last_draw: Instant, + leaky_bucket: f64, }, Remote { state: Arc>,