Enable multiple filters

Add support for specifying multiple filters for a given event.
All filters must evaluate true to trigger the associated action.

Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Change-Id: I86d3e98e5c9e23b65e2e9733c817b38d2ab59465
diff --git a/events.hpp b/events.hpp
index 65eb06a..e029a6f 100644
--- a/events.hpp
+++ b/events.hpp
@@ -52,7 +52,7 @@
  */
 struct DbusSignal final :
     public Event,
-    public std::tuple<const char*, FilterBasePtr>
+    public std::tuple<const char*, std::vector<FilterBasePtr>>
 {
     virtual ~DbusSignal() = default;
     DbusSignal(const DbusSignal&) = default;
@@ -65,10 +65,10 @@
      *  @param[in] sig - The DBus match signature.
      *  @param[in] filter - A DBus signal match callback filtering function.
      */
-    DbusSignal(const char* sig, FilterBasePtr filter) :
+    DbusSignal(const char* sig, const std::vector<FilterBasePtr>& filters) :
         Event(Type::DBUS_SIGNAL),
-        std::tuple<const char*, FilterBasePtr>(
-            sig, std::move(filter)) {}
+        std::tuple<const char*, std::vector<FilterBasePtr>>(
+                    sig, std::move(filters)) {}
 };
 
 /** @brief make_filter
@@ -128,7 +128,7 @@
             const char* iface = nullptr;
 
             msg.read(iface);
-            if (strcmp(iface, _iface))
+            if (!iface || strcmp(iface, _iface))
             {
                 return false;
             }
diff --git a/manager.cpp b/manager.cpp
index e100cd9..a5cdf89 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -183,16 +183,20 @@
     const details::DbusSignal& event,
     const EventInfo& info)
 {
-    auto& filter = *std::get<1>(event);
+    auto& filters = std::get<1>(event);
     auto& actions = std::get<1>(info);
 
-    if (filter(msg, *this))
+    for (auto& f : filters)
     {
-        for (auto& action : actions)
+        if (!(*f)(msg, *this))
         {
-            (*action)(*this);
+            return;
         }
     }
+    for (auto& action : actions)
+    {
+        (*action)(*this);
+    }
 }
 
 void Manager::destroyObjects(
diff --git a/pimgen.py b/pimgen.py
index 5e2cf00..a7d2a2e 100755
--- a/pimgen.py
+++ b/pimgen.py
@@ -314,6 +314,9 @@
 
         filters = [
             self.filter_map[x['name']](**x) for x in kw.pop('filters', [])]
+        filters = Vector(
+            templates=[Template(name='FilterBasePtr', namespace=['details'])],
+            args=filters)
 
         event = MethodCall(
             name='make_shared',
@@ -321,7 +324,7 @@
             templates=[Template(
                 name=kw.pop('event'),
                 namespace=kw.pop('event_namespace', []))],
-            args=kw.pop('event_args', []) + [filters[0]])
+            args=kw.pop('event_args', []) + [filters])
 
         events = Vector(
             templates=[Template(name='EventBasePtr', namespace=['details'])],