File indexing completed on 2024-05-12 16:59:21

0001 /*
0002  *   SPDX-FileCopyrightText: 2013-2016 Ivan Cukic <ivan.cukic@kde.org>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #ifndef ACTIVITIES_DBUSFUTURE_P_H
0008 #define ACTIVITIES_DBUSFUTURE_P_H
0009 
0010 #include <QDBusAbstractInterface>
0011 #include <QDBusPendingCallWatcher>
0012 #include <QDBusPendingReply>
0013 #include <QDBusServiceWatcher>
0014 #include <QFuture>
0015 #include <QFutureInterface>
0016 #include <QFutureWatcherBase>
0017 
0018 namespace DBusFuture
0019 {
0020 namespace detail
0021 { //_
0022 
0023 template<typename _Result>
0024 class DBusCallFutureInterface : public QObject, public QFutureInterface<_Result>
0025 {
0026 public:
0027     DBusCallFutureInterface(QDBusPendingReply<_Result> reply)
0028         : reply(reply)
0029         , replyWatcher(nullptr)
0030     {
0031     }
0032 
0033     ~DBusCallFutureInterface()
0034     {
0035         delete replyWatcher;
0036     }
0037 
0038     void callFinished();
0039 
0040     QFuture<_Result> start()
0041     {
0042         replyWatcher = new QDBusPendingCallWatcher(reply);
0043 
0044         QObject::connect(replyWatcher, &QDBusPendingCallWatcher::finished, [this]() {
0045             callFinished();
0046         });
0047 
0048         this->reportStarted();
0049 
0050         if (reply.isFinished()) {
0051             this->callFinished();
0052         }
0053 
0054         return this->future();
0055     }
0056 
0057 private:
0058     QDBusPendingReply<_Result> reply;
0059     QDBusPendingCallWatcher *replyWatcher;
0060 };
0061 
0062 template<typename _Result>
0063 void DBusCallFutureInterface<_Result>::callFinished()
0064 {
0065     deleteLater();
0066 
0067     if (!reply.isError()) {
0068         this->reportResult(reply.value());
0069     }
0070 
0071     this->reportFinished();
0072 }
0073 
0074 template<>
0075 void DBusCallFutureInterface<void>::callFinished();
0076 
0077 template<typename _Result>
0078 class ValueFutureInterface : public QObject, QFutureInterface<_Result>
0079 {
0080 public:
0081     ValueFutureInterface(const _Result &value)
0082         : value(value)
0083     {
0084     }
0085 
0086     QFuture<_Result> start()
0087     {
0088         auto future = this->future();
0089 
0090         this->reportResult(value);
0091         this->reportFinished();
0092 
0093         deleteLater();
0094 
0095         return future;
0096     }
0097 
0098 private:
0099     _Result value;
0100 };
0101 
0102 template<>
0103 class ValueFutureInterface<void> : public QObject, QFutureInterface<void>
0104 {
0105 public:
0106     ValueFutureInterface();
0107 
0108     QFuture<void> start();
0109     // {
0110     //     auto future = this->future();
0111     //     this->reportFinished();
0112     //     deleteLater();
0113     //     return future;
0114     // }
0115 };
0116 
0117 } //^ namespace detail
0118 
0119 template<typename _Result>
0120 QFuture<_Result> asyncCall(QDBusAbstractInterface *interface,
0121                            const QString &method,
0122                            const QVariant &arg1 = QVariant(),
0123                            const QVariant &arg2 = QVariant(),
0124                            const QVariant &arg3 = QVariant(),
0125                            const QVariant &arg4 = QVariant(),
0126                            const QVariant &arg5 = QVariant(),
0127                            const QVariant &arg6 = QVariant(),
0128                            const QVariant &arg7 = QVariant(),
0129                            const QVariant &arg8 = QVariant())
0130 {
0131     using namespace detail;
0132 
0133     auto callFutureInterface = new DBusCallFutureInterface<_Result>(interface->asyncCall(method, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));
0134 
0135     return callFutureInterface->start();
0136 }
0137 
0138 template<typename _Result>
0139 QFuture<_Result> fromValue(const _Result &value)
0140 {
0141     using namespace detail;
0142 
0143     auto valueFutureInterface = new ValueFutureInterface<_Result>(value);
0144 
0145     return valueFutureInterface->start();
0146 }
0147 
0148 template<typename _Result>
0149 QFuture<_Result> fromReply(const QDBusPendingReply<_Result> &reply)
0150 {
0151     using namespace detail;
0152 
0153     auto callFutureInterface = new DBusCallFutureInterface<_Result>(reply);
0154 
0155     return callFutureInterface->start();
0156 }
0157 
0158 QFuture<void> fromVoid();
0159 
0160 } // namespace DBusFuture
0161 
0162 #endif /* DBUSFUTURE_P_H */