Skip to content

Commit

Permalink
Replaced old implementation with one which should be unit testable
Browse files Browse the repository at this point in the history
Refs #10092
  • Loading branch information
DanNixon committed Aug 11, 2014
1 parent d0e4083 commit 6692668
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 119 deletions.
3 changes: 3 additions & 0 deletions Code/Mantid/MantidQt/API/CMakeLists.txt
@@ -1,4 +1,5 @@
set ( SRC_FILES
src/AbstractAsyncAlgorithmRunner.cpp
src/AlgorithmDialog.cpp
src/AlgorithmInputHistory.cpp
src/AlgorithmPropertiesWidget.cpp
Expand Down Expand Up @@ -38,6 +39,7 @@ set ( SRC_FILES
)

set ( MOC_FILES
inc/MantidQtAPI/AbstractAsyncAlgorithmRunner.h
inc/MantidQtAPI/AlgorithmDialog.h
inc/MantidQtAPI/AlgorithmRunner.h
inc/MantidQtAPI/AlgorithmPropertiesWidget.h
Expand Down Expand Up @@ -67,6 +69,7 @@ set ( MOC_FILES
# Include files aren't required, but this makes them appear in Visual Studio
set ( INC_FILES
${MOC_FILES}
inc/MantidQtAPI/AbstractAsyncAlgorithmRunner.h
inc/MantidQtAPI/AlgorithmInputHistory.h
inc/MantidQtAPI/AlgorithmRunner.h
inc/MantidQtAPI/BatchAlgorithmRunner.h
Expand Down
@@ -0,0 +1,74 @@
#ifndef MANTID_API_ABSTRACTASYNCALGORITHMRUNNER_H_
#define MANTID_API_ABSTRACTASYNCALGORITHMRUNNER_H_

#include "DllOption.h"
#include "MantidAPI/Algorithm.h"

#include <QObject>
#include <Poco/NObserver.h>

namespace MantidQt
{
namespace API
{

/**TODO
Copyright &copy; 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class EXPORT_OPT_MANTIDQT_API AbstractAsyncAlgorithmRunner : public QObject
{
Q_OBJECT

public:
explicit AbstractAsyncAlgorithmRunner(QObject * parent = 0);
virtual ~AbstractAsyncAlgorithmRunner();

Mantid::API::IAlgorithm_sptr getCurrentAlgorithm() const;

protected:
void startAlgorithm(Mantid::API::IAlgorithm_sptr alg);
void cancelRunningAlgorithm();

/// Algorithm notification handlers
void handleAlgorithmFinishedNotification(const Poco::AutoPtr<Mantid::API::Algorithm::FinishedNotification>& pNf);
Poco::NObserver<AbstractAsyncAlgorithmRunner, Mantid::API::Algorithm::FinishedNotification> m_finishedObserver;
virtual void handleAlgorithmFinish() = 0;

void handleAlgorithmProgressNotification(const Poco::AutoPtr<Mantid::API::Algorithm::ProgressNotification>& pNf);
Poco::NObserver<AbstractAsyncAlgorithmRunner, Mantid::API::Algorithm::ProgressNotification> m_progressObserver;
virtual void handleAlgorithmProgress(double p, std::string msg) = 0;

void handleAlgorithmErrorNotification(const Poco::AutoPtr<Mantid::API::Algorithm::ErrorNotification>& pNf);
Poco::NObserver<AbstractAsyncAlgorithmRunner, Mantid::API::Algorithm::ErrorNotification> m_errorObserver;
virtual void handleAlgorithmError() = 0;

/// For the asynchronous call in dynamic rebinning. Holds the result of asyncExecute() algorithm call
Poco::ActiveResult<bool> * m_asyncResult;

/// Reference to the algorithm executing asynchronously.
Mantid::API::IAlgorithm_sptr m_asyncAlg;
};

} // namespace API
} // namespace Mantid

#endif /* MANTID_API_ABSTRACTASYNCALGORITHMRUNNER_H_ */
24 changes: 6 additions & 18 deletions Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmRunner.h
@@ -1,6 +1,8 @@
#ifndef MANTID_API_ALGORITHMRUNNER_H_
#define MANTID_API_ALGORITHMRUNNER_H_

#include "MantidQtAPI/AbstractAsyncAlgorithmRunner.h"

#include "DllOption.h"
#include "MantidAPI/Algorithm.h"

Expand Down Expand Up @@ -47,7 +49,7 @@ namespace API
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class EXPORT_OPT_MANTIDQT_API AlgorithmRunner : public QObject
class EXPORT_OPT_MANTIDQT_API AlgorithmRunner : public AbstractAsyncAlgorithmRunner
{
Q_OBJECT

Expand All @@ -68,26 +70,12 @@ namespace API
void algorithmProgress(double p,const std::string& msg);

protected:

/// Algorithm notification handlers
void handleAlgorithmFinishedNotification(const Poco::AutoPtr<Mantid::API::Algorithm::FinishedNotification>& pNf);
Poco::NObserver<AlgorithmRunner, Mantid::API::Algorithm::FinishedNotification> m_finishedObserver;

void handleAlgorithmProgressNotification(const Poco::AutoPtr<Mantid::API::Algorithm::ProgressNotification>& pNf);
Poco::NObserver<AlgorithmRunner, Mantid::API::Algorithm::ProgressNotification> m_progressObserver;

void handleAlgorithmErrorNotification(const Poco::AutoPtr<Mantid::API::Algorithm::ErrorNotification>& pNf);
Poco::NObserver<AlgorithmRunner, Mantid::API::Algorithm::ErrorNotification> m_errorObserver;

/// For the asynchronous call in dynamic rebinning. Holds the result of asyncExecute() algorithm call
Poco::ActiveResult<bool> * m_asyncResult;

/// Reference to the algorithm executing asynchronously.
Mantid::API::IAlgorithm_sptr m_asyncAlg;
void handleAlgorithmFinish();
void handleAlgorithmProgress(double p, const std::string msg);
void handleAlgorithmError();

};


} // namespace API
} // namespace Mantid

Expand Down
20 changes: 8 additions & 12 deletions Code/Mantid/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h
@@ -1,11 +1,11 @@
#ifndef MANTID_API_BATCHALGORITHMRUNNER_H_
#define MANTID_API_BATCHALGORITHMRUNNER_H_

#include "MantidQtAPI/AbstractAsyncAlgorithmRunner.h"

#include "DllOption.h"
#include "MantidAPI/Algorithm.h"

#include "MantidQtAPI/AlgorithmRunner.h"

#include <QObject>

namespace MantidQt
Expand Down Expand Up @@ -38,7 +38,7 @@ namespace API
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/

class EXPORT_OPT_MANTIDQT_API BatchAlgorithmRunner : public QObject
class EXPORT_OPT_MANTIDQT_API BatchAlgorithmRunner : public AbstractAsyncAlgorithmRunner
{
Q_OBJECT

Expand All @@ -47,34 +47,30 @@ namespace API
virtual ~BatchAlgorithmRunner();

void cancelAll();
void startBatch(bool stopOnFailure = true);
void addAlgorithm(Mantid::API::IAlgorithm_sptr algo);

void startBatch(bool stopOnFailure = true);
bool isExecuting();

void preRegisterWorkspace(std::string workspaceName);
void preRegisterWorkspaces(std::vector<std::string> workspaceNames);

void addAlgorithm(Mantid::API::IAlgorithm_sptr algo);

signals:
void batchComplete(bool error);
void batchProgress(double p, const std::string& currentAlg, const std::string& algMsg);

private slots:
void subAlgorithmFinished(bool error);
void subAlgorithmProgress(double p, const std::string& msg);

private:
void startNextAlgo();

AlgorithmRunner *m_algRunner;

std::deque<Mantid::API::IAlgorithm_sptr> m_algorithms;
size_t m_batchSize;

bool m_stopOnFailure;
bool m_isExecuting;

void handleAlgorithmFinish();
void handleAlgorithmProgress(double p, const std::string msg);
void handleAlgorithmError();
};

} // namespace API
Expand Down
136 changes: 136 additions & 0 deletions Code/Mantid/MantidQt/API/src/AbstractAsyncAlgorithmRunner.cpp
@@ -0,0 +1,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.
*
* Emits a signal for the GUI widget
*
* This is called in a separate (non-GUI) thread and so
* CANNOT directly change the gui.
*
* @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
*
* @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.
* Emits a signal for the GUI widget
*
* @param pNf :: notification object
*/
void AbstractAsyncAlgorithmRunner::handleAlgorithmErrorNotification(const Poco::AutoPtr<Algorithm::ErrorNotification>& pNf)
{
UNUSED_ARG(pNf);
handleAlgorithmError();
}

} // namespace Mantid
} // namespace API

0 comments on commit 6692668

Please sign in to comment.