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);
66namespace ProgressBarSettings {
108template<
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());
391template <
typename T,
typename S>
392double 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);
414template <
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)
423template <
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)
Holds a value or nothing.
size_t width() const
Width of progress bar in characters at 100%.
ProgressBar & operator--(int)
Increment or decrement the progress bar.
void domain(ValueType leftValue, ValueType rightValue)
Possible values.
ProgressBar & operator+=(ValueType delta)
Increment or decrement the progress bar.
void showPercent(bool b)
Whether to show the percent indication.
void value(ValueType curValue)
Value for the progress bar.
std::pair< char, char > barchars() const
Characters to use for the bar.
void domain(const std::pair< ValueType, ValueType > &p)
Possible values.
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.
bool isBackward() const
True if the minimum value is greater than the maximum value.
const std::string & prefix() const
String to show before the beginning of the bar.
void barchars(char bar, char nonBar)
Characters to use for the bar.
Suffix suffix() const
Property: suffix.
void decrement(ValueType delta=1)
Increment or decrement the progress bar.
bool showPercent() const
Whether to show the percent indication.
Suffix suffix()
Property: suffix.
ValueType value() const
Value for the progress bar.
void showValue(bool b)
Whether to show the current value.
bool isEmpty() const
True if the distance between the minimum and maximum is zero.
ProgressBar & operator--()
Increment or decrement the progress bar.
void endchars(const std::string <, const std::string &rt)
Characters to use for the left and right ends of the bar.
void prefix(const std::string &s)
String to show before the beginning of the bar.
std::pair< std::string, std::string > endchars() const
Characters to use for the left and right ends of the bar.
void value(ValueType leftValue, ValueType curValue, ValueType rightValue)
Value for the progress bar.
ProgressBar(ValueType rightValue, const Message::SProxy &stream, const std::string &name="progress")
Construct a progress bar incrementing from zero to some limit.
ProgressBar & suffix(const Suffix &suffix)
Property: suffix.
void increment(ValueType delta=1)
Increment or decrement the progress bar.
double ratio() const
Value of progress bar as a ratio of completeness clipped between 0 and 1.
ProgressBar & operator++(int)
Increment or decrement the progress bar.
ProgressBar & operator-=(ValueType delta)
Increment or decrement the progress bar.
void value(ValueType curValue, ValueType rightValue)
Value for the progress bar.
bool showValue() const
Whether to show the current value.
ProgressBar & operator++()
Increment or decrement the progress bar.
std::pair< ValueType, ValueType > domain() const
Possible values.
void width(size_t width)
Width of progress bar in characters at 100%.
ProgressBar(const Message::SProxy &stream, const std::string &name="progress")
Construct spinning progress bar.
double minimumUpdateInterval()
Minimum time between updates.
double initialDelay()
Delay before first message is emitted.