ROSE 0.11.145.147
Progress.h
1#ifndef ROSE_Progress_H
2#define ROSE_Progress_H
3
4#include <Rose/BasicTypes.h>
5
6#include <Rose/Constants.h>
7#include <ROSE_UNUSED.h>
8
9#include <boost/chrono.hpp>
10#include <boost/thread.hpp>
11#include <rose_isnan.h>
12#include <Sawyer/Stopwatch.h>
13#include <Sawyer/Synchronization.h>
14#include <string>
15#include <vector>
16
17namespace Rose {
18
168public:
171
181 struct Report {
182 std::string name;
183 double completion;
184 double maximum;
188 : completion(0.0), maximum(1.0) {}
189
191 explicit Report(double completion, double maximum = 1.0)
193
195 Report(const std::string &name, double completion, double maximum = 1.0)
197 };
198
199private:
200 static const size_t TERMINATING = INVALID_INDEX;
201
202 // Synchronized data members
203 mutable SAWYER_THREAD_TRAITS::Mutex mutex_; // protects the following data members
204#if SAWYER_MULTI_THREADED
205 mutable SAWYER_THREAD_TRAITS::ConditionVariable cv_;// for signaling changes to the latestReport_
206#endif
207 std::vector<Report> reports_; // report stack, one elemet per nested phase
208 size_t reportNumber_; // sequence number of latestReport_, or TERMINATING
209 Sawyer::Stopwatch reportAge_; // time since last report arrived (or since construction)
210
211protected:
212 Progress(): reportNumber_(0) {}
213
214public:
216 static Ptr instance();
217
218public:
241 void update(double completion, double maximum = 1.0);
242 void update(const Report&);
260 Report push(double completion, double maximum = 1.0);
278 void pop();
279 void pop(double completion, double maximum = 1.0);
280 void pop(const Report&);
303 void finished();
304 void finished(double completion, double maximum = 1.0);
305 void finished(const Report&);
315 bool isFinished() const;
316
327 std::pair<Report, double /*seconds*/> reportLatest(const std::string &nameSeparator = ".") const;
328
350 template<class Functor>
351 bool reportRegularly(boost::chrono::milliseconds interval, Functor f, const std::string &nameSeparator = ".") const {
352 // Makes no sense for single threaded. Does not compile when ROSE is built with CMake
353#if SAWYER_MULTI_THREADED && !defined(ROSE_USE_CMAKE)
354 while (1) {
355 std::pair<Report, double /*seconds*/> rpt = reportLatest(nameSeparator);
356 if (!f(rpt.first, rpt.second))
357 return false;
358 if (isFinished())
359 return true;
360 boost::this_thread::sleep_for(interval);
361 }
362#else
363 ROSE_UNUSED(interval);
364 ROSE_UNUSED(f);
365 ROSE_UNUSED(nameSeparator);
366 return false;
367#endif
368 }
369
390 template<class Functor>
391 bool reportChanges(boost::chrono::milliseconds limit, Functor f, const std::string &nameSeparator = ".") const {
392#if SAWYER_MULTI_THREADED && !defined(ROSE_USE_CMAKE) // makes no sense for single threaded. Does not compile with cmake
393 Sawyer::Stopwatch timer;
394 size_t seen = TERMINATING - 1;
395 while (1) {
396 SAWYER_THREAD_TRAITS::UniqueLock lock(mutex_);
397 while (reportNumber_ == seen)
398 cv_.wait(lock);
399 ASSERT_forbid(reports_.empty());
400 Report report = reports_.back();
401 report.name = reportNameNS(nameSeparator);
402 seen = reportNumber_;
403 lock.unlock();
404
405 if (!f(report))
406 return false;
407 if (TERMINATING == seen)
408 return true;
409 boost::this_thread::sleep_for(limit);
410 }
411#else
412 ROSE_UNUSED(limit);
413 ROSE_UNUSED(f);
414 ROSE_UNUSED(nameSeparator);
415 return false;
416#endif
417 }
418
419private:
420 std::string reportNameNS(const std::string &nameSeparator) const;
421};
422
446 Progress::Ptr progress_;
447 Progress::Report after_;
448
449public:
451 ProgressTask(const Progress::Ptr &progress, const std::string &name, double afterCompletion = NAN)
452 : progress_(progress) {
453 if (progress_) {
454 after_ = progress_->push(Progress::Report(name, 0.0));
455 if (!rose_isnan(afterCompletion))
456 after_.completion = afterCompletion;
457 }
458 }
459
461 ProgressTask(const std::string &name, double afterCompletion = NAN)
462 : progress_(Progress::instance()) {
463 after_ = progress_->push(Progress::Report(name, 0.0));
464 if (!rose_isnan(afterCompletion))
465 after_.completion = afterCompletion;
466 }
467
470 if (progress_)
471 progress_->pop(after_);
472 }
473
474public:
482 return progress_;
483 }
484
489 void cancel() {
490 progress_ = Progress::Ptr();
491 }
492};
493
494} // namespace
495
496#endif
RAII sub-task progress.
Definition Progress.h:445
~ProgressTask()
Clean up subtask progress.
Definition Progress.h:469
ProgressTask(const Progress::Ptr &progress, const std::string &name, double afterCompletion=NAN)
Prepare existing progress object for subtask.
Definition Progress.h:451
ProgressTask(const std::string &name, double afterCompletion=NAN)
Create progress object for subtask.
Definition Progress.h:461
void cancel()
Cancel all cleanup operations.
Definition Progress.h:489
Progress::Ptr progress() const
Progress object being used.
Definition Progress.h:481
A general, thread-safe way to report progress made on some task.
Definition Progress.h:167
void update(const Report &)
Make a progress report.
bool reportRegularly(boost::chrono::milliseconds interval, Functor f, const std::string &nameSeparator=".") const
Invoke the specified function at regular intervals.
Definition Progress.h:351
void finished()
Indicate that the task is complete.
static Ptr instance()
Factory to create a new instance of this class.
void finished(const Report &)
Indicate that the task is complete.
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:391
std::pair< Report, double > reportLatest(const std::string &nameSeparator=".") const
Latest report and its age in seconds.
Report push(double completion, double maximum=1.0)
Push a new progress phase onto the stack.
Report push()
Push a new progress phase onto the stack.
ProgressPtr Ptr
Progress objects are reference counted.
Definition Progress.h:170
void pop()
Pop the top progress phase from the stack.
bool isFinished() const
Predicate indicating whether the task is finished.
void pop(const Report &)
Pop the top progress phase from the stack.
void update(double completion, double maximum=1.0)
Make a progress report.
Report push(const Report &)
Push a new progress phase onto the stack.
void pop(double completion, double maximum=1.0)
Pop the top progress phase from the stack.
void finished(double completion, double maximum=1.0)
Indicate that the task is complete.
Base class for reference counted objects.
Simple elapsed time.
Definition Stopwatch.h:41
The ROSE library.
const size_t INVALID_INDEX
Invalid array index.
Definition Constants.h:25
A single progress report.
Definition Progress.h:181
Report(const std::string &name, double completion, double maximum=1.0)
Report with name and completion.
Definition Progress.h:195
Report(double completion, double maximum=1.0)
Report completion with default name.
Definition Progress.h:191
std::string name
What is being reported.
Definition Progress.h:182
double completion
Estimated degree of completion.
Definition Progress.h:183
double maximum
Maximum value for completion.
Definition Progress.h:184
Report()
Initial progress report.
Definition Progress.h:187