/
AbstractAsyncAlgorithmRunner.cpp
136 lines (119 loc) · 4.42 KB
/
AbstractAsyncAlgorithmRunner.cpp
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "MantidQtAPI/AbstractAsyncAlgorithmRunner.h"
#include <Poco/ActiveResult.h>
using namespace Mantid::Kernel;
using namespace Mantid::API;
namespace MantidQt
{
namespace API
{
//----------------------------------------------------------------------------------------------
/** Constructor
*/
AbstractAsyncAlgorithmRunner::AbstractAsyncAlgorithmRunner(QObject * parent) : QObject(parent),
m_finishedObserver(*this, &AbstractAsyncAlgorithmRunner::handleAlgorithmFinishedNotification),
m_progressObserver(*this, &AbstractAsyncAlgorithmRunner::handleAlgorithmProgressNotification),
m_errorObserver(*this, &AbstractAsyncAlgorithmRunner::handleAlgorithmErrorNotification),
m_asyncResult(NULL)
{
}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
AbstractAsyncAlgorithmRunner::~AbstractAsyncAlgorithmRunner()
{
if (m_asyncAlg)
{
m_asyncAlg->removeObserver(m_finishedObserver);
m_asyncAlg->removeObserver(m_errorObserver);
m_asyncAlg->removeObserver(m_progressObserver);
}
delete m_asyncResult;
}
//--------------------------------------------------------------------------------------
/** If an algorithm is already running, cancel it.
* Does nothing if no algorithm is running. This blocks
* for up to 1 second to wait for the algorithm to finish cancelling.
*/
void AbstractAsyncAlgorithmRunner::cancelRunningAlgorithm()
{
// Cancel any currently running algorithms
if (m_asyncAlg)
{
if (m_asyncAlg->isRunning())
{
m_asyncAlg->cancel();
}
if (m_asyncResult)
{
m_asyncResult->tryWait(1000);
delete m_asyncResult;
m_asyncResult = NULL;
}
m_asyncAlg->removeObserver(m_finishedObserver);
m_asyncAlg->removeObserver(m_errorObserver);
m_asyncAlg->removeObserver(m_progressObserver);
m_asyncAlg.reset();
}
}
//--------------------------------------------------------------------------------------
/** Begin asynchronous execution of an algorithm and observe its execution
*
* @param alg :: algorithm to execute. All properties should have been set properly.
*/
void AbstractAsyncAlgorithmRunner::startAlgorithm(Mantid::API::IAlgorithm_sptr alg)
{
if (!alg)
throw std::invalid_argument("AbstractAsyncAlgorithmRunner::startAlgorithm() given a NULL Algorithm");
if (!alg->isInitialized())
throw std::invalid_argument("AbstractAsyncAlgorithmRunner::startAlgorithm() given an uninitialized Algorithm");
cancelRunningAlgorithm();
// Start asynchronous execution
m_asyncAlg = alg;
m_asyncResult = new Poco::ActiveResult<bool>(m_asyncAlg->executeAsync());
// Observe the algorithm
alg->addObserver(m_finishedObserver);
alg->addObserver(m_errorObserver);
alg->addObserver(m_progressObserver);
}
/// Get back a pointer to the running algorithm
Mantid::API::IAlgorithm_sptr AbstractAsyncAlgorithmRunner::getCurrentAlgorithm() const
{
return m_asyncAlg;
}
//--------------------------------------------------------------------------------------
/** Observer called when the asynchronous algorithm has completed.
*
* Calls handler defined in concrete class
*
* @param pNf :: finished notification object.
*/
void AbstractAsyncAlgorithmRunner::handleAlgorithmFinishedNotification(const Poco::AutoPtr<Algorithm::FinishedNotification>& pNf)
{
UNUSED_ARG(pNf);
handleAlgorithmFinish();
}
//--------------------------------------------------------------------------------------
/** Observer called when the async algorithm has progress to report
*
* Calls handler defined in concrete class
*
* @param pNf :: notification object
*/
void AbstractAsyncAlgorithmRunner::handleAlgorithmProgressNotification(const Poco::AutoPtr<Algorithm::ProgressNotification>& pNf)
{
handleAlgorithmProgress(pNf->progress, pNf->message);
}
//--------------------------------------------------------------------------------------
/** Observer called when the async algorithm has encountered an error.
*
* Calls handler defined in concrete class
*
* @param pNf :: notification object
*/
void AbstractAsyncAlgorithmRunner::handleAlgorithmErrorNotification(const Poco::AutoPtr<Algorithm::ErrorNotification>& pNf)
{
UNUSED_ARG(pNf);
handleAlgorithmError();
}
} // namespace Mantid
} // namespace API