ROSE  0.11.2.0
Progress.h
1 #ifndef Rose_Progress_H
2 #define Rose_Progress_H
3 
4 #include <rosePublicConfig.h> // for ROSE_USE_CMAKE
5 #include <boost/chrono.hpp>
6 #include <boost/thread.hpp>
7 #include <rose_constants.h>
8 #include <rose_isnan.h>
9 #include <Sawyer/SharedPointer.h>
10 #include <Sawyer/Stopwatch.h>
11 #include <Sawyer/Synchronization.h>
12 #include <string>
13 #include <vector>
14 
15 namespace Rose {
16 
166 public:
169 
179  struct Report {
180  std::string name;
181  double completion;
182  double maximum;
186  : completion(0.0), maximum(1.0) {}
187 
189  explicit Report(double completion, double maximum = 1.0)
190  : completion(completion), maximum(maximum) {}
191 
193  Report(const std::string &name, double completion, double maximum = 1.0)
194  : name(name), completion(completion), maximum(maximum) {}
195  };
196 
197 private:
198  static const size_t TERMINATING = INVALID_INDEX;
199 
200  // Synchronized data members
201  mutable SAWYER_THREAD_TRAITS::Mutex mutex_; // protects the following data members
202 #if SAWYER_MULTI_THREADED
203  mutable SAWYER_THREAD_TRAITS::ConditionVariable cv_;// for signaling changes to the latestReport_
204 #endif
205  std::vector<Report> reports_; // report stack, one elemet per nested phase
206  size_t reportNumber_; // sequence number of latestReport_, or TERMINATING
207  Sawyer::Stopwatch reportAge_; // time since last report arrived (or since construction)
208 
209 protected:
210  Progress(): reportNumber_(0) {}
211 
212 public:
214  static Ptr instance();
215 
216 public:
239  void update(double completion, double maximum = 1.0);
240  void update(const Report&);
257  Report push();
258  Report push(double completion, double maximum = 1.0);
259  Report push(const Report&);
276  void pop();
277  void pop(double completion, double maximum = 1.0);
278  void pop(const Report&);
301  void finished();
302  void finished(double completion, double maximum = 1.0);
303  void finished(const Report&);
313  bool isFinished() const;
314 
325  std::pair<Report, double /*seconds*/> reportLatest(const std::string &nameSeparator = ".") const;
326 
348  template<class Functor>
349  bool reportRegularly(boost::chrono::milliseconds interval, Functor f, const std::string &nameSeparator = ".") const {
350  // Makes no sense for single threaded. Does not compile when ROSE is built with CMake
351 #if SAWYER_MULTI_THREADED && !defined(ROSE_USE_CMAKE)
352  while (1) {
353  std::pair<Report, double /*seconds*/> rpt = reportLatest(nameSeparator);
354  if (!f(rpt.first, rpt.second))
355  return false;
356  if (isFinished())
357  return true;
358  boost::this_thread::sleep_for(interval);
359  }
360 #else
361  return false;
362 #endif
363  }
364 
385  template<class Functor>
386  bool reportChanges(boost::chrono::milliseconds limit, Functor f, const std::string &nameSeparator = ".") const {
387 #if SAWYER_MULTI_THREADED && !defined(ROSE_USE_CMAKE) // makes no sense for single threaded. Does not compile with cmake
388  Sawyer::Stopwatch timer;
389  size_t seen = TERMINATING - 1;
390  while (1) {
391  SAWYER_THREAD_TRAITS::UniqueLock lock(mutex_);
392  while (reportNumber_ == seen)
393  cv_.wait(lock);
394  ASSERT_forbid(reports_.empty());
395  Report report = reports_.back();
396  report.name = reportNameNS(nameSeparator);
397  seen = reportNumber_;
398  lock.unlock();
399 
400  if (!f(report))
401  return false;
402  if (TERMINATING == seen)
403  return true;
404  boost::this_thread::sleep_for(limit);
405  }
406 #else
407  return false;
408 #endif
409  }
410 
411 private:
412  std::string reportNameNS(const std::string &nameSeparator) const;
413 };
414 
438  Progress::Ptr progress_;
439  Progress::Report after_;
440 
441 public:
443  ProgressTask(const Progress::Ptr &progress, const std::string &name, double afterCompletion = NAN)
444  : progress_(progress) {
445  if (progress_) {
446  after_ = progress_->push(Progress::Report(name, 0.0));
447  if (!rose_isnan(afterCompletion))
448  after_.completion = afterCompletion;
449  }
450  }
451 
453  ProgressTask(const std::string &name, double afterCompletion = NAN)
454  : progress_(Progress::instance()) {
455  after_ = progress_->push(Progress::Report(name, 0.0));
456  if (!rose_isnan(afterCompletion))
457  after_.completion = afterCompletion;
458  }
459 
462  if (progress_)
463  progress_->pop(after_);
464  }
465 
466 public:
474  return progress_;
475  }
476 
481  void cancel() {
482  progress_ = Progress::Ptr();
483  }
484 };
485 
486 } // namespace
487 
488 #endif
Report(const std::string &name, double completion, double maximum=1.0)
Report with name and completion.
Definition: Progress.h:193
A single progress report.
Definition: Progress.h:179
void cancel()
Cancel all cleanup operations.
Definition: Progress.h:481
Report(double completion, double maximum=1.0)
Report completion with default name.
Definition: Progress.h:189
Progress::Ptr progress() const
Progress object being used.
Definition: Progress.h:473
RAII sub-task progress.
Definition: Progress.h:437
ProgressTask(const std::string &name, double afterCompletion=NAN)
Create progress object for subtask.
Definition: Progress.h:453
std::string name
What is being reported.
Definition: Progress.h:180
ProgressTask(const Progress::Ptr &progress, const std::string &name, double afterCompletion=NAN)
Prepare existing progress object for subtask.
Definition: Progress.h:443
Main namespace for the ROSE library.
void update(double completion, double maximum=1.0)
Make a progress report.
static Ptr instance()
Factory to create a new instance of this class.
std::pair< Report, double > reportLatest(const std::string &nameSeparator=".") const
Latest report and its age in seconds.
bool isFinished() const
Predicate indicating whether the task is finished.
Simple elapsed time.
Definition: Stopwatch.h:41
void finished()
Indicate that the task is complete.
Report()
Initial progress report.
Definition: Progress.h:185
Report push()
Push a new progress phase onto the stack.
bool reportRegularly(boost::chrono::milliseconds interval, Functor f, const std::string &nameSeparator=".") const
Invoke the specified function at regular intervals.
Definition: Progress.h:349
void pop()
Pop the top progress phase from the stack.
double completion
Estimated degree of completion.
Definition: Progress.h:181
Base class for reference counted objects.
Definition: SharedObject.h:64
A general, thread-safe way to report progress made on some task.
Definition: Progress.h:165
bool reportChanges(boost::chrono::milliseconds limit, Functor f, const std::string &nameSeparator=".") const
Invoke the specified function each time the progress changes.
Definition: Progress.h:386
~ProgressTask()
Clean up subtask progress.
Definition: Progress.h:461
const size_t INVALID_INDEX(-1)
Invalid array index.
Sawyer::SharedPointer< Progress > Ptr
Progress objects are reference counted.
Definition: Progress.h:168
double maximum
Maximum value for completion.
Definition: Progress.h:182