/* Progress bar suitable for chains of workers */ #ifndef UTIL_STREAM_MULTI_PROGRESS_H #define UTIL_STREAM_MULTI_PROGRESS_H #include #include #include 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