Initial import to Git
[profile/ivi/common-api-dbus-runtime.git] / CommonAPI-DBus / src / CommonAPI / DBus / DBusEvent.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #ifndef COMMONAPI_DBUS_DBUS_EVENT_H_
5 #define COMMONAPI_DBUS_DBUS_EVENT_H_
6
7 #include "DBusProxyConnection.h"
8 #include "DBusMessage.h"
9 #include "DBusSerializableArguments.h"
10
11 #include <CommonAPI/Event.h>
12
13 namespace CommonAPI {
14 namespace DBus {
15
16 class DBusProxy;
17
18
19 template <typename _EventType, typename _DBusProxy = DBusProxy>
20 class DBusEvent: public _EventType, public DBusProxyConnection::DBusSignalHandler {
21  public:
22         typedef typename _EventType::ArgumentsTuple ArgumentsTuple;
23         typedef typename _EventType::CancellableListener CancellableListener;
24
25         DBusEvent(_DBusProxy& dbusProxy, const char* eventName, const char* eventSignature):
26                         dbusProxy_(dbusProxy),
27                         eventName_(eventName),
28                         eventSignature_(eventSignature) {
29                 assert(eventName);
30                 assert(eventSignature);
31         }
32
33         virtual ~DBusEvent() {
34                 if (this->hasListeners())
35                         dbusProxy_.removeSignalMemberHandler(subscription_);
36         }
37
38         virtual SubscriptionStatus onSignalDBusMessage(const DBusMessage& dbusMessage) {
39                 return unpackArgumentsAndHandleSignalDBusMessage(dbusMessage, ArgumentsTuple());
40         }
41
42  protected:
43         virtual void onFirstListenerAdded(const CancellableListener&) {
44                 subscription_ = dbusProxy_.addSignalMemberHandler(eventName_, eventSignature_, this);
45         }
46
47         virtual void onLastListenerRemoved(const CancellableListener&) {
48                 dbusProxy_.removeSignalMemberHandler(subscription_);
49         }
50
51  private:
52         template <typename ... _Arguments>
53         inline SubscriptionStatus unpackArgumentsAndHandleSignalDBusMessage(const DBusMessage& dbusMessage, std::tuple<_Arguments...> argTuple) {
54                 return handleSignalDBusMessage(dbusMessage, std::move(argTuple), typename make_sequence<sizeof...(_Arguments)>::type());
55         }
56
57         template <typename ... _Arguments, int... _ArgIndices>
58         inline SubscriptionStatus handleSignalDBusMessage(const DBusMessage& dbusMessage, std::tuple<_Arguments...> argTuple, index_sequence<_ArgIndices...>) {
59                 DBusInputStream dbusInputStream(dbusMessage);
60                 const bool success = DBusSerializableArguments<_Arguments...>::deserialize(dbusInputStream, std::get<_ArgIndices>(argTuple)...);
61                 // Continue subscription if deserialization failed
62                 return success ? this->notifyListeners(std::get<_ArgIndices>(argTuple)...) : SubscriptionStatus::RETAIN;
63         }
64
65         _DBusProxy& dbusProxy_;
66         const char* eventName_;
67         const char* eventSignature_;
68         DBusProxyConnection::DBusSignalHandlerToken subscription_;
69 };
70
71 } // namespace DBus
72 } // namespace CommonAPI
73
74 #endif // COMMONAPI_DBUS_DBUS_EVENT_H_