Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <swri_console_util/progress_bar.h>
00031
00032 #include <ctime>
00033 #include <sstream>
00034
00035 namespace swri_console_util
00036 {
00037 ProgressBar::ProgressBar() :
00038 paused_(false),
00039 percent_complete_(0),
00040 start_time_(ros::WallTime::now()),
00041 paused_time_(0)
00042 {
00043 SetupTerminal();
00044 }
00045
00046 ProgressBar::~ProgressBar()
00047 {
00048 RestoreTerminal();
00049 }
00050
00051 void ProgressBar::SetStartTime(const ros::WallTime& start_time)
00052 {
00053 start_time_ = start_time;
00054 }
00055
00056 void ProgressBar::SetProgress(double percent_complete)
00057 {
00058 percent_complete_ = percent_complete;
00059 }
00060
00061 void ProgressBar::PrintTime()
00062 {
00063 ros::WallTime current_time = ros::WallTime::now();
00064 ros::WallDuration elapsed = (current_time - start_time_) - paused_time_;
00065
00066 if (percent_complete_ > 0)
00067 {
00068 ros::WallDuration time_left =
00069 (elapsed * (1.0 / percent_complete_)) - elapsed;
00070
00071 if (paused_)
00072 {
00073 printf("\r [PAUSED] %.2f%% Complete, Elapsed: %s Estimated Remaining: %s \r",
00074 percent_complete_ * 100.0,
00075 GetTimeString(elapsed.toSec()).c_str(),
00076 GetTimeString(time_left.toSec()).c_str());
00077 }
00078 else
00079 {
00080 printf("\r [RUNNING] %.2f%% Complete, Elapsed: %s Estimated Remaining: %s \r",
00081 percent_complete_ * 100.0,
00082 GetTimeString(elapsed.toSec()).c_str(),
00083 GetTimeString(time_left.toSec()).c_str());
00084 }
00085 }
00086 else
00087 {
00088 if (paused_)
00089 {
00090 printf("\r [PAUSED] %.2f%% Complete, Elapsed: %s \r",
00091 percent_complete_ * 100.0,
00092 GetTimeString(elapsed.toSec()).c_str());
00093 }
00094 else
00095 {
00096 printf("\r [RUNNING] %.2f%% Complete, Elapsed: %s \r",
00097 percent_complete_ * 100.0,
00098 GetTimeString(elapsed.toSec()).c_str());
00099 }
00100 }
00101
00102 fflush(stdout);
00103 }
00104
00105 void ProgressBar::CheckForPause()
00106 {
00107 ros::WallTime start_pause = ros::WallTime::now();
00108 do
00109 {
00110 bool charsleftorpaused = true;
00111 while (charsleftorpaused && ros::ok())
00112 {
00113 switch (ReadCharFromStdin())
00114 {
00115 case ' ':
00116 paused_ = !paused_;
00117
00118 if (paused_)
00119 {
00120 PrintTime();
00121 }
00122 case EOF:
00123 charsleftorpaused = paused_;
00124 }
00125 }
00126 }
00127 while (paused_ && ros::ok());
00128
00129 paused_time_ += (ros::WallTime::now() - start_pause);
00130
00131 PrintTime();
00132 }
00133
00134 char ProgressBar::ReadCharFromStdin()
00135 {
00136 fd_set testfd = stdin_fdset_;
00137
00138 timeval tv;
00139 tv.tv_sec = 0;
00140 tv.tv_usec = 0;
00141
00142 if (select(maxfd_, &testfd, NULL, NULL, &tv) <= 0)
00143 {
00144 return EOF;
00145 }
00146
00147 return getc(stdin);
00148 }
00149
00150 void ProgressBar::SetupTerminal()
00151 {
00152 const int fd = fileno(stdin);
00153 termios flags;
00154 tcgetattr(fd, &orig_flags_);
00155 flags = orig_flags_;
00156 flags.c_lflag &= ~ICANON;
00157 flags.c_cc[VMIN] = 0;
00158
00159 flags.c_cc[VTIME] = 0;
00160 tcsetattr(fd, TCSANOW, &flags);
00161
00162 FD_ZERO(&stdin_fdset_);
00163 FD_SET(fd, &stdin_fdset_);
00164 maxfd_ = fd + 1;
00165 }
00166
00167 void ProgressBar::RestoreTerminal()
00168 {
00169 const int fd = fileno(stdin);
00170 tcsetattr(fd, TCSANOW, &orig_flags_);
00171 }
00172
00173 std::string ProgressBar::GetTimeString(double seconds)
00174 {
00175 int days = static_cast<int>(seconds / 86400.0);
00176 seconds -= days * 86400.0;
00177
00178 int hours = static_cast<int>(seconds / 3600.0);
00179 seconds -= hours * 3600.0;
00180
00181 int minutes = static_cast<int>(seconds / 60.0);
00182 seconds -= minutes * 60.0;
00183
00184 std::string time;
00185 std::string unit;
00186 if (days > 0)
00187 {
00188 time += IntToString(days, 2) + ":";
00189 unit = "d";
00190 }
00191
00192 if (hours > 0 || !time.empty())
00193 {
00194 if (time.empty())
00195 {
00196 unit = "h";
00197 }
00198
00199 time += IntToString(hours, 2) + ":";
00200 }
00201
00202 if (minutes > 0 || !time.empty())
00203 {
00204 if (time.empty())
00205 {
00206 unit = "m";
00207 }
00208
00209 time += IntToString(minutes, 2) + ":";
00210 }
00211
00212 if (time.empty())
00213 {
00214 unit = "s";
00215 }
00216
00217 time += IntToString(seconds, 2) + unit;
00218
00219 return time;
00220 }
00221
00222 std::string ProgressBar::IntToString(int64_t i, int width)
00223 {
00224 std::stringstream ss;
00225 std::string s;
00226 ss << std::setfill('0');
00227 ss << std::setw(width);
00228 ss << i;
00229 s = ss.str();
00230 return s;
00231 }
00232 }