9#include "QXmppAsync_p.h"
10#include "QXmppGlobal.h"
15#include <QFutureWatcher>
17namespace QXmpp::Private {
19template<
typename Function>
20auto later(QObject *context, Function function)
22 QMetaObject::invokeMethod(context, std::forward<Function>(function), Qt::QueuedConnection);
25#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
27QFuture<T> makeReadyFuture(T &&value) {
return QtFuture::makeReadyValueFuture(std::move(value)); }
28#elif QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
29using QtFuture::makeReadyFuture;
32QFuture<T> makeReadyFuture(T &&value)
34 QFutureInterface<T> interface(QFutureInterfaceBase::Started);
35 interface.reportResult(std::move(value));
36 interface.reportFinished();
37 return interface.future();
40inline QFuture<void> makeReadyFuture()
42 using State = QFutureInterfaceBase::State;
43 return QFutureInterface<void>(State(State::Started | State::Finished)).future();
47template<
typename T,
typename Handler>
48void await(
const QFuture<T> &future, QObject *context, Handler handler)
50 auto *watcher =
new QFutureWatcher<T>(context);
51 QObject::connect(watcher, &QFutureWatcherBase::finished,
52 context, [watcher, handler = std::move(handler)]()
mutable {
53 handler(watcher->result());
54 watcher->deleteLater();
56 watcher->setFuture(future);
59template<
typename Handler>
60void await(
const QFuture<void> &future, QObject *context, Handler handler)
62 auto *watcher =
new QFutureWatcher<void>(context);
63 QObject::connect(watcher, &QFutureWatcherBase::finished,
64 context, [watcher, handler = std::move(handler)]()
mutable {
66 watcher->deleteLater();
68 watcher->setFuture(future);
71template<
typename T,
typename Err,
typename Function>
72auto mapSuccess(std::variant<T, Err> var, Function lambda)
74 using MapResult = std::decay_t<
decltype(lambda({}))>;
75 using MappedVariant = std::variant<MapResult, Err>;
76 return std::visit(overloaded {
77 [lambda = std::move(lambda)](T val) -> MappedVariant {
78 return lambda(std::move(val));
80 [](Err err) -> MappedVariant {
86template<
typename T,
typename Err>
87auto mapToSuccess(std::variant<T, Err> var)
89 return mapSuccess(std::move(var), [](T) {
94template<
typename T,
typename Err>
95auto chainSuccess(QXmppTask<std::variant<T, Err>> &&source, QObject *context) -> QXmppTask<std::variant<QXmpp::Success, QXmppError>>
97 return chain<std::variant<QXmpp::Success, QXmppError>>(std::move(source), context, mapToSuccess<T, Err>);
100template<
typename Input,
typename Converter>
101auto chainMapSuccess(QXmppTask<Input> &&source, QObject *context, Converter convert)
103 return chain<std::variant<
decltype(convert({})), QXmppError>>(std::move(source), context, [convert](Input &&input) {
104 return mapSuccess(std::move(input), convert);
110QXmppTask<void> joinVoidTasks(QObject *context, QList<QXmppTask<T>> &&tasks)
112 int taskCount = tasks.size();
113 auto finishedTaskCount = std::make_shared<int>();
115 QXmppPromise<void> promise;
117 for (
auto task : tasks) {
118 task.then(context, [=]()
mutable {
119 if (++(*finishedTaskCount) == taskCount) {
125 return promise.
task();
QXmppTask< T > task()
Definition QXmppPromise.h:86