All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Progress.cxx
Go to the documentation of this file.
2 
3 #include "sys/stat.h"
4 
5 #include "TString.h"
6 
7 #include <iostream>
8 
9 namespace{
10  const int kBarWidth = 60;
11 }
12 
13 namespace ana
14 {
15  bool Progress::fAnyLive = false;
16 
17  //----------------------------------------------------------------------
18  Progress::Progress(const std::string& title)
19  : fDone(false), fIFrac(-1), fStart(time(0)), fPrevCall(time(0)), fLive(false)
20  {
21  // If no else is drawing, we can
22  if(!fAnyLive){
23  fLive = true;
24  fAnyLive = false;
25  }
26 
27  if(!fLive) return;
28 
29  std::cout << title << "..." << std::endl;
30  SetProgress(0); // Draw the initial bar
31  }
32 
33  //----------------------------------------------------------------------
35  {
36  // Finish up in case the user forgot to call Done()
37  Done();
38 
39  // If we were the ones drawing, we're not anymore
40  if(fLive) fAnyLive = false;
41  }
42 
43  //----------------------------------------------------------------------
44  void Progress::SetProgress(double frac)
45  {
46  if(!fLive || fDone) return;
47 
48  // Check if we're outputting to a file. If so don't bother showing off
49  // with the progress bar, it won't work.
50  struct stat buf;
51  fstat(fileno(stdout), &buf);
52  const bool isFile = (buf.st_mode & S_IFREG) || (buf.st_mode & S_IFIFO);
53  if(isFile) return;
54 
55  const int ifrac = (kBarWidth-1)*frac;
56 
57  const time_t t_now = time(0);
58 
59  // Don't repaint unnecessarily
60  if(ifrac == fIFrac && t_now - fPrevCall < 2) return;
61 
62  fIFrac = ifrac;
63  fPrevCall = time(0);
64 
65  std::string str(kBarWidth, ' ');
66  for(int i = 0; i < ifrac; ++i) str[i] = '=';
67  str[ifrac] = '>';
68  str[0] = '[';
69  str[kBarWidth-1] = ']';
70 
71  if(frac > 0){
72  const int elapse = t_now - fStart;
73  if(elapse > 2){ // Don't show for very short steps
74  if(frac < 1)
75  str += " "+FormatTime(elapse*(1-frac)/frac);
76  else
77  str += " "+FormatTime(elapse);
78  str += " "; // Enough to cover up any previous version
79  }
80  }
81 
82  std::cout << "\r" << str << std::flush;
83 
84  if(frac == 1){
85  fDone = true;
86  std::cout << std::endl;
87  }
88  }
89 
90  //----------------------------------------------------------------------
92  {
93  if(!fLive) return;
94 
95  if(fDone) return; // Can easily be called multiple times
96 
97  SetProgress(1); // Make sure the bar shows 100%
98 
99  fDone = true;
100  }
101 
102  //----------------------------------------------------------------------
103  std::string Progress::FormatTime(double sec) const
104  {
105  // Yes, I'm sure there's a standard way to do this, but this was easy, and
106  // lets me print exactly what I want.
107  std::string ret;
108  if(sec >= 60*60-.5){
109  ret += TString::Format("%dh", (int(sec+.5)/(60*60))).Data();
110  }
111  if(sec >= 60-.5){
112  ret += TString::Format("%dm", (int(sec+.5)/60)%60).Data();
113  }
114  if(sec < 60*60){ // don't clutter if still measured in hours
115  ret += TString::Format("%ds", (int(sec+.5)%60)).Data();
116  }
117  return ret;
118  }
119 }
process_name opflashCryoW ana
bool fDone
Has Done been called?
Definition: Progress.h:22
time_t fStart
Definition: Progress.h:25
static bool fAnyLive
Are any bars live?
Definition: Progress.h:30
Progress(const std::string &title)
Create and draw the progress bar.
Definition: Progress.cxx:18
int fIFrac
What character are we on? Prevents unnecessary redraws.
Definition: Progress.h:23
time_t fPrevCall
Definition: Progress.h:26
void SetProgress(double frac)
Update the progress fraction between zero and one.
Definition: Progress.cxx:44
bool fLive
Is this bar live (drawable?)
Definition: Progress.h:29
std::string FormatTime(double sec) const
Definition: Progress.cxx:103
void Done()
Call this when action is completed.
Definition: Progress.cxx:91
BEGIN_PROLOG could also be cout