diff options
| author | Linus Jahn <lnj@kaidan.im> | 2022-08-16 21:00:15 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2023-01-03 22:05:54 +0100 |
| commit | b17284ee7d674416e0d11f1699f73fcc606262d4 (patch) | |
| tree | 86597f2bc2a1ed2d257e0cbf8e7de1ca54080c08 /src/base/QXmppFutureUtils_p.h | |
| parent | 3271c6642439d4d3c0d8c634e2b3f4cf17b908a0 (diff) | |
| download | qxmpp-b17284ee7d674416e0d11f1699f73fcc606262d4.tar.gz | |
Introduce QXmppTask & QXmppPromise
Closes #502.
Co-authored-by: Jonah BrĂ¼chert <jbb@kaidan.im>
Diffstat (limited to 'src/base/QXmppFutureUtils_p.h')
| -rw-r--r-- | src/base/QXmppFutureUtils_p.h | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/src/base/QXmppFutureUtils_p.h b/src/base/QXmppFutureUtils_p.h index 311e7019..5e6b5ca8 100644 --- a/src/base/QXmppFutureUtils_p.h +++ b/src/base/QXmppFutureUtils_p.h @@ -16,6 +16,7 @@ // #include "QXmppIq.h" +#include "QXmppPromise.h" #include "QXmppSendResult.h" #include <memory> @@ -85,6 +86,21 @@ inline QFuture<void> makeReadyFuture() } #endif +template<typename T> +QXmppTask<T> makeReadyTask(T &&value) +{ + QXmppPromise<T> promise; + promise.finish(std::move(value)); + return promise.task(); +} + +inline QXmppTask<void> makeReadyTask() +{ + QXmppPromise<void> promise; + promise.finish(); + return promise.task(); +} + template<typename T, typename Handler> void awaitLast(const QFuture<T> &future, QObject *context, Handler handler) { @@ -123,18 +139,14 @@ void await(const QFuture<void> &future, QObject *context, Handler handler) } template<typename Result, typename Input, typename Converter> -auto chain(const QFuture<Input> &source, QObject *context, Converter task) -> QFuture<Result> +auto chain(QXmppTask<Input> &&source, QObject *context, Converter task) -> QXmppTask<Result> { - QFutureInterface<Result> resultInterface(QFutureInterfaceBase::Started); + QXmppPromise<Result> promise; - auto *watcher = new QFutureWatcher<Input>(context); - QObject::connect(watcher, &QFutureWatcherBase::finished, context, [=]() mutable { - resultInterface.reportResult(task(watcher->result())); - resultInterface.reportFinished(); - watcher->deleteLater(); + source.then(context, [=](Input &&input) mutable { + promise.finish(task(std::move(input))); }); - watcher->setFuture(source); - return resultInterface.future(); + return promise.task(); } template<typename IqType, typename Input, typename Converter> @@ -169,21 +181,21 @@ auto parseIq(Input &&sendResult) -> Result } template<typename Input, typename Converter> -auto chainIq(QFuture<Input> &&input, QObject *context, Converter convert) -> QFuture<decltype(convert({}))> +auto chainIq(QXmppTask<Input> &&input, QObject *context, Converter convert) -> QXmppTask<decltype(convert({}))> { using Result = decltype(convert({})); using IqType = std::decay_t<first_argument_t<Converter>>; - return chain<Result>(std::move(input), context, [convert { std::move(convert) }](Input &&input) -> Result { + return chain<Result>(std::move(input), context, [convert = std::move(convert)](Input &&input) -> Result { return parseIq<IqType>(std::move(input), convert); }); } template<typename Result, typename Input> -auto chainIq(QFuture<Input> &&input, QObject *context) -> QFuture<Result> +auto chainIq(QXmppTask<Input> &&input, QObject *context) -> QXmppTask<Result> { // IQ type is first std::variant parameter using IqType = std::decay_t<decltype(std::get<0>(Result {}))>; - return chain<Result>(std::move(input), context, [](Input &&sendResult) { + return chain<Result>(std::move(input), context, [](Input &&sendResult) mutable { return parseIq<IqType, Result>(sendResult); }); } @@ -210,6 +222,24 @@ auto mapSuccess(std::variant<T, Err> var, Function lambda) std::move(var)); } +template<typename T> +static auto taskFromFuture(QFuture<T> &&future) -> QXmppTask<T> +{ + QXmppPromise<T> promise; + auto *watcher = new QFutureWatcher<T>(); + QObject::connect(watcher, &QFutureWatcher<T>::finished, [promise = std::move(promise), watcher]() mutable { + if constexpr (std::is_void_v<T>) { + promise.finish(); + } else { + promise.finish(watcher->result()); + } + watcher->deleteLater(); + }); + watcher->setFuture(future); + + return promise.task(); +} + } // namespace QXmpp::Private #endif // QXMPPFUTUREUTILS_P_H |
