otsdaq  v2_05_02_indev
ProgressBar.h
1 #ifndef _ots_Utilities_ProgressBar_h_
2 #define _ots_Utilities_ProgressBar_h_
3 
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/MessageFacility/MessageFacility.h"
6 
7 #include <mutex>
8 #include <string>
9 
10 namespace ots
11 {
12 // ProgressBar
13 // class by Ryan Rivera ( rrivera @ fnal.gov ), July 2013
14 //
15 // The are 4 public member function that should matter to the user:
16 //
17 // resetProgressBar(int id) ~~
18 // Resets progress bar to 0% complete, id does not have to be unique in your
19 // code, read NOTE 2.
20 //
21 // step() ~~
22 // Marks that incremental progress has been made. user should place step()
23 // freely throughout the code each time a jump in the progress bar is desired.
24 // Thread safe.
25 //
26 // complete() ~~
27 // Indicate the progress bar is to be 100% at this point.
28 //
29 // read() ~~
30 // Returns the % complete. Thread safe.
31 //
32 // USE: User places resetProgressBar(id) at the start of sequence of events, as many
33 // step()'s as desired within the sequence, and complete() at the end of the sequence
34 // of events. The first time the code is run ever the class determines the total
35 // number of steps, so the
36 // progress % will be defined to be 0% with no steps complete, 50% with at least one
37 // step complete, and 100% once complete. Each run thereafter will always use the
38 // number of steps in the previous sequence to calculate the proper %.
39 //
40 // NOTE 1: Since the code uses the previous execution's number of steps to calculate the
41 //%, avoid
42 // placing step() calls in code that is run conditionally. It is best practice to
43 // place them at checkpoints that must always be reached.
44 //
45 // NOTE 2: The class uses the filename and line # of the resetProgressBar(id) call to
46 // store the baseline number of steps for a given sequence. So if using a single
47 // resetProgressBar(id) call to govern more than one sequence of events, you must
48 // assign an integer to the sequence you want to reset. Below is an example for two
49 // sequences sharing a resetProgressBar(id):
50 //
51 // ProgressBar myProgressBar;
52 // void setupProgress(int i)
53 // {
54 // myProgressBar.resetProgressBar(i); //this reset is shared by
55 // sequence one and
56 // //two so must identify with
57 // integer
58 //
59 // if(i==0) sequenceOne();
60 // else if(i==1) sequenceTwo();
61 // myProgressBar.complete();
62 // }
63 //
64 // void sequenceOne()
65 // {
66 // //do things
67 // myProgressBar.step();
68 // //do more things
69 // myProgressBar.step();
70 // }
71 //
72 // void sequenceTwo()
73 // {
74 // //do other things
75 // myProgressBar.step();
76 // }
77 //
78 
80 {
81  public:
82  ProgressBar();
83 
84 //********************************************************************//
85 // NOTE!!! don't call reset. Call resetProgressBar(id) as though
86 // the function was this:
87 // void resetProgressBar(int id)
88 //
89 // then the pre-compiler directive:
90 #define resetProgressBar(x) reset(__FILE__, std::to_string(__LINE__), x)
91  // will call this reset:
92  void reset(std::string file, std::string lineNumber, int id = 0);
93  //********************************************************************//
94 
95  // remaining member functions are called normal
96 
97  // set functions
98  void step(); // thread safe
99  void complete(); // declare complete, thread safe
100 
101  // get functions
102  bool isComplete(); // thread safe
103  int read(); // if stepsToComplete==0, then define any progress as 50%, thread safe
104  std::string readPercentageString(); // if stepsToComplete==0, then define any
105  // progress as 50%, thread safe
106 
107  private:
108  const std::string cProgressBarFilePath_;
109  const std::string cProgressBarFileExtension_;
110  std::string totalStepsFileName_;
111  int stepCount_;
112  int stepsToComplete_;
113  bool started_;
114  std::mutex theMutex_;
115 };
116 
117 } // namespace ots
118 
119 #endif