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_
7 #include "DBusProxyConnection.h"
8 #include "DBusMessage.h"
9 #include "DBusSerializableArguments.h"
11 #include <CommonAPI/Event.h>
19 template <typename _EventType, typename _DBusProxy = DBusProxy>
20 class DBusEvent: public _EventType, public DBusProxyConnection::DBusSignalHandler {
22 typedef typename _EventType::ArgumentsTuple ArgumentsTuple;
23 typedef typename _EventType::CancellableListener CancellableListener;
25 DBusEvent(_DBusProxy& dbusProxy, const char* eventName, const char* eventSignature):
26 dbusProxy_(dbusProxy),
27 eventName_(eventName),
28 eventSignature_(eventSignature) {
30 assert(eventSignature);
33 virtual ~DBusEvent() {
34 if (this->hasListeners())
35 dbusProxy_.removeSignalMemberHandler(subscription_);
38 virtual SubscriptionStatus onSignalDBusMessage(const DBusMessage& dbusMessage) {
39 return unpackArgumentsAndHandleSignalDBusMessage(dbusMessage, ArgumentsTuple());
43 virtual void onFirstListenerAdded(const CancellableListener&) {
44 subscription_ = dbusProxy_.addSignalMemberHandler(eventName_, eventSignature_, this);
47 virtual void onLastListenerRemoved(const CancellableListener&) {
48 dbusProxy_.removeSignalMemberHandler(subscription_);
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());
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;
65 _DBusProxy& dbusProxy_;
66 const char* eventName_;
67 const char* eventSignature_;
68 DBusProxyConnection::DBusSignalHandlerToken subscription_;
72 } // namespace CommonAPI
74 #endif // COMMONAPI_DBUS_DBUS_EVENT_H_