Add event framework
Introduce the concept of events, where the existing Dbus signal
match event is one of many possible event classes.
Change-Id: I9b0c6ca12daaa109f8ceb537a5fb0cc6b5f7181b
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/events.hpp b/events.hpp
index e2a87e3..30fb24f 100644
--- a/events.hpp
+++ b/events.hpp
@@ -22,6 +22,55 @@
using Filter = holder::CallableHolder<
T, bool, sdbusplus::message::message&, Manager&>;
+/** @struct Event
+ * @brief Event object interface.
+ */
+struct Event
+{
+ enum class Type
+ {
+ DBUS_SIGNAL,
+ };
+
+ virtual ~Event() = default;
+ Event(const Event&) = default;
+ Event& operator=(const Event&) = default;
+ Event(Event&&) = default;
+ Event& operator=(Event&&) = default;
+ explicit Event(Type t) : type(t) {}
+
+ Type type;
+};
+
+using EventBasePtr = std::shared_ptr<Event>;
+
+/** @struct DbusSignal
+ * @brief DBus signal event.
+ *
+ * DBus signal events are an association of a match signature
+ * and filtering function object.
+ */
+struct DbusSignal final :
+ public Event,
+ public std::tuple<const char *, FilterBasePtr>
+{
+ virtual ~DbusSignal() = default;
+ DbusSignal(const DbusSignal&) = default;
+ DbusSignal & operator=(const DbusSignal&) = delete;
+ DbusSignal(DbusSignal&&) = default;
+ DbusSignal& operator=(DbusSignal&&) = default;
+
+ /** @brief Import from signature and filter constructor.
+ *
+ * @param[in] sig - The DBus match signature.
+ * @param[in] filter - A DBus signal match callback filtering function.
+ */
+ DbusSignal(const char *sig, FilterBasePtr filter) :
+ Event(Type::DBUS_SIGNAL),
+ std::tuple<const char *, FilterBasePtr>(
+ sig, std::move(filter)) {}
+};
+
/** @brief make_filter
*
* Adapt a filter function object.
diff --git a/generated.mako.cpp b/generated.mako.cpp
index 862b3b2..2dccf82 100644
--- a/generated.mako.cpp
+++ b/generated.mako.cpp
@@ -38,6 +38,7 @@
// ${e['description']}
% endif
std::make_tuple(
+ std::make_shared<details::DbusSignal>(
% for i, s in enumerate(e['signature'].items()):
% if i + 1 == len(e['signature']):
${'"{0}=\'{1}\'"'.format(*s)},
@@ -46,16 +47,16 @@
% endif
% endfor
% if e['filter'].get('args'):
- details::make_filter(filters::${e['filter']['type']}(
+ details::make_filter(filters::${e['filter']['type']}(
% for i, a in enumerate(e['filter']['args']):
% if i + 1 == len(e['filter']['args']):
- "${a['value']}")),
+ "${a['value']}"))),
% else:
"${a['value']}",
% endif
% endfor
% else:
- details::make_filter(filters::${e['filter']['type']}),
+ details::make_filter(filters::${e['filter']['type']})),
% endif
% if e['action'].get('args'):
std::vector<details::ActionBasePtr>({details::make_action(actions::${e['action']['type']}(
diff --git a/manager.cpp b/manager.cpp
index cf3c59c..07d3d31 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -61,6 +61,11 @@
_manager(sdbusplus::server::manager::manager(_bus, root))
{
for (auto &x: _events) {
+ auto pEvent = std::get<0>(x);
+ if (pEvent->type !=
+ details::Event::Type::DBUS_SIGNAL)
+ continue;
+
// Create a callback context for each event.
_sigargs.emplace_back(
std::make_unique<SigArg>(
@@ -69,10 +74,12 @@
&x)));
// Register our callback and the context for
// each event.
+ auto &dbusEvent = static_cast<details::DbusSignal &>(
+ *pEvent);
_matches.emplace_back(
sdbusplus::server::match::match(
_bus,
- std::get<0>(x),
+ std::get<0>(dbusEvent),
details::_signal,
_sigargs.back().get()));
}
@@ -144,8 +151,9 @@
void Manager::signal(sdbusplus::message::message &msg, auto &args)
{
- auto &filter = *std::get<1>(args);
- auto &actions = std::get<2>(args);
+ auto &event = std::get<0>(args);
+ auto &actions = std::get<1>(args);
+ auto &filter = *std::get<1>(static_cast<details::DbusSignal &>(*event));
if(filter(msg, *this)) {
for (auto &action: actions)
diff --git a/manager.hpp b/manager.hpp
index 5c694b5..c905b8b 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -94,22 +94,21 @@
/** @brief Drop an object from DBus. */
void destroyObject(const char *);
- using Event = std::tuple<
- const char *,
- details::FilterBasePtr,
+ using EventInfo = std::tuple<
+ details::EventBasePtr,
std::vector<details::ActionBasePtr>>;
using SigArgs = std::vector<
std::unique_ptr<
std::tuple<
Manager *,
- const Event *>>>;
+ const EventInfo *>>>;
using SigArg = SigArgs::value_type::element_type;
private:
using HolderPtr = std::unique_ptr<details::holder::Base>;
using InterfaceComposite = std::map<std::string, HolderPtr>;
using ObjectReferences = std::map<std::string, InterfaceComposite>;
- using Events = std::vector<Event>;
+ using Events = std::vector<EventInfo>;
using MakerType = HolderPtr(*)(
sdbusplus::bus::bus &, const char *);
using Makers = std::map<std::string, MakerType>;