8 #ifndef Sawyer_ProgressBar_H
9 #define Sawyer_ProgressBar_H
11 #include <Sawyer/Message.h>
12 #include <Sawyer/Optional.h>
13 #include <Sawyer/Sawyer.h>
15 #include <boost/thread/locks.hpp>
16 #include <boost/thread/mutex.hpp>
26 #include <Sawyer/WarningsOff.h>
30 std::string leftEnd_, rightEnd_;
31 char barChar_, nonBarChar_;
34 static double minUpdateInterval_;
35 static double initialDelay_;
36 double lastUpdateTime_;
43 #include <Sawyer/WarningsRestore.h>
46 : value_(0.0), width_(15), showPercent_(
true), leftEnd_(
"["), rightEnd_(
"]"), barChar_(
'#'), nonBarChar_(
'-'),
47 lastUpdateTime_(0.0), stream_(stream), nUpdates_(0), shouldSpin_(
false) {
56 void update(
double ratio,
bool backward);
57 void configUpdate(
double ratio,
bool backward);
58 void valueUpdate(
double ratio,
bool backward);
59 std::string makeBar(
double ratio,
bool backward);
60 void updateTextMesg(
double ratio);
66 namespace ProgressBarSettings {
108 template<
typename T,
typename S=std::
string>
115 ValueType leftValue, curValue, rightValue;
116 Position(ValueType leftValue, ValueType curValue, ValueType rightValue)
117 : leftValue(leftValue), curValue(curValue), rightValue(rightValue) {}
118 bool operator==(
const Position &other)
const {
119 return curValue==other.curValue && leftValue==other.leftValue && rightValue==other.rightValue;
123 mutable boost::mutex mutex_;
134 : value_(0, 0, 0), bar_(stream), showValue_(true) {
135 bar_.shouldSpin_ =
true;
142 : value_(0, 0, rightValue), bar_(stream), showValue_(true) {
143 bar_.shouldSpin_ = isEmptyNS();
151 const std::string &name=
"progress")
152 : value_(leftValue, curValue, rightValue), bar_(stream), showValue_(true) {
153 bar_.shouldSpin_ = isEmptyNS();
160 boost::lock_guard<boost::mutex> lock(mutex_);
161 return value_.curValue;
164 boost::lock_guard<boost::mutex> lock(mutex_);
165 value_.curValue = curValue;
169 void value(ValueType curValue, ValueType rightValue) {
170 boost::lock_guard<boost::mutex> lock(mutex_);
171 value_.curValue = curValue;
172 value_.rightValue = rightValue;
173 bar_.shouldSpin_ = isEmptyNS();
176 void value(ValueType leftValue, ValueType curValue, ValueType rightValue) {
177 boost::lock_guard<boost::mutex> lock(mutex_);
178 value_ = Position(leftValue, curValue, rightValue);
179 bar_.shouldSpin_ = isEmptyNS();
191 boost::lock_guard<boost::mutex> lock(mutex_);
195 boost::lock_guard<boost::mutex> lock(mutex_);
199 boost::lock_guard<boost::mutex> lock(mutex_);
209 boost::lock_guard<boost::mutex> lock(mutex_);
215 boost::lock_guard<boost::mutex> lock(mutex_);
221 boost::lock_guard<boost::mutex> lock(mutex_);
222 return isBackwardNS();
227 std::pair<ValueType, ValueType>
domain()
const {
228 boost::lock_guard<boost::mutex> lock(mutex_);
229 return std::make_pair(value_.leftValue, value_.rightValue);
231 void domain(
const std::pair<ValueType, ValueType> &p) {
232 boost::lock_guard<boost::mutex> lock(mutex_);
233 value_.leftValue = p.first;
234 value_.rightValue = p.second;
237 void domain(ValueType leftValue, ValueType rightValue) {
238 boost::lock_guard<boost::mutex> lock(mutex_);
239 value_.leftValue = leftValue;
240 value_.rightValue = rightValue;
278 boost::lock_guard<boost::mutex> lock(mutex_);
282 boost::lock_guard<boost::mutex> lock(mutex_);
291 boost::lock_guard<boost::mutex> lock(mutex_);
295 boost::lock_guard<boost::mutex> lock(mutex_);
305 boost::lock_guard<boost::mutex> lock(mutex_);
306 return std::make_pair(bar_.barChar_, bar_.nonBarChar_);
309 boost::lock_guard<boost::mutex> lock(mutex_);
311 bar_.nonBarChar_ = nonBar;
318 std::pair<std::string, std::string>
endchars()
const {
319 boost::lock_guard<boost::mutex> lock(mutex_);
320 return std::make_pair(bar_.leftEnd_, bar_.rightEnd_);
322 void endchars(
const std::string <,
const std::string &rt) {
323 boost::lock_guard<boost::mutex> lock(mutex_);
333 boost::lock_guard<boost::mutex> lock(mutex_);
334 return bar_.showPercent_;
337 boost::lock_guard<boost::mutex> lock(mutex_);
338 bar_.showPercent_ = b;
346 boost::lock_guard<boost::mutex> lock(mutex_);
350 boost::lock_guard<boost::mutex> lock(mutex_);
357 bool isEmptyNS()
const {
358 return value_.leftValue == value_.rightValue;
361 double ratioNS()
const;
363 bool isBackwardNS()
const {
364 return value_.leftValue > value_.rightValue;
367 void valueUpdatedNS() {
369 std::ostringstream ss;
370 ss <<value_.curValue <<suffix_;
371 bar_.suffix_ = ss.str();
373 bar_.suffix_.clear();
375 bar_.valueUpdate(ratioNS(), isBackwardNS());
378 void configUpdatedNS() {
380 std::ostringstream ss;
381 ss <<value_.curValue <<suffix_;
382 bar_.suffix_ = ss.str();
384 bar_.suffix_.clear();
386 bar_.configUpdate(ratioNS(), isBackwardNS());
391 template <
typename T,
typename S>
392 double ProgressBar<T, S>::ratioNS()
const {
394 return value_.curValue <= value_.leftValue ? 0.0 : 1.0;
395 }
else if (isBackwardNS()) {
396 if (value_.curValue >= value_.leftValue) {
398 }
else if (value_.curValue <= value_.rightValue) {
401 return 1.0 * (value_.leftValue - value_.curValue) / (value_.leftValue - value_.rightValue);
404 if (value_.curValue <= value_.leftValue) {
406 }
else if (value_.curValue >= value_.rightValue) {
409 return 1.0 * (value_.curValue - value_.leftValue) / (value_.rightValue - value_.leftValue);
414 template <
typename T,
typename S>
416 boost::lock_guard<boost::mutex> lock(mutex_);
417 ValueType oldValue = value_.curValue;
418 value_.curValue += delta;
419 if (oldValue!=value_.curValue)
423 template <
typename T,
typename S>
425 boost::lock_guard<boost::mutex> lock(mutex_);
426 ValueType oldValue = value_.curValue;
427 value_.curValue -= delta;
428 if (oldValue!=value_.curValue)
Suffix suffix() const
Property: suffix.
void prefix(const std::string &s)
String to show before the beginning of the bar.
double minimumUpdateInterval()
Minimum time between updates.
ProgressBar & operator-=(ValueType delta)
Increment or decrement the progress bar.
ProgressBar & operator--()
Increment or decrement the progress bar.
std::pair< char, char > barchars() const
Characters to use for the bar.
ProgressBar(ValueType leftValue, ValueType curValue, ValueType rightValue, const Message::SProxy &stream, const std::string &name="progress")
Construct a progress bar with left and right limits.
void value(ValueType leftValue, ValueType curValue, ValueType rightValue)
Value for the progress bar.
std::pair< std::string, std::string > endchars() const
Characters to use for the left and right ends of the bar.
ProgressBar & operator++(int)
Increment or decrement the progress bar.
ProgressBar & operator+=(ValueType delta)
Increment or decrement the progress bar.
Name space for the entire library.
void domain(const std::pair< ValueType, ValueType > &p)
Possible values.
ProgressBar(ValueType rightValue, const Message::SProxy &stream, const std::string &name="progress")
Construct a progress bar incrementing from zero to some limit.
ProgressBar & operator--(int)
Increment or decrement the progress bar.
ProgressBar & suffix(const Suffix &suffix)
Property: suffix.
ProgressBar(const Message::SProxy &stream, const std::string &name="progress")
Construct spinning progress bar.
std::pair< ValueType, ValueType > domain() const
Possible values.
ValueType value() const
Value for the progress bar.
bool showPercent() const
Whether to show the percent indication.
ProgressBar & operator++()
Increment or decrement the progress bar.
void showPercent(bool b)
Whether to show the percent indication.
void value(ValueType curValue, ValueType rightValue)
Value for the progress bar.
const std::string & prefix() const
String to show before the beginning of the bar.
void decrement(ValueType delta=1)
Increment or decrement the progress bar.
void width(size_t width)
Width of progress bar in characters at 100%.
void increment(ValueType delta=1)
Increment or decrement the progress bar.
void barchars(char bar, char nonBar)
Characters to use for the bar.
Suffix suffix()
Property: suffix.
void endchars(const std::string <, const std::string &rt)
Characters to use for the left and right ends of the bar.
bool showValue() const
Whether to show the current value.
double ratio() const
Value of progress bar as a ratio of completeness clipped between 0 and 1.
bool isEmpty() const
True if the distance between the minimum and maximum is zero.
void domain(ValueType leftValue, ValueType rightValue)
Possible values.
void value(ValueType curValue)
Value for the progress bar.
bool isBackward() const
True if the minimum value is greater than the maximum value.
double initialDelay()
Delay before first message is emitted.
void showValue(bool b)
Whether to show the current value.
size_t width() const
Width of progress bar in characters at 100%.