From 8230a41df870568826964d793ca0440084c81c9f Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Thu, 10 Feb 2022 21:17:48 +0100 Subject: [PATCH] Pass force_draw into drawable() --- src/draw_target.rs | 49 ++++++++++++++++++++++----------------------- src/multi.rs | 19 ++++++++---------- src/progress_bar.rs | 6 +++--- src/state.rs | 7 ++++--- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/src/draw_target.rs b/src/draw_target.rs index 08dce165..63da0f52 100644 --- a/src/draw_target.rs +++ b/src/draw_target.rs @@ -156,7 +156,7 @@ impl ProgressDrawTarget { } /// Apply the given draw state (draws it). - pub(crate) fn drawable(&mut self) -> Option> { + pub(crate) fn drawable(&mut self, force_draw: bool) -> Option> { match &mut self.kind { ProgressDrawTargetKind::Term { term, @@ -169,7 +169,8 @@ impl ProgressDrawTarget { .map(|b| b.try_add_work()) .unwrap_or(true); - match draw_state.force_draw || has_capacity { + draw_state.force_draw = force_draw; + match force_draw || has_capacity { true => Some(Drawable::Term { term, last_line_count, @@ -183,18 +184,21 @@ impl ProgressDrawTarget { Some(Drawable::Multi { idx: *idx, state, - force_draw: false, + force_draw, }) } ProgressDrawTargetKind::TermLike { inner, last_line_count, draw_state, - } => Some(Drawable::TermLike { - term_like: &**inner, - last_line_count, - draw_state, - }), + } => { + draw_state.force_draw = force_draw; + Some(Drawable::TermLike { + term_like: &**inner, + last_line_count, + draw_state, + }) + } // Hidden, finished, or no need to refresh yet _ => None, } @@ -209,7 +213,7 @@ impl ProgressDrawTarget { let _ = Drawable::Multi { state, idx, - force_draw: false, + force_draw: true, } .clear(); } @@ -265,24 +269,19 @@ pub(crate) enum Drawable<'a> { } impl<'a> Drawable<'a> { - pub(crate) fn state(&mut self, force_draw: bool) -> DrawStateWrapper<'_> { + pub(crate) fn state(&mut self) -> DrawStateWrapper<'_> { let mut state = match self { Drawable::Term { draw_state, .. } => DrawStateWrapper::for_term(draw_state), - Drawable::Multi { - state, - idx, - force_draw, - } => state.draw_state(*idx, force_draw), + Drawable::Multi { state, idx, .. } => state.draw_state(*idx), Drawable::TermLike { draw_state, .. } => DrawStateWrapper::for_term(draw_state), }; state.reset(); - state.force_draw = force_draw; state } pub(crate) fn clear(mut self) -> io::Result<()> { - let state = self.state(true); + let state = self.state(); drop(state); self.draw() } @@ -310,22 +309,24 @@ impl<'a> Drawable<'a> { pub(crate) struct DrawStateWrapper<'a> { state: &'a mut ProgressDrawState, - extra: Option<(&'a mut Vec, &'a mut bool)>, + orphan_lines: Option<&'a mut Vec>, } impl<'a> DrawStateWrapper<'a> { pub(crate) fn for_term(state: &'a mut ProgressDrawState) -> Self { - Self { state, extra: None } + Self { + state, + orphan_lines: None, + } } pub(crate) fn for_multi( state: &'a mut ProgressDrawState, orphan_lines: &'a mut Vec, - force_draw: &'a mut bool, ) -> Self { Self { state, - extra: Some((orphan_lines, force_draw)), + orphan_lines: Some(orphan_lines), } } } @@ -346,10 +347,9 @@ impl std::ops::DerefMut for DrawStateWrapper<'_> { impl Drop for DrawStateWrapper<'_> { fn drop(&mut self) { - if let Some((orphan_lines, force_draw)) = &mut self.extra { - orphan_lines.extend(self.state.lines.drain(..self.state.orphan_lines)); + if let Some(orphaned) = &mut self.orphan_lines { + orphaned.extend(self.state.lines.drain(..self.state.orphan_lines)); self.state.orphan_lines = 0; - **force_draw = self.state.force_draw; } } } @@ -466,6 +466,5 @@ impl ProgressDrawState { fn reset(&mut self) { self.lines.clear(); self.orphan_lines = 0; - self.force_draw = false; } } diff --git a/src/multi.rs b/src/multi.rs index 262c6b7e..b3a014d5 100644 --- a/src/multi.rs +++ b/src/multi.rs @@ -167,19 +167,20 @@ impl MultiProgressState { } } - pub(crate) fn draw(&mut self, force_draw: bool) -> io::Result<()> { + pub(crate) fn draw(&mut self, mut force_draw: bool) -> io::Result<()> { // the rest from here is only drawing, we can skip it. if self.draw_target.is_hidden() { return Ok(()); } - let mut drawable = match self.draw_target.drawable() { + let orphan_lines_count = self.orphan_lines.len(); + force_draw |= orphan_lines_count > 0; + let mut drawable = match self.draw_target.drawable(force_draw) { Some(drawable) => drawable, None => return Ok(()), }; - let orphan_lines_count = self.orphan_lines.len(); - let mut draw_state = drawable.state(force_draw || orphan_lines_count > 0); + let mut draw_state = drawable.state(); draw_state.orphan_lines = orphan_lines_count; // Make orphaned lines appear at the top, so they can be properly forgotten. @@ -195,11 +196,7 @@ impl MultiProgressState { drawable.draw() } - pub(crate) fn draw_state<'a>( - &'a mut self, - idx: usize, - force_draw: &'a mut bool, - ) -> DrawStateWrapper<'a> { + pub(crate) fn draw_state(&mut self, idx: usize) -> DrawStateWrapper<'_> { let (states, orphans) = (&mut self.draw_states, &mut self.orphan_lines); let state = match states.get_mut(idx) { Some(Some(draw_state)) => draw_state, @@ -213,7 +210,7 @@ impl MultiProgressState { _ => unreachable!(), }; - DrawStateWrapper::for_multi(state, orphans, force_draw) + DrawStateWrapper::for_multi(state, orphans) } pub(crate) fn width(&self) -> usize { @@ -263,7 +260,7 @@ impl MultiProgressState { } fn clear(&mut self) -> io::Result<()> { - match self.draw_target.drawable() { + match self.draw_target.drawable(true) { Some(drawable) => drawable.clear(), None => Ok(()), } diff --git a/src/progress_bar.rs b/src/progress_bar.rs index 5316f4a5..6b3ba858 100644 --- a/src/progress_bar.rs +++ b/src/progress_bar.rs @@ -247,12 +247,12 @@ impl ProgressBar { let (draw_target, state) = (&mut state.draw_target, &state.state); let width = draw_target.width(); - let mut drawable = match draw_target.drawable() { + let mut drawable = match draw_target.drawable(true) { Some(drawable) => drawable, None => return, }; - let mut draw_state = drawable.state(true); + let mut draw_state = drawable.state(); draw_state.move_cursor = false; draw_state.alignment = Default::default(); @@ -437,7 +437,7 @@ impl ProgressBar { /// ``` pub fn suspend R, R>(&self, f: F) -> R { let mut state = self.state.lock().unwrap(); - if let Some(drawable) = state.draw_target.drawable() { + if let Some(drawable) = state.draw_target.drawable(true) { let _ = drawable.clear(); } diff --git a/src/state.rs b/src/state.rs index 5c3b7827..8edef905 100644 --- a/src/state.rs +++ b/src/state.rs @@ -101,21 +101,22 @@ impl BarState { self.draw(true).ok(); } - pub(crate) fn draw(&mut self, force_draw: bool) -> io::Result<()> { + pub(crate) fn draw(&mut self, mut force_draw: bool) -> io::Result<()> { // we can bail early if the draw target is hidden. if self.draw_target.is_hidden() { return Ok(()); } let width = self.draw_target.width(); - let mut drawable = match self.draw_target.drawable() { + force_draw |= self.state.is_finished(); + let mut drawable = match self.draw_target.drawable(force_draw) { Some(drawable) => drawable, None => return Ok(()), }; // `|| self.is_finished()` should not be needed here, but we used to always for draw for // finished progress bar, so it's kept as to not cause compatibility issues in weird cases. - let mut draw_state = drawable.state(force_draw || self.state.is_finished()); + let mut draw_state = drawable.state(); if self.state.should_render() { self.state