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 #include "stdafx.h"
00027 #include "progressreporter.h"
00028 #include "timer.h"
00029 #include "parallel.h"
00030 #if defined(PBRT_IS_WINDOWS)
00031 #include <windows.h>
00032 #else
00033 #include <sys/ioctl.h>
00034 #include <unistd.h>
00035 #include <errno.h>
00036 #endif // !PBRT_IS_WINDOWS
00037
00038
00039 ProgressReporter::ProgressReporter(int tw, const string &title, int barLength)
00040 : totalWork(tw) {
00041 if (barLength <= 0)
00042 barLength = TerminalWidth() - 28;
00043 totalPlusses = max(2ul, barLength - title.size());
00044 mutex = Mutex::Create();
00045 plussesPrinted = 0;
00046 workDone = 0;
00047 timer = new Timer;
00048 timer->Start();
00049 outFile = stdout;
00050
00051 const int bufLen = title.size() + totalPlusses + 64;
00052 buf = new char[bufLen];
00053 snprintf(buf, bufLen, "\r%s: [", title.c_str());
00054 curSpace = buf + strlen(buf);
00055 char *s = curSpace;
00056 for (int i = 0; i < totalPlusses; ++i)
00057 *s++ = ' ';
00058 *s++ = ']';
00059 *s++ = ' ';
00060 *s++ = '\0';
00061 if (!PbrtOptions.quiet) {
00062 fputs(buf, outFile);
00063 fflush(outFile);
00064 }
00065 }
00066
00067
00068 ProgressReporter::~ProgressReporter() {
00069 delete[] buf;
00070 delete timer;
00071 Mutex::Destroy(mutex);
00072 }
00073
00074
00075 void ProgressReporter::Update(int num) {
00076 if (num == 0 || PbrtOptions.quiet) return;
00077 MutexLock lock(*mutex);
00078 workDone += num;
00079 float percentDone = float(workDone) / float(totalWork);
00080 int plussesNeeded = Round2Int(totalPlusses * percentDone);
00081 if (plussesNeeded > totalPlusses) plussesNeeded = totalPlusses;
00082 while (plussesPrinted < plussesNeeded) {
00083 *curSpace++ = '+';
00084 ++plussesPrinted;
00085 }
00086 fputs(buf, outFile);
00087
00088 float seconds = (float)timer->Time();
00089 float estRemaining = seconds / percentDone - seconds;
00090 if (percentDone == 1.f)
00091 fprintf(outFile, " (%.1fs) ", seconds);
00092 else
00093 fprintf(outFile, " (%.1fs|%.1fs) ", seconds, max(0.f, estRemaining));
00094 fflush(outFile);
00095 }
00096
00097
00098 void ProgressReporter::Done() {
00099 if (PbrtOptions.quiet) return;
00100 MutexLock lock(*mutex);
00101 while (plussesPrinted++ < totalPlusses)
00102 *curSpace++ = '+';
00103 fputs(buf, outFile);
00104 float seconds = (float)timer->Time();
00105 fprintf(outFile, " (%.1fs) \n", seconds);
00106 fflush(outFile);
00107 }
00108
00109
00110 int TerminalWidth() {
00111 #if defined(PBRT_IS_WINDOWS)
00112 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
00113 if (h == INVALID_HANDLE_VALUE || h == NULL) {
00114 fprintf(stderr, "GetStdHandle() call failed");
00115 return 80;
00116 }
00117 CONSOLE_SCREEN_BUFFER_INFO bufferInfo = { 0 };
00118 GetConsoleScreenBufferInfo(h, &bufferInfo);
00119 return bufferInfo.dwSize.X;
00120 #else
00121 struct winsize w;
00122 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) < 0) {
00123 fprintf(stderr, "Error in ioctl() in TerminalWidth(): %d", errno);
00124 return 80;
00125 }
00126 return w.ws_col;
00127 #endif // PBRT_IS_WINDOWS
00128 }
00129
00130
00131