1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
/*
* progress.hpp
*
* A Front-end class for InterruptableProgressMonitor.
*
* Author: karl.forner@gmail.com
*
*/
#ifndef _RcppProgress_PROGRESS_HPP
#define _RcppProgress_PROGRESS_HPP
#include "interruptable_progress_monitor.hpp"
#include "simple_progress_bar.hpp"
// e.g. for Rf_error
#include <R_ext/Error.h>
class Progress {
public:
/**
*
* Main constructor
* @param max the expected number of tasks to perform
* @param display_progress whether to display a progress bar in the console
* @param pb the ProgressBar instance to use
*/
Progress(
unsigned long max,
bool display_progress = true,
ProgressBar& pb = default_progress_bar()
) {
cleanup();
monitor_singleton() = new InterruptableProgressMonitor(max, display_progress, pb);
}
~Progress() { cleanup(); }
public: // ==== USER INTERFACE =====
/**
* cleanup
*
* should normally not be called, unless a something bad happens (
* a process/thread that crashes).
*
*/
void cleanup() {
if (monitor_singleton() != 0) delete monitor_singleton();
monitor_singleton() = 0;
}
/**
* increment the current progress.
*
* This method should preferably be used intead of update in a OpenMP context.
*
* Iff called by the master thread, it will also update the display if needed
*
* @param amount the number of newly performed tasks to report
*
* @return false iff the computation is aborted
*/
bool increment(unsigned long amount=1) { return monitor().increment(amount); }
/**
* set the current progress indicator
*
* Iff called by the master thread, it will also update the display if needed
*
* @param current the total number of performed tasks so far (by all threads)
*
* @return false iff the computation is aborted
*/
bool update(unsigned long current) { return monitor().update(current); }
/**
* return if the computation has been aborted.
* N.B: do not perform any check by itselfd
*/
bool is_aborted() const { return monitor().is_aborted(); }
/**
* check that the no interruption has been requested and return the current status
*
* Iff called by the master thread, it will check for R-user level interruption.
*
* @return true iff the computation is aborted
*/
static bool check_abort() { return monitor().check_abort(); }
private:
static InterruptableProgressMonitor*& monitor_singleton() {
static InterruptableProgressMonitor* p = 0;
return p;
}
// trick to provide a default static member in a header file
static SimpleProgressBar& default_progress_bar() {
static SimpleProgressBar pb;
pb.reset();
return pb;
}
public: // ==== OTHER PUBLIC INTERFACE =====
static InterruptableProgressMonitor& monitor() { return *monitor_singleton(); }
};
#endif
|