Commit c9501866 authored by Clinton Stimpson's avatar Clinton Stimpson

parent 7f800488
......@@ -178,6 +178,8 @@ void pqEventDispatcher::stopPlayback()
SIGNAL(readyPlayNextEvent()));
#endif
this->Implementation->Source->stop();
this->Implementation->Source = 0;
this->Implementation->Player = 0;
......
......@@ -60,6 +60,9 @@ public:
Returns true for valid file, false for invalid file */
virtual void setContent(const QString& filename) = 0;
/** tell the source to stop feeding in events */
virtual void stop() {}
};
#endif // !_pqEventSource_h
......
......@@ -45,7 +45,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QFile>
#include <QtDebug>
#include <QMutex>
#include <QWaitCondition>
#include <QCoreApplication>
#include <QEvent>
#include <QStringList>
......@@ -62,7 +61,6 @@ static pqPythonEventSource* Instance = NULL;
static QString PropertyObject;
static QString PropertyResult;
static QString PropertyValue;
static QWaitCondition WaitResults;
static QStringList ObjectList;
......@@ -84,7 +82,11 @@ QtTesting_playCommand(PyObject* /*self*/, PyObject* args)
if(Instance)
{
Instance->postNextEvent(object, command, arguments);
if(!Instance->postNextEvent(object, command, arguments))
{
PyErr_SetString(PyExc_AssertionError, "error processing event");
return NULL;
}
}
else
{
......@@ -117,7 +119,11 @@ QtTesting_getProperty(PyObject* /*self*/, PyObject* args)
QMutex mut;
mut.lock();
QMetaObject::invokeMethod(Instance, "threadGetProperty", Qt::QueuedConnection);
WaitResults.wait(&mut);
if(!Instance->waitForGUI(mut))
{
PyErr_SetString(PyExc_ValueError, "error getting property");
return NULL;
}
}
else if(QThread::currentThread() == QApplication::instance()->thread())
{
......@@ -164,7 +170,11 @@ QtTesting_setProperty(PyObject* /*self*/, PyObject* args)
QMutex mut;
mut.lock();
QMetaObject::invokeMethod(Instance, "threadSetProperty", Qt::QueuedConnection);
WaitResults.wait(&mut);
if(!Instance->waitForGUI(mut))
{
PyErr_SetString(PyExc_ValueError, "error setting property");
return NULL;
}
}
else if(QThread::currentThread() == QApplication::instance()->thread())
{
......@@ -242,7 +252,11 @@ QtTesting_getChildren(PyObject* /*self*/, PyObject* args)
QMutex mut;
mut.lock();
QMetaObject::invokeMethod(Instance, "threadGetChildren", Qt::QueuedConnection);
WaitResults.wait(&mut);
if(!Instance->waitForGUI(mut))
{
PyErr_SetString(PyExc_ValueError, "error getting children");
return NULL;
}
}
else if(QThread::currentThread() == QApplication::instance()->thread())
{
......@@ -374,7 +388,7 @@ QString pqPythonEventSource::getProperty(QString& object, const QString& prop)
void pqPythonEventSource::threadGetProperty()
{
PropertyResult = this->getProperty(PropertyObject, PropertyResult);
WaitResults.wakeAll();
this->guiAcknowledge();
}
......@@ -402,7 +416,7 @@ void pqPythonEventSource::setProperty(QString& object, QString& prop,
void pqPythonEventSource::threadSetProperty()
{
this->setProperty(PropertyObject, PropertyResult, PropertyValue);
WaitResults.wakeAll();
this->guiAcknowledge();
}
......@@ -432,7 +446,7 @@ QStringList pqPythonEventSource::getChildren(QString& object)
void pqPythonEventSource::threadGetChildren()
{
ObjectList = this->getChildren(PropertyObject);
WaitResults.wakeAll();
this->guiAcknowledge();
}
void pqPythonEventSource::run()
......
......@@ -41,32 +41,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QEvent>
#include <QApplication>
namespace
{
class pqPlayCommandEvent : public QEvent
{
public:
pqPlayCommandEvent(const QString& o, const QString& c, const QString& a)
: QEvent(QEvent::User),
Object(o),
Command(c),
Arguments(a)
{
}
QString Object;
QString Command;
QString Arguments;
};
}
class pqThreadedEventSource::pqInternal : public QThread
{
friend class pqThreadedEventSource;
public:
pqInternal(pqThreadedEventSource& source)
: Source(source),
ShouldStop(0),
GotEvent(false)
{
}
......@@ -81,6 +62,7 @@ public:
QWaitCondition WaitCondition;
QEventLoop Loop;
QAtomic ShouldStop;
bool GotEvent;
QString CurrentObject;
QString CurrentCommand;
......@@ -117,7 +99,7 @@ int pqThreadedEventSource::getNextEvent(
command = this->Internal->CurrentCommand;
arguments = this->Internal->CurrentArgument;
this->Internal->GotEvent = false;
this->Internal->WaitCondition.wakeAll();
this->guiAcknowledge();
if(object == QString::null)
{
......@@ -144,7 +126,7 @@ void pqThreadedEventSource::relayEvent(QString object, QString command, QString
}
void pqThreadedEventSource::postNextEvent(const QString& object,
bool pqThreadedEventSource::postNextEvent(const QString& object,
const QString& command,
const QString& argument)
{
......@@ -155,8 +137,7 @@ void pqThreadedEventSource::postNextEvent(const QString& object,
Q_ARG(QString, command),
Q_ARG(QString, argument));
// wait for the GUI thread to take the event and wake us up
this->Internal->WaitCondition.wait(&mut);
return this->waitForGUI(mut);
}
void pqThreadedEventSource::start()
......@@ -164,6 +145,27 @@ void pqThreadedEventSource::start()
this->Internal->start();
}
void pqThreadedEventSource::stop()
{
this->Internal->ShouldStop = 1;
this->guiAcknowledge();
}
bool pqThreadedEventSource::waitForGUI(QMutex& m)
{
if(this->Internal->ShouldStop)
{
return false;
}
this->Internal->WaitCondition.wait(&m);
return !this->Internal->ShouldStop;
}
void pqThreadedEventSource::guiAcknowledge()
{
this->Internal->WaitCondition.wakeAll();
}
void pqThreadedEventSource::done(int success)
{
if(success == 0)
......
......@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqEventSource.h"
class QString;
class QMutex;
/// Abstract interface for objects that can supply high-level testing events
/// on a separte thread. This class is derived from, and run() is
......@@ -59,11 +60,27 @@ public:
QString& arguments);
/** The testing thread may post an event for the GUI to process.
This function blocks until there are no previously queued events to play. */
void postNextEvent(const QString& object,
This function blocks until there are no previously queued
events to play.
If the event plays successfully, true is returned. */
bool postNextEvent(const QString& object,
const QString& command,
const QString& argument);
/** tell this source to stop */
void stop();
/** Wait for the GUI thread to acknowledge an event.
A previously locked mutex must be passed in.
For use by the testing thread.
If return value is false, an error occurred and
the testing thread should terminate. */
bool waitForGUI(QMutex& m);
/** Give the testing thread an acknowledgement.
For use by the GUI thread */
void guiAcknowledge();
private slots:
void relayEvent(QString object, QString command, QString arguments);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment