Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass force_draw into drawable() #371

Merged
merged 1 commit into from Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 24 additions & 25 deletions src/draw_target.rs
Expand Up @@ -156,7 +156,7 @@ impl ProgressDrawTarget {
}

/// Apply the given draw state (draws it).
pub(crate) fn drawable(&mut self) -> Option<Drawable<'_>> {
pub(crate) fn drawable(&mut self, force_draw: bool) -> Option<Drawable<'_>> {
match &mut self.kind {
ProgressDrawTargetKind::Term {
term,
Expand All @@ -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,
Expand All @@ -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,
}
Expand All @@ -209,7 +213,7 @@ impl ProgressDrawTarget {
let _ = Drawable::Multi {
state,
idx,
force_draw: false,
force_draw: true,
}
.clear();
}
Expand Down Expand Up @@ -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()
}
Expand Down Expand Up @@ -310,22 +309,24 @@ impl<'a> Drawable<'a> {

pub(crate) struct DrawStateWrapper<'a> {
state: &'a mut ProgressDrawState,
extra: Option<(&'a mut Vec<String>, &'a mut bool)>,
orphan_lines: Option<&'a mut Vec<String>>,
}

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<String>,
force_draw: &'a mut bool,
) -> Self {
Self {
state,
extra: Some((orphan_lines, force_draw)),
orphan_lines: Some(orphan_lines),
}
}
}
Expand All @@ -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;
}
}
}
Expand Down Expand Up @@ -466,6 +466,5 @@ impl ProgressDrawState {
fn reset(&mut self) {
self.lines.clear();
self.orphan_lines = 0;
self.force_draw = false;
}
}
19 changes: 8 additions & 11 deletions src/multi.rs
Expand Up @@ -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.
Expand All @@ -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,
Expand All @@ -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 {
Expand Down Expand Up @@ -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(()),
}
Expand Down
6 changes: 3 additions & 3 deletions src/progress_bar.rs
Expand Up @@ -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();

Expand Down Expand Up @@ -437,7 +437,7 @@ impl ProgressBar {
/// ```
pub fn suspend<F: FnOnce() -> 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();
}

Expand Down
7 changes: 4 additions & 3 deletions src/state.rs
Expand Up @@ -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
Expand Down