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