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