From 8e6f41f851ae058dea63fbc9b9f523ec9fd1a4fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Fri, 20 Feb 2015 13:58:03 +0100 Subject: Async: allow appending existing Job objects to the Job chain Now it's possible to do something like Job job = createSomeJob(); auto main = Async::start(....).then(job); Previously the 'job' would have to be wrapped in a ThenTask-like lambda (which is what we still do internally), but with this new syntax it's possible to append another job chain to existing chain easilly. This syntax is available for all task types. --- async/autotests/asynctest.cpp | 201 +++++++++++++++++++++++++++--------------- 1 file changed, 130 insertions(+), 71 deletions(-) (limited to 'async/autotests') diff --git a/async/autotests/asynctest.cpp b/async/autotests/asynctest.cpp index ed550ca..73026bb 100644 --- a/async/autotests/asynctest.cpp +++ b/async/autotests/asynctest.cpp @@ -47,12 +47,46 @@ private Q_SLOTS: void testAsyncThen(); void testSyncThen(); + void testJoinedThen(); + void testAsyncEach(); void testSyncEach(); + void testJoinedEach(); + void testAsyncReduce(); void testSyncReduce(); + void testJoinedReduce(); + void testErrorHandler(); + void benchmarkSyncThenExecutor(); + +private: + template + class AsyncSimulator { + public: + AsyncSimulator(Async::Future &future, const T &result) + : mFuture(future) + , mResult(result) + { + QObject::connect(&mTimer, &QTimer::timeout, + [this]() { + mFuture.setValue(mResult); + mFuture.setFinished(); + }); + QObject::connect(&mTimer, &QTimer::timeout, + [this]() { + delete this; + }); + mTimer.setSingleShot(true); + mTimer.start(200); + } + + private: + Async::Future mFuture; + T mResult; + QTimer mTimer; + }; }; @@ -86,16 +120,7 @@ void AsyncTest::testAsyncPromises() { auto job = Async::start( [](Async::Future &future) { - QTimer *timer = new QTimer(); - QObject::connect(timer, &QTimer::timeout, - [&]() { - future.setValue(42); - future.setFinished(); - }); - QObject::connect(timer, &QTimer::timeout, - timer, &QObject::deleteLater); - timer->setSingleShot(true); - timer->start(200); + new AsyncSimulator(future, 42); }); Async::Future future = job.exec(); @@ -110,16 +135,7 @@ void AsyncTest::testAsyncPromises2() auto job = Async::start( [](Async::Future &future) { - QTimer *timer = new QTimer(); - QObject::connect(timer, &QTimer::timeout, - [&]() { - future.setValue(42); - future.setFinished(); - }); - QObject::connect(timer, &QTimer::timeout, - timer, &QObject::deleteLater); - timer->setSingleShot(true); - timer->start(200); + new AsyncSimulator(future, 42); } ).then([&done](int result, Async::Future &future) { done = true; @@ -139,16 +155,7 @@ void AsyncTest::testNestedAsync() auto job = Async::start( [](Async::Future &future) { auto innerJob = Async::start([](Async::Future &innerFuture) { - QTimer *timer = new QTimer(); - QObject::connect(timer, &QTimer::timeout, - [&]() { - innerFuture.setValue(42); - innerFuture.setFinished(); - }); - QObject::connect(timer, &QTimer::timeout, - timer, &QObject::deleteLater); - timer->setSingleShot(true); - timer->start(0); + new AsyncSimulator(innerFuture, 42); }).then([&future](Async::Future &innerThenFuture) { future.setFinished(); innerThenFuture.setFinished(); @@ -186,16 +193,7 @@ void AsyncTest::testAsyncThen() { auto job = Async::start( [](Async::Future &future) { - QTimer *timer = new QTimer; - QObject::connect(timer, &QTimer::timeout, - [&]() { - future.setValue(42); - future.setFinished(); - }); - QObject::connect(timer, &QTimer::timeout, - timer, &QObject::deleteLater); - timer->setSingleShot(true); - timer->start(0); + new AsyncSimulator(future, 42); }); auto future = job.exec(); @@ -221,33 +219,37 @@ void AsyncTest::testSyncThen() QCOMPARE(future.value(), 84); } +void AsyncTest::testJoinedThen() +{ + auto job1 = Async::start( + [](int in, Async::Future &future) { + new AsyncSimulator(future, in * 2); + }); + + auto job2 = Async::start( + [](Async::Future &future) { + new AsyncSimulator(future, 42); + }) + .then(job1); + + auto future = job2.exec(); + future.waitForFinished(); + + QVERIFY(future.isFinished()); + QCOMPARE(future.value(), 84); +} + + + void AsyncTest::testAsyncEach() { auto job = Async::start>( [](Async::Future> &future) { - QTimer *timer = new QTimer; - QObject::connect(timer, &QTimer::timeout, - [&future]() { - future.setValue({ 1, 2, 3, 4 }); - future.setFinished(); - }); - QObject::connect(timer, &QTimer::timeout, - timer, &QObject::deleteLater); - timer->setSingleShot(true); - timer->start(0); + new AsyncSimulator>(future, { 1, 2, 3, 4 }); }) .each, int>( [](const int &v, Async::Future> &future) { - QTimer *timer = new QTimer; - QObject::connect(timer, &QTimer::timeout, - [v, &future]() { - future.setValue({ v + 1 }); - future.setFinished(); - }); - QObject::connect(timer, &QTimer::timeout, - timer, &QObject::deleteLater); - timer->setSingleShot(true); - timer->start(0); + new AsyncSimulator>(future, { v + 1 }); }); auto future = job.exec(); @@ -258,7 +260,6 @@ void AsyncTest::testAsyncEach() QCOMPARE(future.value(), expected); } - void AsyncTest::testSyncEach() { auto job = Async::start>( @@ -277,20 +278,35 @@ void AsyncTest::testSyncEach() QCOMPARE(future.value(), expected); } +void AsyncTest::testJoinedEach() +{ + auto job1 = Async::start, int>( + [](int v, Async::Future> &future) { + new AsyncSimulator>(future, { v * 2 }); + }); + + auto job = Async::start>( + []() -> QList { + return { 1, 2, 3, 4 }; + }) + .each(job1); + + auto future = job.exec(); + future.waitForFinished(); + + const QList expected({ 2, 4, 6, 8 }); + QVERIFY(future.isFinished()); + QCOMPARE(future.value(), expected); +} + + + + void AsyncTest::testAsyncReduce() { auto job = Async::start>( [](Async::Future> &future) { - QTimer *timer = new QTimer(); - QObject::connect(timer, &QTimer::timeout, - [&future]() { - future.setValue({ 1, 2, 3, 4 }); - future.setFinished(); - }); - QObject::connect(timer, &QTimer::timeout, - timer, &QObject::deleteLater); - timer->setSingleShot(true); - timer->start(0); + new AsyncSimulator>(future, { 1, 2, 3, 4 }); }) .reduce>( [](const QList &list, Async::Future &future) { @@ -334,6 +350,32 @@ void AsyncTest::testSyncReduce() QCOMPARE(future.value(), 10); } + +void AsyncTest::testJoinedReduce() +{ + auto job1 = Async::start>( + [](const QList &list, Async::Future &future) { + int sum = 0; + for (int i : list) sum += i; + new AsyncSimulator(future, sum); + }); + + auto job = Async::start>( + []() -> QList { + return { 1, 2, 3, 4 }; + }) + .reduce(job1); + + auto future = job.exec(); + future.waitForFinished(); + + QVERIFY(future.isFinished()); + QCOMPARE(future.value(), 10); +} + + + + void AsyncTest::testErrorHandler() { int error = 0; @@ -356,6 +398,23 @@ void AsyncTest::testErrorHandler() } + + + +void AsyncTest::benchmarkSyncThenExecutor() +{ + auto job = Async::start( + []() -> int { + return 0; + }); + + QBENCHMARK { + job.exec(); + } +} + + + QTEST_MAIN(AsyncTest); #include "asynctest.moc" -- cgit v1.2.3