From adc6a443776820b5ae36c982baf92b1d29bbaa4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Sun, 8 Feb 2015 12:02:04 +0100 Subject: Async: introduce sync executors Sync executors don't pass Async::Future into the user-provided tasks, but instead work with return values of the task methods, wrapping them into the Async::Future internally. Sync tasks are of course possible since forever, but not the API for those tasks is much cleaner, for users don't have to deal with "future" in synchronous tasks, for instance when synchronously processing results of an async task before passing the data to another async task. --- async/autotests/asynctest.cpp | 138 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 11 deletions(-) (limited to 'async/autotests') diff --git a/async/autotests/asynctest.cpp b/async/autotests/asynctest.cpp index 9240d28..4ebe65e 100644 --- a/async/autotests/asynctest.cpp +++ b/async/autotests/asynctest.cpp @@ -42,9 +42,14 @@ private Q_SLOTS: void testAsyncPromises(); void testAsyncPromises2(); void testNestedAsync(); + void testAsyncThen(); + void testSyncThen(); + void testAsyncEach(); void testSyncEach(); + void testAsyncReduce(); void testSyncReduce(); void testErrorHandler(); + }; void AsyncTest::testSyncPromises() @@ -155,17 +160,92 @@ void AsyncTest::testNestedAsync() QTRY_VERIFY(done); } -void AsyncTest::testSyncEach() +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); + }); + + auto future = job.exec(); + future.waitForFinished(); + + QVERIFY(future.isFinished()); + QCOMPARE(future.value(), 42); +} + + +void AsyncTest::testSyncThen() +{ + auto job = Async::start( + []() -> int { + return 42; + }).then( + [](int in) -> int { + return in * 2; + }); + + auto future = job.exec(); + QVERIFY(future.isFinished()); + QCOMPARE(future.value(), 84); +} + +void AsyncTest::testAsyncEach() { auto job = Async::start>( [](Async::Future> &future) { - future.setValue(QList{ 1, 2, 3, 4 }); - future.setFinished(); + 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); }) .each, int>( [](const int &v, Async::Future> &future) { - future.setValue(QList{ v + 1 }); - future.setFinished(); + 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); + }); + + auto future = job.exec(); + future.waitForFinished(); + + const QList expected({ 2, 3, 4, 5 }); + QVERIFY(future.isFinished()); + QCOMPARE(future.value(), expected); +} + + +void AsyncTest::testSyncEach() +{ + auto job = Async::start>( + []() -> QList { + return { 1, 2, 3, 4 }; + }) + .each, int>( + [](const int &v) -> QList { + return { v + 1 }; }); Async::Future> future = job.exec(); @@ -175,19 +255,55 @@ void AsyncTest::testSyncEach() QCOMPARE(future.value(), expected); } -void AsyncTest::testSyncReduce() +void AsyncTest::testAsyncReduce() { auto job = Async::start>( [](Async::Future> &future) { - future.setValue(QList{ 1, 2, 3, 4 }); - future.setFinished(); + 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); }) .reduce>( [](const QList &list, Async::Future &future) { + QTimer *timer = new QTimer(); + QObject::connect(timer, &QTimer::timeout, + [list, &future]() { + int sum = 0; + for (int i : list) sum += i; + future.setValue(sum); + future.setFinished(); + }); + QObject::connect(timer, &QTimer::timeout, + timer, &QObject::deleteLater); + timer->setSingleShot(true); + timer->start(0); + }); + + Async::Future future = job.exec(); + future.waitForFinished(); + + QVERIFY(future.isFinished()); + QCOMPARE(future.value(), 10); +} + +void AsyncTest::testSyncReduce() +{ + auto job = Async::start>( + []() -> QList { + return { 1, 2, 3, 4 }; + }) + .reduce>( + [](const QList &list) -> int { int sum = 0; for (int i : list) sum += i; - future.setValue(sum); - future.setFinished(); + return sum; }); Async::Future future = job.exec(); @@ -213,7 +329,7 @@ void AsyncTest::testErrorHandler() ); auto future = job.exec(); future.waitForFinished(); - QVERIFY(error == 1); + QCOMPARE(error, 1); QVERIFY(future.isFinished()); } -- cgit v1.2.3