Closed chris-laplante closed 2 years ago
This sounds reasonable. I don't have a deep understanding of MultiProgress
paged in right now and the video doesn't want to play for me ("Video can't be played because the file is corrupt" -- Firefox on macOS), but I'd be happy to review a PR for this.
Consider this small example program:
It creates one more spinner that there are lines in the terminal. Here is a video of it running:
https://user-images.githubusercontent.com/40474653/166507072-efdbaf25-82e5-4f25-91ac-e6ab51db2314.mp4
Since we never call
MultiProgress::remove
onProgressBar
s that are dropped/finished (see #419), bars are always redrawn even when they don't need to be. When the number of bars (n) becomes greater than terminal lines (m), on each drawMultiProgress
will clear the last m lines but write n lines, leaving m - n lines in the scrollback history.I propose the following algorithm. On each
MultiProgress:draw
, iterate over the bars in order (according toMultiState::ordering
) andtake_while(|bar| bar.is_finished())
. This set of leading progress bars is then pruned by callingMultiProgress:remove
on each one. This ensures we are not re-drawing bars that don't need to be redrawn and that we are some reclaiming memory.The wrinkle is that
MultiState
cannot currently get at theProgressState
to checkis_finished()
, so we will need to restructure some code.