00001 #ifndef Util_ProgressPrinter_h 00002 #define Util_ProgressPrinter_h 00003 00004 #include "Basis/CmdOptions.h" 00005 #include "Link/Mpi/MpiFuncs.h" 00006 00007 /* will print 00008 / name [======== ] 45% 00009 ^ percentage 00010 ^ progress bar 00011 ^ name of this progress 00012 ^ spinning mark 00013 */ 00014 00015 namespace Impala 00016 { 00017 namespace Util 00018 { 00019 00020 class ProgressPrinter 00021 { 00022 public: 00023 ProgressPrinter(std::ostream& console) : 00024 mConsole(console) 00025 { 00026 mDoShow = CmdOptions::GetInstance().GetBool("showProgress", true); 00027 if (Link::Mpi::MpiUsed()) 00028 mDoShow = false; 00029 mRange = 100; 00030 mLinewidth = 79; 00031 mMinimumBarLength = 20; 00032 } 00033 00034 void Start(const std::string& name, int range) 00035 { 00036 if (mDoShow) 00037 { 00038 mSpinner = 0; 00039 mName = name; 00040 mRange = range; 00041 if(mName.size() > mLinewidth - 10 - mMinimumBarLength) 00042 mName = mName.substr(0, mLinewidth - 10 - mMinimumBarLength - 3) + "..."; 00043 mProgressBarLength = mLinewidth - 10 - mName.size(); 00044 WriteLine(0); 00045 } 00046 } 00047 00048 void PrintProgress(int progress) 00049 { 00050 if (mDoShow) 00051 { 00052 EraseLine(); 00053 WriteLine(progress); 00054 } 00055 } 00056 00057 void Done() 00058 { 00059 if (mDoShow) 00060 { 00061 EraseLine(); 00062 WriteLine(mRange); 00063 mConsole << "\n"; 00064 mConsole.flush(); 00065 } 00066 } 00067 00068 private: 00069 void WriteLine(int progress) 00070 { 00071 switch(mSpinner) 00072 { 00073 case 0: mConsole << '/'; mSpinner=1; break; 00074 case 1: mConsole << '-'; mSpinner=2; break; 00075 case 2: mConsole << '\\'; mSpinner=3; break; 00076 case 3: mConsole << '|'; mSpinner=0; break; 00077 } 00078 mConsole << ' ' << mName << " ["; 00079 int length = mProgressBarLength * progress / mRange; 00080 mConsole << std::string(length, '=') << std::string(mProgressBarLength - length, ' '); 00081 std::string percentage = Impala::MakeString((int)(100 * ((double)progress / (double)mRange))); 00082 mConsole << "] " << std::string(3-percentage.size(), ' ') << percentage << '%'; 00083 mConsole.flush(); 00084 } 00085 00086 void EraseLine() 00087 { 00088 if (Link::Mpi::MpiUsed()) 00089 return; 00090 mConsole << std::string(mLinewidth,'\b'); 00091 mConsole.flush(); 00092 } 00093 00094 std::ostream &mConsole; 00095 int mRange; 00096 int mProgressBarLength; 00097 std::string mName; 00098 int mLinewidth; 00099 int mMinimumBarLength; 00100 int mSpinner; 00101 00102 bool mDoShow; 00103 }; 00104 00105 }//namespace Util 00106 }//namespace Impala 00107 00108 #endif //Util_ProgressPrinter_h