blob: 82e698a59c32cdcd839293332781eaf0e2232d17 [file] [log] [blame]
/* Progress bar suitable for chains of workers */
#ifndef UTIL_STREAM_MULTI_PROGRESS_H
#define UTIL_STREAM_MULTI_PROGRESS_H
#include <boost/thread/mutex.hpp>
#include <cstddef>
#include <stdint.h>
namespace util { namespace stream {
class WorkerProgress;
class MultiProgress {
public:
static const unsigned char kWidth = 100;
MultiProgress();
~MultiProgress();
// Turns on showing (requires SetTarget too).
void Activate();
void SetTarget(uint64_t complete);
WorkerProgress Add();
void Finished();
private:
friend class WorkerProgress;
void Milestone(WorkerProgress &worker);
bool active_;
uint64_t complete_;
boost::mutex mutex_;
// \0 at the end.
char display_[kWidth + 1];
std::size_t character_handout_;
MultiProgress(const MultiProgress &);
MultiProgress &operator=(const MultiProgress &);
};
class WorkerProgress {
public:
// Default contrutor must be initialized with operator= later.
WorkerProgress() : parent_(NULL) {}
// Not threadsafe for the same worker by default.
WorkerProgress &operator++() {
if (++current_ >= next_) {
parent_->Milestone(*this);
}
return *this;
}
WorkerProgress &operator+=(uint64_t amount) {
current_ += amount;
if (current_ >= next_) {
parent_->Milestone(*this);
}
return *this;
}
private:
friend class MultiProgress;
WorkerProgress(uint64_t next, MultiProgress &parent, char character)
: current_(0), next_(next), parent_(&parent), stone_(0), character_(character) {}
uint64_t current_, next_;
MultiProgress *parent_;
// Previous milestone reached.
unsigned char stone_;
// Character to display in bar.
char character_;
};
}} // namespaces
#endif // UTIL_STREAM_MULTI_PROGRESS_H