File indexing completed on 2024-12-01 12:29:51

0001 /*
0002  * BluezQt - Asynchronous BlueZ wrapper library
0003  *
0004  * SPDX-FileCopyrightText: 2019 Manuel Weichselbaumer <mincequi@web.de>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007  */
0008 
0009 #ifndef BLUEZQT_TPENDINGCALL_H
0010 #define BLUEZQT_TPENDINGCALL_H
0011 
0012 #include <QDBusPendingReply>
0013 
0014 #include "pendingcall.h"
0015 
0016 namespace BluezQt
0017 {
0018 using namespace std::placeholders;
0019 
0020 /**
0021  * @class BluezQt::TPendingCall tpendingcall.h <BluezQt/TPendingCall>
0022  *
0023  * Pending method call (template version).
0024  *
0025  * This class represents a pending method call. It is a convenient wrapper
0026  * around QDBusPendingReply and QDBusPendingCallWatcher.
0027  * The TPendingCall is a template class whose parameters are the types that will
0028  * be used to extract the contents of the reply's data.
0029  */
0030 
0031 // KF6 TODO: convert all PendingCalls to TPendingCall (or convert existing PendingCall class to templated version).
0032 template<class... T>
0033 class TPendingCall : public PendingCall
0034 {
0035 private:
0036     template<int Index, typename Ty, typename... Ts>
0037     struct Select {
0038         using Type = typename Select<Index - 1, Ts...>::Type;
0039     };
0040     template<typename Ty, typename... Ts>
0041     struct Select<0, Ty, Ts...> {
0042         using Type = Ty;
0043     };
0044 
0045 public:
0046     /**
0047      * Returns a return value at given index of the call.
0048      *
0049      * Returns the return value at position Index (which is a template parameter) cast to type Type.
0050      * This function uses template code to determine the proper Type type, according to the type
0051      * list used in the construction of this object.
0052      *
0053      * @return return value at index
0054      */
0055     template<int Index>
0056     inline const typename Select<Index, T...>::Type valueAt() const
0057     {
0058         using ResultType = typename Select<Index, T...>::Type;
0059         return qdbus_cast<ResultType>(m_reply.argumentAt(Index), nullptr);
0060     }
0061 
0062 private:
0063     TPendingCall(const QDBusPendingCall &call, QObject *parent = nullptr)
0064         : PendingCall(call, std::bind(&TPendingCall::process, this, _1, _2, _3), parent)
0065     {
0066     }
0067 
0068     void process(QDBusPendingCallWatcher *watcher, ErrorProcessor errorProcessor, QVariantList *values)
0069     {
0070         m_reply = *watcher;
0071         errorProcessor(m_reply.error());
0072         if (m_reply.isError()) {
0073             return;
0074         }
0075 
0076         for (int i = 0; i < m_reply.count(); ++i) {
0077             values->append(m_reply.argumentAt(i));
0078         }
0079     }
0080 
0081     QDBusPendingReply<T...> m_reply;
0082 
0083     friend class MediaTransport;
0084 };
0085 
0086 } // namespace BluezQt
0087 
0088 #endif