Commit f1d3e7c8 authored by Eike Ziller's avatar Eike Ziller

runextensions: Add convenience method for result handler

Change-Id: Ibe7e62049f165276fdedcd04d8311324f6bc5d19
Reviewed-by: Tobias Hunger's avatarTobias Hunger <tobias.hunger@qt.io>
parent f8736299
......@@ -31,6 +31,7 @@
#include <QCoreApplication>
#include <QFuture>
#include <QFutureInterface>
#include <QFutureWatcher>
#include <QRunnable>
#include <QThread>
#include <QThreadPool>
......@@ -493,4 +494,58 @@ runAsync(QThreadPool *pool, Function &&function, Args&&... args)
std::forward<Args>(args)...);
}
/*!
Adds a handler for when a result is ready.
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
or create a QFutureWatcher already for other reasons.
*/
template <typename R, typename T>
const QFuture<T> &onResultReady(const QFuture<T> &future, R *receiver, void(R::*member)(const T &))
{
auto watcher = new QFutureWatcher<T>();
watcher->setFuture(future);
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, receiver,
[receiver, member, watcher](int index) {
(receiver->*member)(watcher->future().resultAt(index));
});
return future;
}
/*!
Adds a handler for when a result is ready. The guard object determines the lifetime of
the connection.
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
or create a QFutureWatcher already for other reasons.
*/
template <typename T, typename Function>
const QFuture<T> &onResultReady(const QFuture<T> &future, QObject *guard, Function f)
{
auto watcher = new QFutureWatcher<T>();
watcher->setFuture(future);
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, guard, [f, watcher](int index) {
f(watcher->future().resultAt(index));
});
return future;
}
/*!
Adds a handler for when a result is ready.
This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
or create a QFutureWatcher already for other reasons.
*/
template <typename T, typename Function>
const QFuture<T> &onResultReady(const QFuture<T> &future, Function f)
{
auto watcher = new QFutureWatcher<T>();
watcher->setFuture(future);
QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
QObject::connect(watcher, &QFutureWatcherBase::resultReadyAt, [f, watcher](int index) {
f(watcher->future().resultAt(index));
});
return future;
}
} // Utils
......@@ -44,6 +44,7 @@ private slots:
void threadPriority();
void runAsyncNoFutureInterface();
void crefFunction();
void onResultReady();
};
void report3(QFutureInterface<int> &fi)
......@@ -557,6 +558,64 @@ void tst_RunExtensions::crefFunction()
QCOMPARE(value, true);
}
class ObjWithProperty : public QObject
{
Q_OBJECT
public slots:
void setValue(const QString &s)
{
value = s;
}
public:
QString value;
};
void tst_RunExtensions::onResultReady()
{
{ // lambda
QFuture<QString> f = Utils::runAsync([](QFutureInterface<QString> &fi) {
fi.reportResult("Hi");
fi.reportResult("there");
});
int count = 0;
QString res;
Utils::onResultReady(f, [&count, &res](const QString &s) {
++count;
res = s;
});
f.waitForFinished();
QCoreApplication::processEvents();
QCOMPARE(count, 2);
QCOMPARE(res, QString("there"));
}
{ // lambda with guard
QFuture<QString> f = Utils::runAsync([](QFutureInterface<QString> &fi) {
fi.reportResult("Hi");
fi.reportResult("there");
});
int count = 0;
ObjWithProperty obj;
Utils::onResultReady(f, &obj, [&count, &obj](const QString &s) {
++count;
obj.setValue(s);
});
f.waitForFinished();
QCoreApplication::processEvents();
QCOMPARE(count, 2);
QCOMPARE(obj.value, QString("there"));
}
{ // member
QFuture<QString> f = Utils::runAsync([]() { return QString("Hi"); });
ObjWithProperty obj;
Utils::onResultReady(f, &obj, &ObjWithProperty::setValue);
f.waitForFinished();
QCoreApplication::processEvents();
QCOMPARE(obj.value, QString("Hi"));
}
}
QTEST_MAIN(tst_RunExtensions)
#include "tst_runextensions.moc"
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