From 72279745be1a73a98ca5e505ad918806ed9f9e65 Mon Sep 17 00:00:00 2001 From: GQPHD Date: Fri, 22 Jan 2021 16:03:01 +0900 Subject: [PATCH 1/7] added testcase when windows --- example/src/example.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/example/src/example.cpp b/example/src/example.cpp index 225ca55..2faf9a3 100644 --- a/example/src/example.cpp +++ b/example/src/example.cpp @@ -1,5 +1,11 @@ #include -#include + +#ifdef _WIN32 +#include +#else +//#include +#endif + #include "progresscpp/ProgressBar.hpp" /* Example usage of ProgressBar */ @@ -16,7 +22,11 @@ int main() { for (int i = 0; i < total; i++) { ++progressBar; // record the tick +#ifdef _WIN32 + Sleep(2); +#else usleep(200); // simulate work +#endif // display the bar only at certain steps if (i % 10 == 0) From ef47115bd1e73ce78ff5d0c44b432cc6b51434db Mon Sep 17 00:00:00 2001 From: GQPHD Date: Fri, 22 Jan 2021 16:03:23 +0900 Subject: [PATCH 2/7] made progressbar with throttling --- include/progresscpp/ProgressBar.hpp | 80 +++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/include/progresscpp/ProgressBar.hpp b/include/progresscpp/ProgressBar.hpp index e4c4cf3..6ceb94d 100644 --- a/include/progresscpp/ProgressBar.hpp +++ b/include/progresscpp/ProgressBar.hpp @@ -1,7 +1,13 @@ #pragma once +/* + * from progress-cpp by prakhar1989 (@ref https://github.com/prakhar1989/progress-cpp) + * added throttling by sikbrad @ref https://github.com/sikbrad/progress-cpp-throttled.git + */ + #include #include +#include namespace progresscpp { class ProgressBar { @@ -9,39 +15,83 @@ class ProgressBar { unsigned int ticks = 0; const unsigned int total_ticks; - const unsigned int bar_width; + const unsigned int bar_width = 70; const char complete_char = '='; const char incomplete_char = ' '; const std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); +private: + int prev_progress_percent = 0; + int throttle_progress = 5; + int throttle_counter = 0; + public: + ProgressBar(unsigned int total, unsigned int width, char complete, char incomplete, int throttle) : + total_ticks{total}, bar_width{width}, complete_char{complete}, incomplete_char{incomplete}, throttle_progress{throttle} {} + ProgressBar(unsigned int total, unsigned int width, char complete, char incomplete) : total_ticks{total}, bar_width{width}, complete_char{complete}, incomplete_char{incomplete} {} ProgressBar(unsigned int total, unsigned int width) : total_ticks{total}, bar_width{width} {} + ProgressBar(unsigned int total) : total_ticks{total} {} + unsigned int operator++() { return ++ticks; } + + void UnsetThrottle(){ + throttle_progress = 0; + } - void display() const { - float progress = (float) ticks / total_ticks; - int pos = (int) (bar_width * progress); + void _display() const { + } - std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); - auto time_elapsed = std::chrono::duration_cast(now - start_time).count(); + void display() { + float progress = (float) (ticks+1) / total_ticks; + int curr_progress_percent = ceil(100 * progress); + bool is_print = false; - std::cout << "["; + //dont limit if set as zero + if(throttle_progress == 0){ + is_print = true; + } + //if limit is set, + else if(prev_progress_percent > 0){ - for (int i = 0; i < bar_width; ++i) { - if (i < pos) std::cout << complete_char; - else if (i == pos) std::cout << ">"; - else std::cout << incomplete_char; + //detect percentage change + if(prev_progress_percent < curr_progress_percent){ + throttle_counter++; + } + + //when throttle exceeds, then print and reset the counter. + if(throttle_counter >= throttle_progress){ + is_print = true; + throttle_counter = 0; + } } - std::cout << "] " << int(progress * 100.0) << "% " - << float(time_elapsed) / 1000.0 << "s\r"; - std::cout.flush(); + + if(is_print){ + int pos = (int) (bar_width * progress); + + std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); + auto time_elapsed = std::chrono::duration_cast(now - start_time).count(); + + std::cout << "["; + + for (int i = 0; i < bar_width; ++i) { + if (i < pos) std::cout << complete_char; + else if (i == pos) std::cout << ">"; + else std::cout << incomplete_char; + } + std::cout << "] " << int(progress * 100.0) << "% " + << float(time_elapsed) / 1000.0 << "s\r"; + std::cout.flush(); + } + + //save status + prev_progress_percent = curr_progress_percent; } - void done() const { + void done() { display(); std::cout << std::endl; } From 13884f36ef6fae8f884052e5f26b76616047af63 Mon Sep 17 00:00:00 2001 From: GQPHD Date: Fri, 22 Jan 2021 16:43:21 +0900 Subject: [PATCH 3/7] 1. spinner added 2.duplicated print error fixed --- example/src/example.cpp | 4 +- include/progresscpp/ProgressBar.hpp | 68 ++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/example/src/example.cpp b/example/src/example.cpp index 2faf9a3..52ac6eb 100644 --- a/example/src/example.cpp +++ b/example/src/example.cpp @@ -23,9 +23,9 @@ int main() { ++progressBar; // record the tick #ifdef _WIN32 - Sleep(2); + Sleep(1); #else - usleep(200); // simulate work + usleep(100); // simulate work #endif // display the bar only at certain steps diff --git a/include/progresscpp/ProgressBar.hpp b/include/progresscpp/ProgressBar.hpp index 6ceb94d..7bac67b 100644 --- a/include/progresscpp/ProgressBar.hpp +++ b/include/progresscpp/ProgressBar.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace progresscpp { class ProgressBar { @@ -20,14 +21,19 @@ class ProgressBar { const char incomplete_char = ' '; const std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); +public: + int throttle_progress = 5; + bool is_eta_enabled = true; + bool is_spinner_enabled = true; + private: int prev_progress_percent = 0; - int throttle_progress = 5; int throttle_counter = 0; + int count_display = 0; public: - ProgressBar(unsigned int total, unsigned int width, char complete, char incomplete, int throttle) : - total_ticks{total}, bar_width{width}, complete_char{complete}, incomplete_char{incomplete}, throttle_progress{throttle} {} + ProgressBar(unsigned int total, unsigned int width, char complete, char incomplete, int throttle, bool is_eta) : + total_ticks{total}, bar_width{width}, complete_char{complete}, incomplete_char{incomplete}, throttle_progress{throttle}, is_eta_enabled{is_eta} {} ProgressBar(unsigned int total, unsigned int width, char complete, char incomplete) : total_ticks{total}, bar_width{width}, complete_char{complete}, incomplete_char{incomplete} {} @@ -37,10 +43,6 @@ class ProgressBar { ProgressBar(unsigned int total) : total_ticks{total} {} unsigned int operator++() { return ++ticks; } - - void UnsetThrottle(){ - throttle_progress = 0; - } void _display() const { } @@ -56,16 +58,15 @@ class ProgressBar { } //if limit is set, else if(prev_progress_percent > 0){ - //detect percentage change if(prev_progress_percent < curr_progress_percent){ - throttle_counter++; - } + ++throttle_counter; - //when throttle exceeds, then print and reset the counter. - if(throttle_counter >= throttle_progress){ - is_print = true; - throttle_counter = 0; + //when throttle exceeds, then print and reset the counter. + if(throttle_counter >= throttle_progress){ + is_print = true; + throttle_counter = 0; + } } } @@ -82,9 +83,44 @@ class ProgressBar { else if (i == pos) std::cout << ">"; else std::cout << incomplete_char; } - std::cout << "] " << int(progress * 100.0) << "% " - << float(time_elapsed) / 1000.0 << "s\r"; + std::cout << "] "; + + std::cout << "[" << int(progress * 100.0) << "% "; + std::cout << std::fixed << std::setprecision(2) << float(time_elapsed) / 1000.0 << "s"; + std::cout << "]"; + + if(is_eta_enabled){ + float expected = float(time_elapsed) / progress; + float eta = abs(expected - time_elapsed); + std::cout << " eta " << std::fixed << std::setprecision(2) << float(eta) / 1000.0 << "s "; + } + + if(is_spinner_enabled){ + //followed character spinner style of etaprogress(python) + //@ref https://pypi.org/project/etaprogress/ + const int total_pinchar = 4; + int idx_spinchar = count_display % total_pinchar; + char spinchar = ' '; + switch(idx_spinchar){ + case 0: + spinchar = '-'; break; + case 1: + spinchar = '\\'; break; + case 2: + spinchar = '|'; break; + case 3: + spinchar = '/'; break; + default: + break; + } + std::cout << " " << spinchar; + } + + + std::cout << " \r"; std::cout.flush(); + + count_display++; } //save status From 227230a4536a00498eee863021c1d67711290e48 Mon Sep 17 00:00:00 2001 From: GQPHD Date: Fri, 22 Jan 2021 17:00:34 +0900 Subject: [PATCH 4/7] edited readme --- README.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f47473b..235ae29 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,36 @@ -Progress-CPP +Progress-CPP-Throttled-HeaderOnly === + + +### What's better, TLDR + +By printing progress bar only when it is needed, performance got better. + +Added ETA(Estimated time of arrival), and Spinner. + +It is just one header file, like original. + + + +## What's new, and why. + +### Throttling added + +Displaying progress is important, but when printing too much console from your program, your program slows down. That's what exactly happened to me when using original library. So I added throttling feature, to print the progress bar only when it is needed. When `throttle_progress` is set to 1(default), then program will display the progress bar only when percentage changes. If we set `throttle_progress` larger than 1, then it will skip printing progress bar until added progress percentage gets larger than `throttle_progress` . + +### ETA added + +Time estimation is added. It can be enabled/disabled by variable `is_eta_enabled` + +### Spinner added + +Spinner is added. It can be enabled/disabled by variable `is_spinner_enabled` + + + +## Original README of Progress-CPP + A flexible ASCII progress bar for your console based C++ projects. ### Usage From 6e5e893e2d65d50a947b22c4922c8ff6d8ad4523 Mon Sep 17 00:00:00 2001 From: GQPHD Date: Fri, 22 Jan 2021 17:01:42 +0900 Subject: [PATCH 5/7] readme typo --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 235ae29..bc4eaa2 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ Progress-CPP-Throttled-HeaderOnly === - - -### What's better, TLDR +## What's new, TLDR By printing progress bar only when it is needed, performance got better. @@ -13,7 +11,7 @@ It is just one header file, like original. -## What's new, and why. +## What's new and why, in detail ### Throttling added From 0272ebc0bcb3d193a8a8b4591186cc8d32241c60 Mon Sep 17 00:00:00 2001 From: GQPHD Date: Fri, 22 Jan 2021 17:36:36 +0900 Subject: [PATCH 6/7] added is_displayed flag to propagate the display status to outside of progbar --- include/progresscpp/ProgressBar.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/progresscpp/ProgressBar.hpp b/include/progresscpp/ProgressBar.hpp index 7bac67b..022db4a 100644 --- a/include/progresscpp/ProgressBar.hpp +++ b/include/progresscpp/ProgressBar.hpp @@ -31,6 +31,9 @@ class ProgressBar { int throttle_counter = 0; int count_display = 0; +public: + bool is_displayed = false; + public: ProgressBar(unsigned int total, unsigned int width, char complete, char incomplete, int throttle, bool is_eta) : total_ticks{total}, bar_width{width}, complete_char{complete}, incomplete_char{incomplete}, throttle_progress{throttle}, is_eta_enabled{is_eta} {} @@ -47,7 +50,7 @@ class ProgressBar { void _display() const { } - void display() { + bool display() { float progress = (float) (ticks+1) / total_ticks; int curr_progress_percent = ceil(100 * progress); bool is_print = false; @@ -120,11 +123,16 @@ class ProgressBar { std::cout << " \r"; std::cout.flush(); + is_displayed = true; count_display++; + }else{ + is_displayed = false; } //save status prev_progress_percent = curr_progress_percent; + + return is_displayed; } void done() { From 4c92158d81ff57e3adc024961e04d72ae06d985d Mon Sep 17 00:00:00 2001 From: GQPHD Date: Tue, 26 Jan 2021 11:32:25 +0900 Subject: [PATCH 7/7] example function was wrong --- example/src/example.cpp | 3 +-- include/progresscpp/ProgressBar.hpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/example/src/example.cpp b/example/src/example.cpp index 52ac6eb..5ab4b08 100644 --- a/example/src/example.cpp +++ b/example/src/example.cpp @@ -29,8 +29,7 @@ int main() { #endif // display the bar only at certain steps - if (i % 10 == 0) - progressBar.display(); + progressBar.display(); } // tell the bar to finish diff --git a/include/progresscpp/ProgressBar.hpp b/include/progresscpp/ProgressBar.hpp index 022db4a..27aa64f 100644 --- a/include/progresscpp/ProgressBar.hpp +++ b/include/progresscpp/ProgressBar.hpp @@ -67,8 +67,8 @@ class ProgressBar { //when throttle exceeds, then print and reset the counter. if(throttle_counter >= throttle_progress){ - is_print = true; throttle_counter = 0; + is_print = true; } } }