summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--async/autotests/asynctest.cpp19
-rw-r--r--async/src/async.cpp40
-rw-r--r--async/src/async.h40
3 files changed, 71 insertions, 28 deletions
diff --git a/async/autotests/asynctest.cpp b/async/autotests/asynctest.cpp
index a387dd6..78a834e 100644
--- a/async/autotests/asynctest.cpp
+++ b/async/autotests/asynctest.cpp
@@ -69,6 +69,7 @@ private Q_SLOTS:
69 void testLifetimeWithHandle(); 69 void testLifetimeWithHandle();
70 70
71 void testWhile(); 71 void testWhile();
72 void testWhileWithoutCondition();
72 73
73 void benchmarkSyncThenExecutor(); 74 void benchmarkSyncThenExecutor();
74 75
@@ -385,7 +386,7 @@ void AsyncTest::testWhile()
385 QList<int> processed; 386 QList<int> processed;
386 QList<int> list({1, 2, 3, 4}); 387 QList<int> list({1, 2, 3, 4});
387 auto it = QSharedPointer<QListIterator<int> >::create(list); 388 auto it = QSharedPointer<QListIterator<int> >::create(list);
388 Async::dowhile<void>( 389 Async::dowhile(
389 [it]() -> bool { return it->hasNext(); }, 390 [it]() -> bool { return it->hasNext(); },
390 [it, &processed](Async::Future<void> future) { 391 [it, &processed](Async::Future<void> future) {
391 auto value = it->next(); 392 auto value = it->next();
@@ -396,6 +397,22 @@ void AsyncTest::testWhile()
396 QCOMPARE(processed, list); 397 QCOMPARE(processed, list);
397} 398}
398 399
400void AsyncTest::testWhileWithoutCondition()
401{
402
403 QList<int> processed;
404 QList<int> list({1, 2, 3, 4});
405 auto it = QSharedPointer<QListIterator<int> >::create(list);
406 Async::dowhile(
407 [it, &processed](Async::Future<bool> future) {
408 auto value = it->next();
409 processed << value;
410 future.setValue(it->hasNext());
411 future.setFinished();
412 }
413 ).exec().waitForFinished();
414 QCOMPARE(processed, list);
415}
399 416
400 417
401 418
diff --git a/async/src/async.cpp b/async/src/async.cpp
index 6eefd1b..20ba4e6 100644
--- a/async/src/async.cpp
+++ b/async/src/async.cpp
@@ -47,3 +47,43 @@ JobBase::~JobBase()
47{ 47{
48} 48}
49 49
50static void asyncWhile(const std::function<void(std::function<void(bool)>)> &body, const std::function<void()> &completionHandler) {
51 body([body, completionHandler](bool complete) {
52 if (complete) {
53 completionHandler();
54 } else {
55 asyncWhile(body, completionHandler);
56 }
57 });
58}
59
60Job<void> Async::dowhile(Condition condition, ThenTask<void> body)
61{
62 return Async::start<void>([body, condition](Async::Future<void> &future) {
63 asyncWhile([condition, body](std::function<void(bool)> whileCallback) {
64 Async::start<void>(body).then<void>([whileCallback, condition]() {
65 whileCallback(!condition());
66 }).exec();
67 },
68 [&future]() { //while complete
69 future.setFinished();
70 });
71 });
72}
73
74Job<void> Async::dowhile(ThenTask<bool> body)
75{
76 return Async::start<void>([body](Async::Future<void> &future) {
77 asyncWhile([body](std::function<void(bool)> whileCallback) {
78 Async::start<bool>(body).then<bool, bool>([whileCallback](bool result) {
79 whileCallback(!result);
80 //FIXME this return value is only required because .then<bool, void> doesn't work
81 return true;
82 }).exec();
83 },
84 [&future]() { //while complete
85 future.setFinished();
86 });
87 });
88}
89
diff --git a/async/src/async.h b/async/src/async.h
index 0d1d81e..57879a7 100644
--- a/async/src/async.h
+++ b/async/src/async.h
@@ -227,8 +227,19 @@ template<typename ReturnType, typename KJobType, ReturnType (KJobType::*KJobResu
227Job<ReturnType, Args ...> start(); 227Job<ReturnType, Args ...> start();
228#endif 228#endif
229 229
230template<typename Out> 230/**
231Job<Out> dowhile(Condition condition, ThenTask<void> func); 231 * Async while loop.
232 *
233 * The loop continues while @param condition returns true.
234 */
235Job<void> dowhile(Condition condition, ThenTask<void> func);
236
237/**
238 * Async while loop.
239 *
240 * Loop continues while body returns true.
241 */
242Job<void> dowhile(ThenTask<bool> body);
232 243
233 244
234/** 245/**
@@ -249,7 +260,6 @@ Job<Out> null();
249template<typename Out> 260template<typename Out>
250Job<Out> error(int errorCode = 1, const QString &errorMessage = QString()); 261Job<Out> error(int errorCode = 1, const QString &errorMessage = QString());
251 262
252
253class JobBase 263class JobBase
254{ 264{
255 template<typename Out, typename ... In> 265 template<typename Out, typename ... In>
@@ -511,30 +521,6 @@ Job<ReturnType, Args ...> start()
511} 521}
512#endif 522#endif
513 523
514static void asyncWhile(const std::function<void(std::function<void(bool)>)> &body, const std::function<void()> &completionHandler) {
515 body([body, completionHandler](bool complete) {
516 if (complete) {
517 completionHandler();
518 } else {
519 asyncWhile(body, completionHandler);
520 }
521 });
522}
523 }
524template<typename Out>
525Job<Out> dowhile(Condition condition, ThenTask<void> body)
526{
527 return Async::start<void>([body, condition](Async::Future<void> &future) {
528 asyncWhile([condition, body](std::function<void(bool)> whileCallback) {
529 Async::start<void>(body).then<void>([whileCallback, condition]() {
530 whileCallback(!condition());
531 }).exec();
532 },
533 [&future]() { //while complete
534 future.setFinished();
535 });
536 });
537}
538 524
539template<typename Out> 525template<typename Out>
540Job<Out> null() 526Job<Out> null()