1 /**
2  * (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
3  * (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
4  *
5  * @file ProxyInterfaces.h
6  *
7  * Created on: Apr 8, 2019
8  * Project: sdbus-c++
9  * Description: High-level D-Bus IPC C++ library based on sd-bus
10  *
11  * This file is part of sdbus-c++.
12  *
13  * sdbus-c++ is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU Lesser General Public License as published by
15  * the Free Software Foundation, either version 2.1 of the License, or
16  * (at your option) any later version.
17  *
18  * sdbus-c++ is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with sdbus-c++. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #ifndef SDBUS_CXX_PROXYINTERFACES_H_
28 #define SDBUS_CXX_PROXYINTERFACES_H_
29 
30 #include <sdbus-c++/IProxy.h>
31 #include <cassert>
32 #include <string>
33 #include <memory>
34 
35 // Forward declarations
36 namespace sdbus {
37     class IConnection;
38 }
39 
40 namespace sdbus {
41 
42     /********************************************//**
43      * @class ProxyObjectHolder
44      *
45      * ProxyObjectHolder is a helper that simply owns and provides
46      * access to a proxy object to other classes in the inheritance
47      * hierarchy of a native-like proxy object based on generated
48      * interface classes.
49      *
50      ***********************************************/
51     class ProxyObjectHolder
52     {
53     protected:
ProxyObjectHolder(std::unique_ptr<IProxy> && proxy)54         ProxyObjectHolder(std::unique_ptr<IProxy>&& proxy)
55             : proxy_(std::move(proxy))
56         {
57             assert(proxy_ != nullptr);
58         }
59 
getProxy()60         const IProxy& getProxy() const
61         {
62             assert(proxy_ != nullptr);
63             return *proxy_;
64         }
65 
getProxy()66         IProxy& getProxy()
67         {
68             assert(proxy_ != nullptr);
69             return *proxy_;
70         }
71 
72     private:
73         std::unique_ptr<IProxy> proxy_;
74     };
75 
76     /********************************************//**
77      * @class ProxyInterfaces
78      *
79      * ProxyInterfaces is a helper template class that joins all interface classes of a remote
80      * D-Bus object generated by sdbus-c++-xml2cpp to be used on the client (the proxy) side,
81      * including some auxiliary classes. ProxyInterfaces is the class that native-like proxy
82      * implementation classes written by users should inherit from and implement all pure virtual
83      * methods. So the _Interfaces template parameter is a list of sdbus-c++-xml2cpp-generated
84      * proxy-side interface classes representing interfaces of the corresponding remote D-Bus object.
85      *
86      * In the final proxy class inherited from ProxyInterfaces, it is necessary to finish proxy
87      * registration in class constructor (`finishRegistration();`), and, conversely, unregister
88      * the proxy in class destructor (`unregister();`).
89      *
90      ***********************************************/
91     template <typename... _Interfaces>
92     class ProxyInterfaces
93         : protected ProxyObjectHolder
94         , public _Interfaces...
95     {
96     public:
97         /*!
98          * @brief Creates native-like proxy object instance
99          *
100          * @param[in] destination Bus name that provides a D-Bus object
101          * @param[in] objectPath Path of the D-Bus object
102          *
103          * This constructor overload creates a proxy that manages its own D-Bus connection(s).
104          * For more information on its behavior, consult @ref createProxy(std::string,std::string)
105          */
ProxyInterfaces(std::string destination,std::string objectPath)106         ProxyInterfaces(std::string destination, std::string objectPath)
107             : ProxyObjectHolder(createProxy(std::move(destination), std::move(objectPath)))
108             , _Interfaces(getProxy())...
109         {
110         }
111 
112         /*!
113          * @brief Creates native-like proxy object instance
114          *
115          * @param[in] connection D-Bus connection to be used by the proxy object
116          * @param[in] destination Bus name that provides a D-Bus object
117          * @param[in] objectPath Path of the D-Bus object
118          *
119          * The proxy created this way just references a D-Bus connection owned and managed by the user.
120          * For more information on its behavior, consult @ref createProxy(IConnection&,std::string,std::string)
121          */
ProxyInterfaces(IConnection & connection,std::string destination,std::string objectPath)122         ProxyInterfaces(IConnection& connection, std::string destination, std::string objectPath)
123             : ProxyObjectHolder(createProxy(connection, std::move(destination), std::move(objectPath)))
124             , _Interfaces(getProxy())...
125         {
126         }
127 
128         /*!
129          * @brief Creates native-like proxy object instance
130          *
131          * @param[in] connection D-Bus connection to be used by the proxy object
132          * @param[in] destination Bus name that provides a D-Bus object
133          * @param[in] objectPath Path of the D-Bus object
134          *
135          * The proxy created this way becomes an owner of the connection.
136          * For more information on its behavior, consult @ref createProxy(std::unique_ptr<sdbus::IConnection>&&,std::string,std::string)
137          */
ProxyInterfaces(std::unique_ptr<sdbus::IConnection> && connection,std::string destination,std::string objectPath)138         ProxyInterfaces(std::unique_ptr<sdbus::IConnection>&& connection, std::string destination, std::string objectPath)
139             : ProxyObjectHolder(createProxy(std::move(connection), std::move(destination), std::move(objectPath)))
140             , _Interfaces(getProxy())...
141         {
142         }
143 
144         /*!
145          * @brief Finishes proxy registration and makes the proxy ready for use
146          *
147          * This function must be called in the constructor of the final proxy class that implements ProxyInterfaces.
148          *
149          * For more information, see underlying @ref IProxy::finishRegistration()
150          */
registerProxy()151         void registerProxy()
152         {
153             getProxy().finishRegistration();
154         }
155 
156         /*!
157          * @brief Unregisters the proxy so it no more receives signals and async call replies
158          *
159          * This function must be called in the destructor of the final proxy class that implements ProxyInterfaces.
160          *
161          * See underlying @ref IProxy::unregister()
162          */
unregisterProxy()163         void unregisterProxy()
164         {
165             getProxy().unregister();
166         }
167 
168         /*!
169          * @brief Returns object path of the underlying DBus object
170          */
getObjectPath()171         const std::string& getObjectPath() const
172         {
173             return getProxy().getObjectPath();
174         }
175 
176     protected:
177         using base_type = ProxyInterfaces;
178         ~ProxyInterfaces() = default;
179     };
180 
181 }
182 
183 #endif /* SDBUS_CXX_INTERFACES_H_ */
184