00001 #ifndef PROGRESS_HH
00002 #define PROGRESS_HH
00003
00004 #include <math.h>
00005 #include <string>
00006 #include <stdio.h>
00007 #include "Timer.hh"
00008
00010 class Progress {
00011 public:
00012
00019 Progress(long skip = 0, long max_count = 0)
00020 {
00021 m_file = stderr;
00022 m_count = 0;
00023 m_skip_count = 0;
00024 m_skip = skip;
00025 m_max_count = max_count;
00026 m_timer.start();
00027 }
00028
00030 void set_file(FILE *file)
00031 {
00032 m_file = file;
00033 }
00034
00036 void set_report_string(std::string str)
00037 {
00038 m_report_str = str;
00039 }
00040
00042 void reset_timer()
00043 {
00044 m_timer.stop();
00045 m_timer.reset();
00046 m_timer.start();
00047 }
00048
00052 void step(long steps = 1)
00053 {
00054 m_count += steps;
00055 m_skip_count -= steps;
00056 if (m_skip_count <= 0) {
00057 show_report();
00058 m_skip_count = m_skip + 1;
00059 }
00060 }
00061
00063 void show_report()
00064 {
00065 if (m_max_count <= 0)
00066 fprintf(m_file, "\r%s %ld ", m_report_str.c_str(), m_count);
00067 else {
00068 m_timer.snapshot();
00069 float real_sec = m_timer.real_sec();
00070 float fraction = (float)m_count / m_max_count;
00071
00072 if (real_sec < 1)
00073 real_sec = 1;
00074
00075 int secs_left = lrintf(real_sec / fraction - real_sec);
00076 int mins_left = secs_left / 60;
00077 secs_left = secs_left % 60;
00078 int hours_left = mins_left / 60;
00079 mins_left = mins_left % 60;
00080
00081 int secs_elapsed = (int)real_sec;
00082 int mins_elapsed = secs_elapsed / 60;
00083 secs_elapsed = secs_elapsed % 60;
00084 int hours_elapsed = mins_elapsed / 60;
00085 mins_elapsed = mins_elapsed % 60;
00086
00087 fprintf(m_file,
00088 "\r%s %ld / %ld (%.2f %%) %02d:%02d:%02d ETA %02d:%02d:%02d ",
00089 m_report_str.c_str(), m_count, m_max_count,
00090 100.0 * fraction,
00091 hours_elapsed, mins_elapsed, (int)secs_elapsed,
00092 hours_left, mins_left, secs_left);
00093 }
00094 }
00095
00097 void finish()
00098 {
00099 show_report();
00100 fputc('\n', m_file);
00101 }
00102
00103 private:
00104
00106 FILE *m_file;
00107
00109 std::string m_report_str;
00110
00112 long m_count;
00113
00115 long m_skip_count;
00116
00119 long m_skip;
00120
00123 long m_max_count;
00124
00127 Timer m_timer;
00128 };
00129
00130 #endif