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