Correctly print final progress when ProgressBar is destructed

Fixes issue #46
This commit is contained in:
Daniel Wolf 2019-01-02 14:29:19 +01:00
parent 11a29ddef6
commit d0c9a294e9
2 changed files with 34 additions and 19 deletions

View File

@ -8,9 +8,21 @@
using std::string;
ProgressBar::ProgressBar(std::ostream& stream) :
double sanitizeProgress(double progress) {
// Make sure value is in [0..1] range
return std::isnan(progress)
? 0.0
: boost::algorithm::clamp(progress, 0.0, 1.0);
}
ProgressBar::ProgressBar(double progress) :
ProgressBar(std::cerr, progress)
{}
ProgressBar::ProgressBar(std::ostream& stream, double progress) :
stream(stream)
{
currentProgress = sanitizeProgress(progress);
updateLoopFuture = std::async(std::launch::async, &ProgressBar::updateLoop, this);
}
@ -20,37 +32,38 @@ ProgressBar::~ProgressBar() {
}
void ProgressBar::reportProgress(double value) {
// Make sure value is in [0..1] range
value = boost::algorithm::clamp(value, 0.0, 1.0);
if (std::isnan(value)) {
value = 0.0;
}
currentProgress = value;
currentProgress = sanitizeProgress(value);
}
void ProgressBar::updateLoop() {
const int blockCount = 20;
const std::chrono::milliseconds animationInterval(1000 / 8);
const string animation = "|/-\\";
while (!done) {
int progressBlockCount = static_cast<int>(currentProgress * blockCount);
int percent = static_cast<int>(currentProgress * 100);
string text = fmt::format("[{0}{1}] {2:3}% {3}",
string(progressBlockCount, '#'), string(blockCount - progressBlockCount, '-'),
percent,
animation[animationIndex++ % animation.size()]);
updateText(text);
update();
std::this_thread::sleep_for(animationInterval);
}
if (clearOnDestruction) {
updateText("");
} else {
update();
}
}
void ProgressBar::update() {
const int blockCount = 20;
const string animation = "|/-\\";
int progressBlockCount = static_cast<int>(currentProgress * blockCount);
const double epsilon = 0.0001;
int percent = static_cast<int>(currentProgress * 100 + epsilon);
string text = fmt::format("[{0}{1}] {2:3}% {3}",
string(progressBlockCount, '#'), string(blockCount - progressBlockCount, '-'),
percent,
animation[animationIndex++ % animation.size()]);
updateText(text);
}
void ProgressBar::updateText(const string& text) {
// Get length of common portion
int commonPrefixLength = 0;

View File

@ -7,7 +7,8 @@
class ProgressBar : public ProgressSink {
public:
ProgressBar(std::ostream& stream = std::cerr);
explicit ProgressBar(double progress = 0.0);
ProgressBar(std::ostream& stream, double progress = 0.0);
~ProgressBar();
void reportProgress(double value) override;
@ -21,6 +22,7 @@ public:
private:
void updateLoop();
void update();
void updateText(const std::string& text);
std::future<void> updateLoopFuture;