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