ROSE  0.9.9.139
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_isnan.h>
8 #include <Sawyer/SharedPointer.h>
9 #include <Sawyer/Stopwatch.h>
10 #include <Sawyer/Synchronization.h>
11 #include <string>
12 #include <vector>
13 
14 namespace Rose {
15 
165 public:
168 
172  struct Report {
173  std::string name;
174  double completion;
178  : completion(0.0) {}
179 
181  explicit Report(double completion)
182  : completion(completion) {}
183 
185  Report(const std::string &name, double completion)
186  : name(name), completion(completion) {}
187  };
188 
189 private:
190  static const size_t TERMINATING = (size_t)(-1);
191 
192  // Synchronized data members
193  mutable SAWYER_THREAD_TRAITS::Mutex mutex_; // protects the following data members
194 #if SAWYER_MULTI_THREADED
195  mutable SAWYER_THREAD_TRAITS::ConditionVariable cv_;// for signaling changes to the latestReport_
196 #endif
197  std::vector<Report> reports_; // report stack, one elemet per nested phase
198  size_t reportNumber_; // sequence number of latestReport_, or TERMINATING
199  Sawyer::Stopwatch reportAge_; // time since last report arrived (or since construction)
200 
201 protected:
202  Progress(): reportNumber_(0) {}
203 
204 public:
206  static Ptr instance();
207 
208 public:
231  void update(double completion);
232  void update(const Report&);
249  Report push();
250  Report push(double completion);
251  Report push(const Report&);
268  void pop();
269  void pop(double completion);
270  void pop(const Report&);
293  void finished();
294  void finished(double completion);
295  void finished(const Report&);
305  bool isFinished() const;
306 
317  std::pair<Report, double /*seconds*/> reportLatest(const std::string &nameSeparator = ".") const;
318 
340  template<class Functor>
341  bool reportRegularly(boost::chrono::milliseconds interval, Functor f, const std::string &nameSeparator = ".") const {
342  // Makes no sense for single threaded. Does not compile when ROSE is built with CMake
343 #if SAWYER_MULTI_THREADED && !defined(ROSE_USE_CMAKE)
344  while (1) {
345  std::pair<Report, double /*seconds*/> rpt = reportLatest(nameSeparator);
346  if (!f(rpt.first, rpt.second))
347  return false;
348  if (isFinished())
349  return true;
350  boost::this_thread::sleep_for(interval);
351  }
352 #else
353  return false;
354 #endif
355  }
356 
377  template<class Functor>
378  bool reportChanges(boost::chrono::milliseconds limit, Functor f, const std::string &nameSeparator = ".") const {
379 #if SAWYER_MULTI_THREADED && !defined(ROSE_USE_CMAKE) // makes no sense for single threaded. Does not compile with cmake
380  Sawyer::Stopwatch timer;
381  size_t seen = TERMINATING - 1;
382  while (1) {
383  SAWYER_THREAD_TRAITS::UniqueLock lock(mutex_);
384  while (reportNumber_ == seen)
385  cv_.wait(lock);
386  ASSERT_forbid(reports_.empty());
387  Report report = reports_.back();
388  report.name = reportNameNS(nameSeparator);
389  seen = reportNumber_;
390  lock.unlock();
391 
392  if (!f(report))
393  return false;
394  if (TERMINATING == seen)
395  return true;
396  boost::this_thread::sleep_for(limit);
397  }
398 #else
399  return false;
400 #endif
401  }
402 
403 private:
404  std::string reportNameNS(const std::string &nameSeparator) const;
405 };
406 
430  Progress::Ptr progress_;
431  Progress::Report after_;
432 
433 public:
435  ProgressTask(const Progress::Ptr &progress, const std::string &name, double afterCompletion = NAN)
436  : progress_(progress) {
437  if (progress_) {
438  after_ = progress_->push(Progress::Report(name, 0.0));
439  if (!rose_isnan(afterCompletion))
440  after_.completion = afterCompletion;
441  }
442  }
443 
445  ProgressTask(const std::string &name, double afterCompletion = NAN)
446  : progress_(Progress::instance()) {
447  after_ = progress_->push(Progress::Report(name, 0.0));
448  if (!rose_isnan(afterCompletion))
449  after_.completion = afterCompletion;
450  }
451 
454  if (progress_)
455  progress_->pop(after_);
456  }
457 
458 public:
466  return progress_;
467  }
468 
473  void cancel() {
474  progress_ = Progress::Ptr();
475  }
476 };
477 
478 } // namespace
479 
480 #endif
A single progress report.
Definition: Progress.h:172
void cancel()
Cancel all cleanup operations.
Definition: Progress.h:473
Progress::Ptr progress() const
Progress object being used.
Definition: Progress.h:465
RAII sub-task progress.
Definition: Progress.h:429
ProgressTask(const std::string &name, double afterCompletion=NAN)
Create progress object for subtask.
Definition: Progress.h:445
std::string name
What is being reported.
Definition: Progress.h:173
void update(double completion)
Make a progress report.
ProgressTask(const Progress::Ptr &progress, const std::string &name, double afterCompletion=NAN)
Prepare existing progress object for subtask.
Definition: Progress.h:435
Main namespace for the ROSE library.
Report(const std::string &name, double completion)
Full report with name and completion.
Definition: Progress.h:185
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:177
Report push()
Push a new progress phase onto the stack.
Report(double completion)
Report completion with default name.
Definition: Progress.h:181
bool reportRegularly(boost::chrono::milliseconds interval, Functor f, const std::string &nameSeparator=".") const
Invoke the specified function at regular intervals.
Definition: Progress.h:341
void pop()
Pop the top progress phase from the stack.
double completion
Estimated degree of completion.
Definition: Progress.h:174
Base class for reference counted objects.
Definition: SharedObject.h:22
A general, thread-safe way to report progress made on some task.
Definition: Progress.h:164
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:378
~ProgressTask()
Clean up subtask progress.
Definition: Progress.h:453
Sawyer::SharedPointer< Progress > Ptr
Progress objects are reference counted.
Definition: Progress.h:167