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 */