aboutsummaryrefslogtreecommitdiff
path: root/src/base/QXmppFutureUtils_p.h
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2022-08-16 21:00:15 +0200
committerLinus Jahn <lnj@kaidan.im>2023-01-03 22:05:54 +0100
commitb17284ee7d674416e0d11f1699f73fcc606262d4 (patch)
tree86597f2bc2a1ed2d257e0cbf8e7de1ca54080c08 /src/base/QXmppFutureUtils_p.h
parent3271c6642439d4d3c0d8c634e2b3f4cf17b908a0 (diff)
downloadqxmpp-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.h56
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