00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sys/time.h>
00022 #include <unistd.h>
00023
00024
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027
00028
00029 #include <iostream>
00030
00031 #include <archon/util/time.H>
00032 #include <archon/util/progress_meter.H>
00033
00034
00035 namespace Archon
00036 {
00037 namespace Utilities
00038 {
00039 ProgressBase::ProgressBase(unsigned long totalWorkUnits):
00040 totalWorkUnits(totalWorkUnits), completedWorkUnits(0),
00041 updateTime(getTimeInMilliSeconds()),
00042 skippedWorkUnits(0), workUnitsPerUpdate(1) {}
00043
00044 unsigned long ProgressBase::getTimeInMilliSeconds()
00045 {
00046 return Time::now().getMilliSeconds();
00047 }
00048
00049 void ProgressBase::update()
00050 {
00051 if(completedWorkUnits == totalWorkUnits) return;
00052
00053 skippedWorkUnits = 0;
00054 completedWorkUnits += workUnitsPerUpdate;
00055
00056
00057 const unsigned long now = getTimeInMilliSeconds();
00058 unsigned long timeSinceLastUpdate = now - updateTime;
00059 if(timeSinceLastUpdate == 0) timeSinceLastUpdate = 1;
00060 workUnitsPerUpdate = int(double(workUnitsPerUpdate) / timeSinceLastUpdate * millisBetweenUpdates);
00061 if(workUnitsPerUpdate == 0) workUnitsPerUpdate = 1;
00062 if(workUnitsPerUpdate > totalWorkUnits - completedWorkUnits) workUnitsPerUpdate = totalWorkUnits - completedWorkUnits;
00063
00064 updateTime = now;
00065
00066 display();
00067 }
00068
00069 void ProgressBar::display()
00070 {
00071 const div_t d = div(static_cast<int>(width * 10 * static_cast<float>(completedWorkUnits)/totalWorkUnits), 10);
00072
00073 std::cout << leadText << "|";
00074 int i=0;
00075 while(i<d.quot) ++i, std::cout << "#";
00076 if(extraResolution && i<width) ++i, std::cout << static_cast<char>(d.rem + '0');
00077 while(i<width) ++i, std::cout << "-";
00078 std::cout << "|";
00079
00080 if(completedWorkUnits == totalWorkUnits) std::cout << "\n";
00081 else std::cout << std::flush << "\r";
00082 }
00083
00084 void ProgressStatus::display()
00085 {
00086 char buffer[64];
00087
00088 const float fraction = static_cast<float>(completedWorkUnits)/totalWorkUnits;
00089
00090 sprintf(buffer, "%.1f", fraction*100);
00091 std::cout << leadText << completedWorkUnits << "/" << totalWorkUnits << ", " << buffer << "%, ";
00092
00093 const unsigned long elapsedTime = updateTime - startTime;
00094 if(elapsedTime >= millisUntilFirstTotalTimeEstimate)
00095 {
00096 const unsigned long totalTime = static_cast<unsigned long>(elapsedTime/fraction);
00097
00098 int seconds, minutes, hours;
00099 div_t d;
00100
00101 seconds = (totalTime-elapsedTime)/1000;
00102 d = div(seconds, 60);
00103 seconds = d.rem;
00104 d = div(d.quot, 60);
00105 minutes = d.rem;
00106 hours = d.quot;
00107 sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds);
00108 std::cout << "time left: " << buffer << ", ";
00109
00110 seconds = totalTime/1000;
00111 d = div(seconds, 60);
00112 seconds = d.rem;
00113 d = div(d.quot, 60);
00114 minutes = d.rem;
00115 hours = d.quot;
00116 sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds);
00117 std::cout << "time total: " << buffer;
00118 }
00119 else std::cout << "time left: ??:??:??, time total: ??:??:??";
00120
00121 if(completedWorkUnits == totalWorkUnits) std::cout << "\n";
00122 else std::cout << std::flush << " \r";
00123 }
00124 }
00125 }