summaryrefslogtreecommitdiffstats
path: root/async
diff options
context:
space:
mode:
Diffstat (limited to 'async')
-rw-r--r--async/autotests/asynctest.cpp62
-rw-r--r--async/src/async.h2
-rw-r--r--async/src/future.cpp20
-rw-r--r--async/src/future.h5
4 files changed, 88 insertions, 1 deletions
diff --git a/async/autotests/asynctest.cpp b/async/autotests/asynctest.cpp
index 61ab8bc..7b8d430 100644
--- a/async/autotests/asynctest.cpp
+++ b/async/autotests/asynctest.cpp
@@ -60,6 +60,7 @@ private Q_SLOTS:
60 void testJoinedReduce(); 60 void testJoinedReduce();
61 void testVoidReduce(); 61 void testVoidReduce();
62 62
63 void testProgressReporting();
63 void testErrorHandler(); 64 void testErrorHandler();
64 65
65 void testChainingRunningJob(); 66 void testChainingRunningJob();
@@ -69,6 +70,7 @@ private Q_SLOTS:
69 void testLifetimeWithHandle(); 70 void testLifetimeWithHandle();
70 71
71 void benchmarkSyncThenExecutor(); 72 void benchmarkSyncThenExecutor();
73 void benchmarkAllTests();
72 74
73private: 75private:
74 template<typename T> 76 template<typename T>
@@ -471,6 +473,40 @@ void AsyncTest::testVoidReduce()
471} 473}
472 474
473 475
476void AsyncTest::testProgressReporting()
477{
478 static int progress;
479 progress = 0;
480
481 auto job = Async::start<void>(
482 [](Async::Future<void> &f) {
483 QTimer *timer = new QTimer();
484 connect(timer, &QTimer::timeout,
485 [&f, timer]() {
486 f.setProgress(++progress);
487 if (progress == 100) {
488 timer->stop();
489 timer->deleteLater();
490 f.setFinished();
491 }
492 });
493 timer->start(1);
494 });
495
496 int progressCheck = 0;
497 Async::FutureWatcher<void> watcher;
498 connect(&watcher, &Async::FutureWatcher<void>::futureProgress,
499 [&progressCheck](qreal progress) {
500 progressCheck++;
501 // FIXME: Don't use Q_ASSERT in unit tests
502 Q_ASSERT((int) progress == progressCheck);
503 });
504 watcher.setFuture(job.exec());
505 watcher.future().waitForFinished();
506
507 QVERIFY(watcher.future().isFinished());
508 QCOMPARE(progressCheck, 100);
509}
474 510
475void AsyncTest::testErrorHandler() 511void AsyncTest::testErrorHandler()
476{ 512{
@@ -634,6 +670,32 @@ void AsyncTest::benchmarkSyncThenExecutor()
634 } 670 }
635} 671}
636 672
673void AsyncTest::benchmarkAllTests()
674{
675 QBENCHMARK {
676 testSyncPromises();
677 testAsyncPromises();
678 testAsyncPromises2();
679 testNestedAsync();
680 testStartValue();
681
682 testAsyncThen();
683 testSyncThen();
684 testJoinedThen();
685 testVoidThen();
686
687 testAsyncEach();
688 testSyncEach();
689 testJoinedEach();
690 testVoidEach();
691
692 testAsyncReduce();
693 testSyncReduce();
694 testJoinedReduce();
695 testVoidReduce();
696 }
697}
698
637 699
638 700
639QTEST_MAIN(AsyncTest); 701QTEST_MAIN(AsyncTest);
diff --git a/async/src/async.h b/async/src/async.h
index 6cb3825..c316639 100644
--- a/async/src/async.h
+++ b/async/src/async.h
@@ -56,7 +56,7 @@
56 * valid until the task is complete. To abort a job it has to be killed through the future handle. 56 * valid until the task is complete. To abort a job it has to be killed through the future handle.
57 * TODO: Can we tie the lifetime of the executor to the last available future handle? 57 * TODO: Can we tie the lifetime of the executor to the last available future handle?
58 * 58 *
59 * TODO: Progress reporting through future 59 * TODO: Composed progress reporting
60 * TODO: Possibility to abort a job through future (perhaps optional?) 60 * TODO: Possibility to abort a job through future (perhaps optional?)
61 * TODO: Support for timeout, specified during exec call, after which the error handler gets called with a defined errorCode. 61 * TODO: Support for timeout, specified during exec call, after which the error handler gets called with a defined errorCode.
62 */ 62 */
diff --git a/async/src/future.cpp b/async/src/future.cpp
index 970060b..4f3cd80 100644
--- a/async/src/future.cpp
+++ b/async/src/future.cpp
@@ -102,6 +102,21 @@ QString FutureBase::errorMessage() const
102 return d->errorMessage; 102 return d->errorMessage;
103} 103}
104 104
105void FutureBase::setProgress(int processed, int total)
106{
107 setProgress((qreal) processed / total);
108}
109
110void FutureBase::setProgress(qreal progress)
111{
112 for (auto watcher : d->watchers) {
113 if (watcher) {
114 watcher->futureProgressCallback(progress);
115 }
116 }
117}
118
119
105 120
106void FutureBase::addWatcher(FutureWatcherBase* watcher) 121void FutureBase::addWatcher(FutureWatcherBase* watcher)
107{ 122{
@@ -128,6 +143,11 @@ void FutureWatcherBase::futureReadyCallback()
128 Q_EMIT futureReady(); 143 Q_EMIT futureReady();
129} 144}
130 145
146void FutureWatcherBase::futureProgressCallback(qreal progress)
147{
148 Q_EMIT futureProgress(progress);
149}
150
131void FutureWatcherBase::setFutureImpl(const FutureBase &future) 151void FutureWatcherBase::setFutureImpl(const FutureBase &future)
132{ 152{
133 d->future = future; 153 d->future = future;
diff --git a/async/src/future.h b/async/src/future.h
index bc18f00..32c1015 100644
--- a/async/src/future.h
+++ b/async/src/future.h
@@ -54,6 +54,9 @@ public:
54 int errorCode() const; 54 int errorCode() const;
55 QString errorMessage() const; 55 QString errorMessage() const;
56 56
57 void setProgress(qreal progress);
58 void setProgress(int processed, int total);
59
57protected: 60protected:
58 class PrivateBase : public QSharedData 61 class PrivateBase : public QSharedData
59 { 62 {
@@ -197,12 +200,14 @@ class FutureWatcherBase : public QObject
197 200
198Q_SIGNALS: 201Q_SIGNALS:
199 void futureReady(); 202 void futureReady();
203 void futureProgress(qreal progress);
200 204
201protected: 205protected:
202 FutureWatcherBase(QObject *parent = nullptr); 206 FutureWatcherBase(QObject *parent = nullptr);
203 virtual ~FutureWatcherBase(); 207 virtual ~FutureWatcherBase();
204 208
205 void futureReadyCallback(); 209 void futureReadyCallback();
210 void futureProgressCallback(qreal progress);
206 211
207 void setFutureImpl(const Async::FutureBase &future); 212 void setFutureImpl(const Async::FutureBase &future);
208 213