| 1 | /* |
| 2 | * BluezQt - Asynchronous BlueZ wrapper library |
| 3 | * |
| 4 | * SPDX-FileCopyrightText: 2019 Manuel Weichselbaumer <mincequi@web.de> |
| 5 | * |
| 6 | * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
| 7 | */ |
| 8 | |
| 9 | #ifndef BLUEZQT_TPENDINGCALL_H |
| 10 | #define BLUEZQT_TPENDINGCALL_H |
| 11 | |
| 12 | #include <QDBusPendingReply> |
| 13 | |
| 14 | #include "pendingcall.h" |
| 15 | |
| 16 | namespace BluezQt |
| 17 | { |
| 18 | using namespace std::placeholders; |
| 19 | |
| 20 | /*! |
| 21 | * \inmodule BluezQt |
| 22 | * \class BluezQt::TPendingCall |
| 23 | * \inheaderfile BluezQt/TPendingCall |
| 24 | * \brief Pending method call (template version). |
| 25 | * |
| 26 | * This class represents a pending method call. It is a convenient wrapper |
| 27 | * around QDBusPendingReply and QDBusPendingCallWatcher. |
| 28 | * The TPendingCall is a template class whose parameters are the types that will |
| 29 | * be used to extract the contents of the reply's data. |
| 30 | */ |
| 31 | |
| 32 | // KF6 TODO: convert all PendingCalls to TPendingCall (or convert existing PendingCall class to templated version). |
| 33 | template<class... T> |
| 34 | class TPendingCall : public PendingCall |
| 35 | { |
| 36 | private: |
| 37 | template<int Index, typename Ty, typename... Ts> |
| 38 | struct Select { |
| 39 | using Type = typename Select<Index - 1, Ts...>::Type; |
| 40 | }; |
| 41 | template<typename Ty, typename... Ts> |
| 42 | struct Select<0, Ty, Ts...> { |
| 43 | using Type = Ty; |
| 44 | }; |
| 45 | |
| 46 | public: |
| 47 | /*! |
| 48 | * Returns a return value at given index of the call. |
| 49 | * |
| 50 | * Returns the return value at position Index (which is a template parameter) cast to type Type. |
| 51 | * This function uses template code to determine the proper Type type, according to the type |
| 52 | * list used in the construction of this object. |
| 53 | */ |
| 54 | template<int Index> |
| 55 | inline const typename Select<Index, T...>::Type valueAt() const |
| 56 | { |
| 57 | using ResultType = typename Select<Index, T...>::Type; |
| 58 | return qdbus_cast<ResultType>(m_reply.argumentAt(Index)); |
| 59 | } |
| 60 | |
| 61 | private: |
| 62 | TPendingCall(const QDBusPendingCall &call, QObject *parent = nullptr) |
| 63 | : PendingCall(call, std::bind(&TPendingCall::process, this, _1, _2, _3), parent) |
| 64 | { |
| 65 | } |
| 66 | |
| 67 | void process(QDBusPendingCallWatcher *watcher, ErrorProcessor errorProcessor, QVariantList *values) |
| 68 | { |
| 69 | m_reply = *watcher; |
| 70 | errorProcessor(m_reply.error()); |
| 71 | if (m_reply.isError()) { |
| 72 | return; |
| 73 | } |
| 74 | |
| 75 | for (int i = 0; i < m_reply.count(); ++i) { |
| 76 | values->append(m_reply.argumentAt(i)); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | QDBusPendingReply<T...> m_reply; |
| 81 | |
| 82 | friend class MediaTransport; |
| 83 | }; |
| 84 | |
| 85 | } // namespace BluezQt |
| 86 | |
| 87 | #endif |
| 88 | |