1 /* Progress bar suitable for chains of workers */ 2 #ifndef UTIL_STREAM_MULTI_PROGRESS_H 3 #define UTIL_STREAM_MULTI_PROGRESS_H 4 5 #include <boost/thread/mutex.hpp> 6 7 #include <cstddef> 8 #include <stdint.h> 9 10 namespace util { namespace stream { 11 12 class WorkerProgress; 13 14 class MultiProgress { 15 public: 16 static const unsigned char kWidth = 100; 17 18 MultiProgress(); 19 20 ~MultiProgress(); 21 22 // Turns on showing (requires SetTarget too). 23 void Activate(); 24 25 void SetTarget(uint64_t complete); 26 27 WorkerProgress Add(); 28 29 void Finished(); 30 31 private: 32 friend class WorkerProgress; 33 void Milestone(WorkerProgress &worker); 34 35 bool active_; 36 37 uint64_t complete_; 38 39 boost::mutex mutex_; 40 41 // \0 at the end. 42 char display_[kWidth + 1]; 43 44 std::size_t character_handout_; 45 46 MultiProgress(const MultiProgress &); 47 MultiProgress &operator=(const MultiProgress &); 48 }; 49 50 class WorkerProgress { 51 public: 52 // Default contrutor must be initialized with operator= later. WorkerProgress()53 WorkerProgress() : parent_(NULL) {} 54 55 // Not threadsafe for the same worker by default. operator ++()56 WorkerProgress &operator++() { 57 if (++current_ >= next_) { 58 parent_->Milestone(*this); 59 } 60 return *this; 61 } 62 operator +=(uint64_t amount)63 WorkerProgress &operator+=(uint64_t amount) { 64 current_ += amount; 65 if (current_ >= next_) { 66 parent_->Milestone(*this); 67 } 68 return *this; 69 } 70 71 private: 72 friend class MultiProgress; WorkerProgress(uint64_t next,MultiProgress & parent,char character)73 WorkerProgress(uint64_t next, MultiProgress &parent, char character) 74 : current_(0), next_(next), parent_(&parent), stone_(0), character_(character) {} 75 76 uint64_t current_, next_; 77 78 MultiProgress *parent_; 79 80 // Previous milestone reached. 81 unsigned char stone_; 82 83 // Character to display in bar. 84 char character_; 85 }; 86 87 }} // namespaces 88 89 #endif // UTIL_STREAM_MULTI_PROGRESS_H 90