File indexing completed on 2025-01-26 05:06:09
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, typename... Args> 0122 QFuture<_Result> asyncCall(QDBusAbstractInterface *interface, const QString &method, Args &&...args) 0123 { 0124 using namespace detail; 0125 0126 auto callFutureInterface = new DBusCallFutureInterface<_Result>(interface->asyncCall(method, std::forward<Args>(args)...)); 0127 0128 return callFutureInterface->start(); 0129 } 0130 0131 template<typename _Result> 0132 QFuture<_Result> fromValue(const _Result &value) 0133 { 0134 using namespace detail; 0135 0136 auto valueFutureInterface = new ValueFutureInterface<_Result>(value); 0137 0138 return valueFutureInterface->start(); 0139 } 0140 0141 template<typename _Result> 0142 QFuture<_Result> fromReply(const QDBusPendingReply<_Result> &reply) 0143 { 0144 using namespace detail; 0145 0146 auto callFutureInterface = new DBusCallFutureInterface<_Result>(reply); 0147 0148 return callFutureInterface->start(); 0149 } 0150 0151 QFuture<void> fromVoid(); 0152 0153 } // namespace DBusFuture 0154 0155 #endif /* ACTIVITIES_DBUSFUTURE_P_H */