summaryrefslogtreecommitdiffstats
path: root/async/src
diff options
context:
space:
mode:
Diffstat (limited to 'async/src')
-rw-r--r--async/src/async.h58
1 files changed, 44 insertions, 14 deletions
diff --git a/async/src/async.h b/async/src/async.h
index 1f44f10..386722a 100644
--- a/async/src/async.h
+++ b/async/src/async.h
@@ -31,6 +31,7 @@
31#include <QObject> 31#include <QObject>
32#include <QSharedPointer> 32#include <QSharedPointer>
33 33
34#include <QDebug>
34 35
35/* 36/*
36 * TODO: instead of passing the future objects callbacks could be provided for result reporting (we can still use the future object internally 37 * TODO: instead of passing the future objects callbacks could be provided for result reporting (we can still use the future object internally
@@ -44,6 +45,7 @@ class JobBase;
44 45
45template<typename Out, typename ... In> 46template<typename Out, typename ... In>
46class Job; 47class Job;
48
47template<typename Out, typename ... In> 49template<typename Out, typename ... In>
48using ThenTask = typename detail::identity<std::function<void(In ..., Async::Future<Out>&)>>::type; 50using ThenTask = typename detail::identity<std::function<void(In ..., Async::Future<Out>&)>>::type;
49template<typename Out, typename ... In> 51template<typename Out, typename ... In>
@@ -71,6 +73,9 @@ class ExecutorBase
71 template<typename PrevOut, typename Out, typename ... In> 73 template<typename PrevOut, typename Out, typename ... In>
72 friend class Executor; 74 friend class Executor;
73 75
76 template<typename Out, typename ... In>
77 friend class Async::Job;
78
74public: 79public:
75 virtual ~ExecutorBase(); 80 virtual ~ExecutorBase();
76 virtual void exec() = 0; 81 virtual void exec() = 0;
@@ -178,8 +183,11 @@ private:
178 * void return type, and accept exactly one argument of type @p Async::Future<In>, 183 * void return type, and accept exactly one argument of type @p Async::Future<In>,
179 * where @p In is type of the result. 184 * where @p In is type of the result.
180 */ 185 */
181template<typename Out> 186template<typename Out, typename ... In>
182Job<Out> start(ThenTask<Out> func); 187Job<Out, In ...> start(ThenTask<Out, In ...> func);
188
189template<typename Out, typename ... In>
190Job<Out, In ...> start(SyncThenTask<Out, In ...> func);
183 191
184 192
185/** 193/**
@@ -262,11 +270,11 @@ class Job : public JobBase
262 template<typename OutOther, typename ... InOther> 270 template<typename OutOther, typename ... InOther>
263 friend class Job; 271 friend class Job;
264 272
265 template<typename OutOther> 273 template<typename OutOther, typename ... InOther>
266 friend Job<OutOther> start(Async::ThenTask<OutOther> func); 274 friend Job<OutOther, InOther ...> start(Async::ThenTask<OutOther, InOther ...> func);
267 275
268 template<typename OutOther> 276 template<typename OutOther, typename ... InOther>
269 friend Job<OutOther> start(Async::SyncThenTask<OutOther> func); 277 friend Job<OutOther, InOther ...> start(Async::SyncThenTask<OutOther, InOther ...> func);
270 278
271public: 279public:
272 template<typename OutOther, typename ... InOther> 280 template<typename OutOther, typename ... InOther>
@@ -315,6 +323,27 @@ public:
315 new Private::SyncReduceExecutor<OutOther, InOther>(func, errorFunc, mExecutor))); 323 new Private::SyncReduceExecutor<OutOther, InOther>(func, errorFunc, mExecutor)));
316 } 324 }
317 325
326 template<typename FirstIn>
327 Async::Future<Out> exec(FirstIn in)
328 {
329 // Inject a fake sync executor that will return the initial value
330 Private::ExecutorBasePtr first = mExecutor;
331 while (first->mPrev) {
332 first = first->mPrev;
333 }
334 auto init = new Private::SyncThenExecutor<FirstIn>(
335 [in]() -> FirstIn {
336 return in;
337 },
338 ErrorHandler(), Private::ExecutorBasePtr());
339 first->mPrev = Private::ExecutorBasePtr(init);
340
341 auto result = exec();
342 // Remove the injected executor
343 first->mPrev.reset();
344 return result;
345 }
346
318 Async::Future<Out> exec() 347 Async::Future<Out> exec()
319 { 348 {
320 mExecutor->exec(); 349 mExecutor->exec();
@@ -357,18 +386,18 @@ private:
357 386
358namespace Async { 387namespace Async {
359 388
360template<typename Out> 389template<typename Out, typename ... In>
361Job<Out> start(ThenTask<Out> func) 390Job<Out, In ...> start(ThenTask<Out, In ...> func)
362{ 391{
363 return Job<Out>(Private::ExecutorBasePtr( 392 return Job<Out, In...>(Private::ExecutorBasePtr(
364 new Private::ThenExecutor<Out>(func, ErrorHandler(), Private::ExecutorBasePtr()))); 393 new Private::ThenExecutor<Out, In ...>(func, ErrorHandler(), Private::ExecutorBasePtr())));
365} 394}
366 395
367template<typename Out> 396template<typename Out, typename ... In>
368Job<Out> start(SyncThenTask<Out> func) 397Job<Out, In ...> start(SyncThenTask<Out, In ...> func)
369{ 398{
370 return Job<Out>(Private::ExecutorBasePtr( 399 return Job<Out, In...>(Private::ExecutorBasePtr(
371 new Private::SyncThenExecutor<Out>(func, ErrorHandler(), Private::ExecutorBasePtr()))); 400 new Private::SyncThenExecutor<Out, In ...>(func, ErrorHandler(), Private::ExecutorBasePtr())));
372} 401}
373 402
374template<typename Out> 403template<typename Out>
@@ -443,6 +472,7 @@ void Executor<PrevOut, Out, In ...>::exec()
443 } 472 }
444} 473}
445 474
475
446template<typename Out, typename ... In> 476template<typename Out, typename ... In>
447ThenExecutor<Out, In ...>::ThenExecutor(ThenTask<Out, In ...> then, ErrorHandler error, const ExecutorBasePtr &parent) 477ThenExecutor<Out, In ...>::ThenExecutor(ThenTask<Out, In ...> then, ErrorHandler error, const ExecutorBasePtr &parent)
448 : Executor<typename detail::prevOut<In ...>::type, Out, In ...>(error, parent) 478 : Executor<typename detail::prevOut<In ...>::type, Out, In ...>(error, parent)