diff options
author | Dan Vrátil <dvratil@redhat.com> | 2015-02-20 13:58:03 +0100 |
---|---|---|
committer | Dan Vrátil <dvratil@redhat.com> | 2015-02-20 14:00:49 +0100 |
commit | 8e6f41f851ae058dea63fbc9b9f523ec9fd1a4fb (patch) | |
tree | cbe403f4aaa9498389ab0ddba6af611b99dac98c /async/src | |
parent | 1da08ebfe267313015c201fd1106f891af554e14 (diff) | |
download | sink-8e6f41f851ae058dea63fbc9b9f523ec9fd1a4fb.tar.gz sink-8e6f41f851ae058dea63fbc9b9f523ec9fd1a4fb.zip |
Async: allow appending existing Job objects to the Job chain
Now it's possible to do something like
Job<int, int> job = createSomeJob();
auto main = Async::start<int>(....).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.
Diffstat (limited to 'async/src')
-rw-r--r-- | async/src/async.h | 35 | ||||
-rw-r--r-- | async/src/async_impl.h | 15 |
2 files changed, 50 insertions, 0 deletions
diff --git a/async/src/async.h b/async/src/async.h index 386722a..d21caf8 100644 --- a/async/src/async.h +++ b/async/src/async.h | |||
@@ -291,6 +291,12 @@ public: | |||
291 | new Private::SyncThenExecutor<OutOther, InOther ...>(func, errorFunc, mExecutor))); | 291 | new Private::SyncThenExecutor<OutOther, InOther ...>(func, errorFunc, mExecutor))); |
292 | } | 292 | } |
293 | 293 | ||
294 | template<typename OutOther, typename ... InOther> | ||
295 | Job<OutOther, InOther ...> then(Job<OutOther, InOther ...> otherJob, ErrorHandler errorFunc = ErrorHandler()) | ||
296 | { | ||
297 | return then<OutOther, InOther ...>(nestedJobWrapper<OutOther, InOther ...>(otherJob), errorFunc); | ||
298 | } | ||
299 | |||
294 | template<typename OutOther, typename InOther> | 300 | template<typename OutOther, typename InOther> |
295 | Job<OutOther, InOther> each(EachTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler()) | 301 | Job<OutOther, InOther> each(EachTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler()) |
296 | { | 302 | { |
@@ -308,6 +314,13 @@ public: | |||
308 | } | 314 | } |
309 | 315 | ||
310 | template<typename OutOther, typename InOther> | 316 | template<typename OutOther, typename InOther> |
317 | Job<OutOther, InOther> each(Job<OutOther, InOther> otherJob, ErrorHandler errorFunc = ErrorHandler()) | ||
318 | { | ||
319 | eachInvariants<OutOther>(); | ||
320 | return each<OutOther, InOther>(nestedJobWrapper<OutOther, InOther>(otherJob), errorFunc); | ||
321 | } | ||
322 | |||
323 | template<typename OutOther, typename InOther> | ||
311 | Job<OutOther, InOther> reduce(ReduceTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler()) | 324 | Job<OutOther, InOther> reduce(ReduceTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler()) |
312 | { | 325 | { |
313 | reduceInvariants<InOther>(); | 326 | reduceInvariants<InOther>(); |
@@ -323,6 +336,12 @@ public: | |||
323 | new Private::SyncReduceExecutor<OutOther, InOther>(func, errorFunc, mExecutor))); | 336 | new Private::SyncReduceExecutor<OutOther, InOther>(func, errorFunc, mExecutor))); |
324 | } | 337 | } |
325 | 338 | ||
339 | template<typename OutOther, typename InOther> | ||
340 | Job<OutOther, InOther> reduce(Job<OutOther, InOther> otherJob, ErrorHandler errorFunc = ErrorHandler()) | ||
341 | { | ||
342 | return reduce<OutOther, InOther>(nestedJobWrapper<OutOther, InOther>(otherJob), errorFunc); | ||
343 | } | ||
344 | |||
326 | template<typename FirstIn> | 345 | template<typename FirstIn> |
327 | Async::Future<Out> exec(FirstIn in) | 346 | Async::Future<Out> exec(FirstIn in) |
328 | { | 347 | { |
@@ -377,6 +396,22 @@ private: | |||
377 | static_assert(std::is_same<typename Out::value_type, typename InOther::value_type>::value, | 396 | static_assert(std::is_same<typename Out::value_type, typename InOther::value_type>::value, |
378 | "The return type of previous task must be compatible with input type of this task"); | 397 | "The return type of previous task must be compatible with input type of this task"); |
379 | } | 398 | } |
399 | |||
400 | template<typename OutOther, typename ... InOther> | ||
401 | inline std::function<void(InOther ..., Async::Future<OutOther>&)> nestedJobWrapper(Job<OutOther, InOther ...> otherJob) { | ||
402 | return [otherJob](InOther ... in, Async::Future<OutOther> &future) { | ||
403 | // copy by value is const | ||
404 | auto job = otherJob; | ||
405 | FutureWatcher<OutOther> *watcher = new FutureWatcher<OutOther>(); | ||
406 | QObject::connect(watcher, &FutureWatcherBase::futureReady, | ||
407 | [watcher, &future]() { | ||
408 | Async::detail::copyFutureValue(watcher->future(), future); | ||
409 | future.setFinished(); | ||
410 | watcher->deleteLater(); | ||
411 | }); | ||
412 | watcher->setFuture(job.exec(in ...)); | ||
413 | }; | ||
414 | } | ||
380 | }; | 415 | }; |
381 | 416 | ||
382 | } // namespace Async | 417 | } // namespace Async |
diff --git a/async/src/async_impl.h b/async/src/async_impl.h index 58f6ced..eccbc9b 100644 --- a/async/src/async_impl.h +++ b/async/src/async_impl.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #define ASYNC_IMPL_H | 19 | #define ASYNC_IMPL_H |
20 | 20 | ||
21 | #include "async.h" | 21 | #include "async.h" |
22 | #include <type_traits> | ||
22 | 23 | ||
23 | namespace Async { | 24 | namespace Async { |
24 | 25 | ||
@@ -45,6 +46,20 @@ struct prevOut { | |||
45 | using type = typename std::tuple_element<0, std::tuple<T ..., void>>::type; | 46 | using type = typename std::tuple_element<0, std::tuple<T ..., void>>::type; |
46 | }; | 47 | }; |
47 | 48 | ||
49 | template<typename T> | ||
50 | inline typename std::enable_if<!std::is_void<T>::value, void>::type | ||
51 | copyFutureValue(const Async::Future<T> &in, Async::Future<T> &out) | ||
52 | { | ||
53 | out.setValue(in.value()); | ||
54 | } | ||
55 | |||
56 | template<typename T> | ||
57 | inline typename std::enable_if<std::is_void<T>::value, void>::type | ||
58 | copyFutureValue(const Async::Future<T> &in, Async::Future<T> &out) | ||
59 | { | ||
60 | // noop | ||
61 | } | ||
62 | |||
48 | } // namespace Detail | 63 | } // namespace Detail |
49 | 64 | ||
50 | } // namespace Async | 65 | } // namespace Async |