forked from qt-creator/qt-creator
runextensions: Add convenience method for result handler
Change-Id: Ibe7e62049f165276fdedcd04d8311324f6bc5d19 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -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"
|
||||
|
Reference in New Issue
Block a user