diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-01-19 19:22:16 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-01-19 19:22:16 +0100 |
commit | 65e5a6ac8848750e94e35ec65ac37d0d4a8638cd (patch) | |
tree | cf353e8364e40ce5d803f032a22788ccf5d76a75 /async/src/async.h | |
parent | f4929574125def1ef006f8fd65c529971d164959 (diff) | |
download | sink-65e5a6ac8848750e94e35ec65ac37d0d4a8638cd.tar.gz sink-65e5a6ac8848750e94e35ec65ac37d0d4a8638cd.zip |
Async: Error continuation.
Diffstat (limited to 'async/src/async.h')
-rw-r--r-- | async/src/async.h | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/async/src/async.h b/async/src/async.h index 8fee0bc..e4b06a9 100644 --- a/async/src/async.h +++ b/async/src/async.h | |||
@@ -47,6 +47,7 @@ template<typename Out, typename In> | |||
47 | using EachTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type; | 47 | using EachTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type; |
48 | template<typename Out, typename In> | 48 | template<typename Out, typename In> |
49 | using ReduceTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type; | 49 | using ReduceTask = typename detail::identity<std::function<void(In, Async::Future<Out>&)>>::type; |
50 | using ErrorHandler = std::function<void(int, const QString &)>; | ||
50 | 51 | ||
51 | namespace Private | 52 | namespace Private |
52 | { | 53 | { |
@@ -93,6 +94,7 @@ protected: | |||
93 | void exec(); | 94 | void exec(); |
94 | 95 | ||
95 | std::function<void(const In& ..., Async::Future<Out> &)> mFunc; | 96 | std::function<void(const In& ..., Async::Future<Out> &)> mFunc; |
97 | std::function<void(int, const QString &)> mErrorFunc; | ||
96 | Async::Future<PrevOut> *mPrevFuture; | 98 | Async::Future<PrevOut> *mPrevFuture; |
97 | Async::FutureWatcher<PrevOut> *mPrevFutureWatcher; | 99 | Async::FutureWatcher<PrevOut> *mPrevFutureWatcher; |
98 | }; | 100 | }; |
@@ -101,7 +103,7 @@ template<typename Out, typename ... In> | |||
101 | class ThenExecutor: public Executor<typename PreviousOut<In ...>::type, Out, In ...> | 103 | class ThenExecutor: public Executor<typename PreviousOut<In ...>::type, Out, In ...> |
102 | { | 104 | { |
103 | public: | 105 | public: |
104 | ThenExecutor(ThenTask<Out, In ...> then, ExecutorBase *parent = nullptr); | 106 | ThenExecutor(ThenTask<Out, In ...> then, ErrorHandler errorHandler = ErrorHandler(), ExecutorBase *parent = nullptr); |
105 | void previousFutureReady(); | 107 | void previousFutureReady(); |
106 | 108 | ||
107 | private: | 109 | private: |
@@ -221,9 +223,9 @@ class Job : public JobBase | |||
221 | 223 | ||
222 | public: | 224 | public: |
223 | template<typename OutOther, typename ... InOther> | 225 | template<typename OutOther, typename ... InOther> |
224 | Job<OutOther, InOther ...> then(ThenTask<OutOther, InOther ...> func) | 226 | Job<OutOther, InOther ...> then(ThenTask<OutOther, InOther ...> func, ErrorHandler errorFunc = ErrorHandler()) |
225 | { | 227 | { |
226 | return Job<OutOther, InOther ...>(new Private::ThenExecutor<OutOther, InOther ...>(func, mExecutor)); | 228 | return Job<OutOther, InOther ...>(new Private::ThenExecutor<OutOther, InOther ...>(func, errorFunc, mExecutor)); |
227 | } | 229 | } |
228 | 230 | ||
229 | template<typename OutOther, typename InOther> | 231 | template<typename OutOther, typename InOther> |
@@ -309,10 +311,11 @@ void Executor<PrevOut, Out, In ...>::exec() | |||
309 | } | 311 | } |
310 | 312 | ||
311 | template<typename Out, typename ... In> | 313 | template<typename Out, typename ... In> |
312 | ThenExecutor<Out, In ...>::ThenExecutor(ThenTask<Out, In ...> then, ExecutorBase* parent) | 314 | ThenExecutor<Out, In ...>::ThenExecutor(ThenTask<Out, In ...> then, ErrorHandler error, ExecutorBase* parent) |
313 | : Executor<typename PreviousOut<In ...>::type, Out, In ...>(parent) | 315 | : Executor<typename PreviousOut<In ...>::type, Out, In ...>(parent) |
314 | { | 316 | { |
315 | this->mFunc = then; | 317 | this->mFunc = then; |
318 | this->mErrorFunc = error; | ||
316 | } | 319 | } |
317 | 320 | ||
318 | template<typename Out, typename ... In> | 321 | template<typename Out, typename ... In> |
@@ -321,8 +324,19 @@ void ThenExecutor<Out, In ...>::previousFutureReady() | |||
321 | if (this->mPrevFuture) { | 324 | if (this->mPrevFuture) { |
322 | assert(this->mPrevFuture->isFinished()); | 325 | assert(this->mPrevFuture->isFinished()); |
323 | } | 326 | } |
324 | this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ..., | 327 | if (this->mPrevFuture && this->mPrevFuture->errorCode()) { |
325 | *static_cast<Async::Future<Out>*>(this->mResult)); | 328 | if (this->mErrorFunc) { |
329 | this->mErrorFunc(this->mPrevFuture->errorCode(), this->mPrevFuture->errorMessage()); | ||
330 | } else { | ||
331 | static_cast<Async::Future<Out>*>(this->mResult)->setError(this->mPrevFuture->errorCode(), this->mPrevFuture->errorMessage()); | ||
332 | //propagate error if no error handler is available | ||
333 | this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ..., | ||
334 | *static_cast<Async::Future<Out>*>(this->mResult)); | ||
335 | } | ||
336 | } else { | ||
337 | this->mFunc(this->mPrevFuture ? this->mPrevFuture->value() : In() ..., | ||
338 | *static_cast<Async::Future<Out>*>(this->mResult)); | ||
339 | } | ||
326 | } | 340 | } |
327 | 341 | ||
328 | template<typename PrevOut, typename Out, typename In> | 342 | template<typename PrevOut, typename Out, typename In> |