LBIBCell
 All Classes Functions Variables Friends Pages
ProgressBar.cpp
1 /* Copyright (c) 2013 David Sichau <mail"at"sichau"dot"eu>
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18  * THE SOFTWARE.
19  *
20  */
21 #include <UtilLib/include/ProgressBar.hpp>
22 #include <UtilLib/include/TerminalColors.hpp>
23 #include <iomanip>
24 #include <vector>
25 
26 namespace UtilLib {
28  unsigned int expectedCount,
29  double updateInterval,
30  std::ostream& os)
31  : count_(0),
32  expectedCount_(expectedCount),
33  nextTicCount_(0),
34  updateCount_(0),
35  tic_(0),
36  outputStream_(os),
37  updateInterval_(updateInterval) {
38  outputStream_ << "progress: " << std::setw(4) << std::setprecision(3) <<
39  static_cast<float>(tic_) << "% estimated time remaining:" << std::setw(
40  6) << std::setprecision(3) << "inf sec\n"
41  << "0% 10 20 30 40 50 60 70 80 90 100%\n"
42  << "|----|----|----|----|----|----|----|----|----|----|"
43  << std::endl;
44  wholeTime_.start();
45 }
46 
47 unsigned int ProgressBar::operator+=(unsigned int increment) {
48  count_ += increment;
49  if (count_ >= nextTicCount_) {
50  displayPercentage();
51  displayTic();
52  } else if (count_ > updateCount_) {
53  displayPercentage();
54  }
55  return count_;
56 }
57 
58 unsigned int ProgressBar::operator++() {
59  return operator+=(1);
60 }
61 
62 unsigned int ProgressBar::operator++(int i) {
63  return operator+=(1);
64 }
65 
66 void ProgressBar::displayTic() {
67  unsigned int tics_needed =
68  static_cast<unsigned int>((static_cast<double>(count_) /
69  expectedCount_) * 50.0);
70  do {
71  outputStream_ << '*' << std::flush;
72  } while (++tic_ < tics_needed);
73 
74  nextTicCount_ = static_cast<unsigned int>((tic_ / 50.0) * expectedCount_);
75  // if the end is reached make sure that the output is correct
76  if (count_ == expectedCount_) {
77  outputStream_ << STORE_CURSOR << GO_LINE_UP << GO_LINE_UP << GO_LINE_UP
78  << GO_LINE_BEGIN << "progress: " << std::setw(4)
79  << std::setprecision(3) << static_cast<float>(100)
80  << "% estimated time remaining:" << std::setw(6)
81  << std::setprecision(3) << 0.0 << " sec" << DEL_END
82  << RESET_CURSOR;
83  if (tic_ < 51)
84  outputStream_ << '*';
85 
86  outputStream_ << "\noverall runtime: " << std::setw(9) << BOLDWHITE
87  << std::setprecision(6) << wholeTime_.stop() << " sec"
88  << RESET << std::endl;
89  }
90 }
91 
92 void ProgressBar::displayPercentage() {
93  const float percentage = static_cast<float>(count_) / (expectedCount_) *
94  100;
95  const float dt = wholeTime_.stop();
96  const float remainingTime = 100 * dt / percentage - dt;
97  updateCount_ = count_ + count_ / dt * updateInterval_;
98  /*
99  * I use the following terminal control sequences:
100  * \x1b[s stores the current cursor position
101  * \x1b[A goes one line up
102  * \r goes to the beginning of the line
103  * \x1b[K deletes form the cursor position to the end
104  * \x1b[u restores the cursor position
105  */
106  outputStream_ << STORE_CURSOR << GO_LINE_UP << GO_LINE_UP << GO_LINE_UP
107  << GO_LINE_BEGIN << "progress: " << std::setw(4)
108  << BOLDWHITE << std::setprecision(3) << percentage << "% "
109  << RESET << "estimated time remaining: " << std::setw(6)
110  << BOLDWHITE << std::setprecision(3) << remainingTime << RESET
111  << " sec" << DEL_END << RESET_CURSOR << std::flush;
112 }
113 } /* end namespace */
unsigned int operator+=(unsigned int increment)
Definition: ProgressBar.cpp:47
void start()
starts the timer
Definition: Timer.hpp:37
ProgressBar(unsigned int expected_count, double updateInterval=30, std::ostream &os=std::cout)
Definition: ProgressBar.cpp:27
unsigned int operator++()
Prefix operator.
Definition: ProgressBar.cpp:58
double stop()
stops the timer and returns the time in sec
Definition: Timer.hpp:46