diff options
author | Dan Vrátil <dvratil@redhat.com> | 2015-03-30 17:49:26 +0200 |
---|---|---|
committer | Dan Vrátil <dvratil@redhat.com> | 2015-03-30 17:49:28 +0200 |
commit | 8f2fed8d2a1b23a8f318047b6592ad64b6ecbd22 (patch) | |
tree | 6f8d5ea2dc8695dfc6c3c641c2ef044ad5810bd8 /async/src/async.h | |
parent | 1d946c166cc7a4a2556e8bfaab7dc66695b555e1 (diff) | |
download | sink-8f2fed8d2a1b23a8f318047b6592ad64b6ecbd22.tar.gz sink-8f2fed8d2a1b23a8f318047b6592ad64b6ecbd22.zip |
Async: initial support for native chaining of KJobs
It is now possible use KJob-derived jobs with libasync without having to write
lambda wrappers.
auto job = Async::start<ReturnType, MyKJob, MyKJob::result, Args ...)
.then<ReturnType, OtherKJob, OtherKJob::result, PrevKJobReturnType>();
job.exec(arg1, arg2, ...);
The reason for this approach (instead of taking KJob* as an argument is that
we usually want the KJob ctor arguments to depend on result of previous job.
At least in case of Async::start() however it makes sense to support passing
KJob* as an argument (not yet implemented).
In future we should also support custom error handlers.
The KJob integration is build-time optional, but enabled by default (pass
-DWITH_KJOB=FALSE to CMake to disable).
Adds KCoreAddons dependency.
Diffstat (limited to 'async/src/async.h')
-rw-r--r-- | async/src/async.h | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/async/src/async.h b/async/src/async.h index 2be1260..8da3daa 100644 --- a/async/src/async.h +++ b/async/src/async.h | |||
@@ -33,6 +33,11 @@ | |||
33 | 33 | ||
34 | #include <QDebug> | 34 | #include <QDebug> |
35 | 35 | ||
36 | #ifdef WITH_KJOB | ||
37 | #include <KJob> | ||
38 | #endif | ||
39 | |||
40 | |||
36 | /* | 41 | /* |
37 | * TODO: instead of passing the future objects callbacks could be provided for result reporting (we can still use the future object internally | 42 | * TODO: instead of passing the future objects callbacks could be provided for result reporting (we can still use the future object internally |
38 | */ | 43 | */ |
@@ -196,10 +201,15 @@ Job<Out, In ...> start(ThenTask<Out, In ...> func); | |||
196 | template<typename Out, typename ... In> | 201 | template<typename Out, typename ... In> |
197 | Job<Out, In ...> start(SyncThenTask<Out, In ...> func); | 202 | Job<Out, In ...> start(SyncThenTask<Out, In ...> func); |
198 | 203 | ||
204 | #ifdef WITH_KJOB | ||
205 | template<typename ReturnType, typename KJobType, ReturnType (KJobType::*KJobResultMethod)(), typename ... Args> | ||
206 | Job<ReturnType, Args ...> start(); | ||
207 | #endif | ||
208 | |||
199 | 209 | ||
200 | /** | 210 | /** |
201 | * A null job. | 211 | * A null job. |
202 | * | 212 | * |
203 | * An async noop. | 213 | * An async noop. |
204 | * | 214 | * |
205 | */ | 215 | */ |
@@ -283,6 +293,11 @@ class Job : public JobBase | |||
283 | template<typename OutOther, typename ... InOther> | 293 | template<typename OutOther, typename ... InOther> |
284 | friend Job<OutOther, InOther ...> start(Async::SyncThenTask<OutOther, InOther ...> func); | 294 | friend Job<OutOther, InOther ...> start(Async::SyncThenTask<OutOther, InOther ...> func); |
285 | 295 | ||
296 | #ifdef WITH_KJOB | ||
297 | template<typename ReturnType, typename KJobType, ReturnType (KJobType::*KJobResultMethod)(), typename ... Args> | ||
298 | friend Job<ReturnType, Args ...> start(); | ||
299 | #endif | ||
300 | |||
286 | public: | 301 | public: |
287 | template<typename OutOther, typename ... InOther> | 302 | template<typename OutOther, typename ... InOther> |
288 | Job<OutOther, InOther ...> then(ThenTask<OutOther, InOther ...> func, ErrorHandler errorFunc = ErrorHandler()) | 303 | Job<OutOther, InOther ...> then(ThenTask<OutOther, InOther ...> func, ErrorHandler errorFunc = ErrorHandler()) |
@@ -304,6 +319,14 @@ public: | |||
304 | return then<OutOther, InOther ...>(nestedJobWrapper<OutOther, InOther ...>(otherJob), errorFunc); | 319 | return then<OutOther, InOther ...>(nestedJobWrapper<OutOther, InOther ...>(otherJob), errorFunc); |
305 | } | 320 | } |
306 | 321 | ||
322 | #ifdef WITH_KJOB | ||
323 | template<typename ReturnType, typename KJobType, ReturnType (KJobType::*KJobResultMethod)(), typename ... Args> | ||
324 | Job<ReturnType, Args ...> then() | ||
325 | { | ||
326 | return start<ReturnType, KJobType, KJobResultMethod, Args ...>(); | ||
327 | } | ||
328 | #endif | ||
329 | |||
307 | template<typename OutOther, typename InOther> | 330 | template<typename OutOther, typename InOther> |
308 | Job<OutOther, InOther> each(EachTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler()) | 331 | Job<OutOther, InOther> each(EachTask<OutOther, InOther> func, ErrorHandler errorFunc = ErrorHandler()) |
309 | { | 332 | { |
@@ -442,6 +465,28 @@ Job<Out, In ...> start(SyncThenTask<Out, In ...> func) | |||
442 | new Private::SyncThenExecutor<Out, In ...>(func, ErrorHandler(), Private::ExecutorBasePtr()))); | 465 | new Private::SyncThenExecutor<Out, In ...>(func, ErrorHandler(), Private::ExecutorBasePtr()))); |
443 | } | 466 | } |
444 | 467 | ||
468 | #ifdef WITH_KJOB | ||
469 | template<typename ReturnType, typename KJobType, ReturnType (KJobType::*KJobResultMethod)(), typename ... Args> | ||
470 | Job<ReturnType, Args ...> start() | ||
471 | { | ||
472 | return Job<ReturnType, Args ...>(Private::ExecutorBasePtr( | ||
473 | new Private::ThenExecutor<ReturnType, Args ...>([](const Args & ... args, Async::Future<ReturnType> &future) | ||
474 | { | ||
475 | KJobType *job = new KJobType(args ...); | ||
476 | job->connect(job, &KJob::finished, | ||
477 | [&future](KJob *job) { | ||
478 | if (job->error()) { | ||
479 | future.setError(job->error(), job->errorString()); | ||
480 | } else { | ||
481 | future.setValue((static_cast<KJobType*>(job)->*KJobResultMethod)()); | ||
482 | future.setFinished(); | ||
483 | } | ||
484 | }); | ||
485 | job->start(); | ||
486 | }, ErrorHandler(), Private::ExecutorBasePtr()))); | ||
487 | } | ||
488 | #endif | ||
489 | |||
445 | template<typename Out> | 490 | template<typename Out> |
446 | Job<Out> null() | 491 | Job<Out> null() |
447 | { | 492 | { |