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)