# | Line 39 | Line 39 | |
---|---|---|
39 | * [4] Vardeman, Stocker & Gezelter, in progress (2010). | |
40 | */ | |
41 | ||
42 | < | #include <string> |
43 | < | #include <sstream> |
42 | > | #include <iostream> |
43 | #include <sys/ioctl.h> | |
44 | #ifdef IS_MPI | |
45 | #include <mpi.h> | |
46 | < | #endif //is_mpi |
46 | > | #endif |
47 | #include "utils/ProgressBar.hpp" | |
48 | ||
49 | + | using namespace std; |
50 | + | |
51 | namespace OpenMD { | |
52 | ||
53 | const char * progressSpinner_ = "|/-\\"; | |
# | Line 58 | Line 59 | namespace OpenMD { | |
59 | #ifdef IS_MPI | |
60 | if (MPI::COMM_WORLD.Get_rank() == 0) { | |
61 | #endif | |
62 | < | printf("\n"); |
63 | < | fflush(stdout); |
62 | > | cout << endl; |
63 | > | cout.flush(); |
64 | #ifdef IS_MPI | |
65 | } | |
66 | #endif | |
# | Line 70 | Line 71 | namespace OpenMD { | |
71 | } | |
72 | ||
73 | void ProgressBar::update() { | |
74 | < | int width = 80; |
74 | > | |
75 | > | int width; |
76 | > | |
77 | #ifdef IS_MPI | |
78 | if (MPI::COMM_WORLD.Get_rank() == 0) { | |
79 | #endif | |
77 | – | #ifndef IS_MPI |
78 | – | // get the window width: |
79 | – | struct winsize w; |
80 | – | ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); |
81 | – | width = w.ws_col; |
82 | – | #endif |
83 | – | |
84 | – | // We'll use: |
85 | – | // 31 characters for the completion estimate, |
86 | – | // 6 for the % complete, |
87 | – | // 2 characters for the open and closing brackets. |
88 | – | |
89 | – | int avail = width - 31 - 6 - 2; |
90 | – | |
91 | – | ++iteration_; |
92 | – | |
93 | – | if (maximum_ > 0.0) { |
94 | – | // we know the maximum, so |
95 | – | // draw a progress bar |
80 | ||
81 | < | RealType percent = value_ * 100.0 / maximum_; |
82 | < | int hashes = int(percent * avail / 100.0); |
83 | < | std::string progressbar; |
84 | < | progressbar.assign(hashes, '#'); |
81 | > | // only do the progress bar if we are actually running in a tty: |
82 | > | if (isatty(fileno(stdout))) { |
83 | > | |
84 | > | // get the window width: |
85 | > | struct winsize w; |
86 | > | ioctl(fileno(stdout), TIOCGWINSZ, &w); |
87 | > | width = w.ws_col; |
88 | ||
89 | < | // add the spinner to the end of the progress bar: |
90 | < | progressbar += progressSpinner_[iteration_ & 3]; |
89 | > | // handle the case when the width is returned as a nonsensical value. |
90 | > | if (width <= 0) width = 80; |
91 | ||
92 | < | // compute the best estimate of the ending time: |
93 | < | time_t current_ = time(NULL); |
94 | < | time_t end_ = start_ + (current_ - start_) * (100.0/percent); |
95 | < | struct tm * ender = localtime(&end_); |
96 | < | char buffer[24]; |
97 | < | strftime(buffer, 24, "%a %b %d @ %I:%M %p", ender); |
92 | > | // We'll use: |
93 | > | // 31 characters for the completion estimate, |
94 | > | // 6 for the % complete, |
95 | > | // 2 characters for the open and closing brackets. |
96 | > | |
97 | > | int avail = width - 31 - 6 - 2; |
98 | ||
99 | < | std::stringstream fmt; |
113 | < | fmt << "\r%3d%% [%-" << avail << "s] Estimate: %s"; |
114 | < | std::string st = fmt.str(); |
99 | > | ++iteration_; |
100 | ||
101 | < | printf(st.c_str(), int(percent), |
117 | < | progressbar.c_str(), |
118 | < | buffer); |
101 | > | if (maximum_ > 0.0) { |
102 | ||
103 | < | } else { |
104 | < | // we don't know the maximum, so we can't draw a progress bar |
105 | < | int center = (iteration_ % 48) + 1; // 50 spaces, minus 2 |
106 | < | std::string before; |
107 | < | std::string after; |
108 | < | before.assign(std::max(center - 2, 0), ' '); |
109 | < | after.assign(std::min(center + 2, 50), ' '); |
110 | < | |
111 | < | printf("\r[%s###%s] ", |
112 | < | before.c_str(), after.c_str()); |
113 | < | } |
114 | < | fflush(stdout); |
103 | > | // we know the maximum, so draw a progress bar |
104 | > | |
105 | > | RealType percent = value_ * 100.0 / maximum_; |
106 | > | int hashes = int(percent * avail / 100.0); |
107 | > | |
108 | > | // compute the best estimate of the ending time: |
109 | > | time_t current_ = time(NULL); |
110 | > | time_t end_ = start_ + (current_ - start_) * (100.0/percent); |
111 | > | struct tm * ender = localtime(&end_); |
112 | > | char buffer[22]; |
113 | > | strftime(buffer, 22, "%a %b %d @ %I:%M %p", ender); |
114 | > | |
115 | > | cout << '\r'; |
116 | > | cout.width(3); |
117 | > | cout << right << int(percent); |
118 | > | cout.width(3); |
119 | > | cout << "% ["; |
120 | > | cout.fill('#'); |
121 | > | if (hashes+1 < avail) { |
122 | > | cout.width(hashes+1); |
123 | > | cout << progressSpinner_[iteration_ & 3]; |
124 | > | } else { |
125 | > | cout.width(avail); |
126 | > | cout << '#'; |
127 | > | } |
128 | > | cout.fill(' '); |
129 | > | if (avail - hashes - 1 > 0) { |
130 | > | cout.width(avail - hashes - 1); |
131 | > | cout << ' '; |
132 | > | } |
133 | > | cout.width(11); |
134 | > | cout << "] Estimate:"; |
135 | > | cout.width(22); |
136 | > | cout << buffer; |
137 | > | |
138 | > | } |
139 | > | cout.flush(); |
140 | > | } |
141 | #ifdef IS_MPI | |
142 | } | |
143 | #endif |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |