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 | * @class BluezQt::TPendingCall tpendingcall.h <BluezQt/TPendingCall> |
22 | * |
23 | * Pending method call (template version). |
24 | * |
25 | * This class represents a pending method call. It is a convenient wrapper |
26 | * around QDBusPendingReply and QDBusPendingCallWatcher. |
27 | * The TPendingCall is a template class whose parameters are the types that will |
28 | * be used to extract the contents of the reply's data. |
29 | */ |
30 | |
31 | // KF6 TODO: convert all PendingCalls to TPendingCall (or convert existing PendingCall class to templated version). |
32 | template<class... T> |
33 | class TPendingCall : public PendingCall |
34 | { |
35 | private: |
36 | template<int Index, typename Ty, typename... Ts> |
37 | struct Select { |
38 | using Type = typename Select<Index - 1, Ts...>::Type; |
39 | }; |
40 | template<typename Ty, typename... Ts> |
41 | struct Select<0, Ty, Ts...> { |
42 | using Type = Ty; |
43 | }; |
44 | |
45 | public: |
46 | /** |
47 | * Returns a return value at given index of the call. |
48 | * |
49 | * Returns the return value at position Index (which is a template parameter) cast to type Type. |
50 | * This function uses template code to determine the proper Type type, according to the type |
51 | * list used in the construction of this object. |
52 | * |
53 | * @return return value at index |
54 | */ |
55 | template<int Index> |
56 | inline const typename Select<Index, T...>::Type valueAt() const |
57 | { |
58 | using ResultType = typename Select<Index, T...>::Type; |
59 | return qdbus_cast<ResultType>(m_reply.argumentAt(Index)); |
60 | } |
61 | |
62 | private: |
63 | TPendingCall(const QDBusPendingCall &call, QObject *parent = nullptr) |
64 | : PendingCall(call, std::bind(&TPendingCall::process, this, _1, _2, _3), parent) |
65 | { |
66 | } |
67 | |
68 | void process(QDBusPendingCallWatcher *watcher, ErrorProcessor errorProcessor, QVariantList *values) |
69 | { |
70 | m_reply = *watcher; |
71 | errorProcessor(m_reply.error()); |
72 | if (m_reply.isError()) { |
73 | return; |
74 | } |
75 | |
76 | for (int i = 0; i < m_reply.count(); ++i) { |
77 | values->append(m_reply.argumentAt(i)); |
78 | } |
79 | } |
80 | |
81 | QDBusPendingReply<T...> m_reply; |
82 | |
83 | friend class MediaTransport; |
84 | }; |
85 | |
86 | } // namespace BluezQt |
87 | |
88 | #endif |
89 | |