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.