From 74c0e1f8e2a6dbc5b7485c3b06e12d4ad7f43c6b Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Fri, 23 Nov 2018 10:00:09 +0100 Subject: Use specific binder's event handlers Use specific binder's event handlers which allows you to bind a callback with an incoming event based on a pattern matching. This replace the global event listener and internal callback search algorythm which is now delegated to the binder. Clean unused constructor Bug-AGL: SPEC-1968 Change-Id: I4b22c003661189fb71498efc4d9021c1a54ae866 Signed-off-by: Romain Forlot --- signal-composer-binding/source.cpp | 83 +++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) (limited to 'signal-composer-binding/source.cpp') diff --git a/signal-composer-binding/source.cpp b/signal-composer-binding/source.cpp index f400731..a33db22 100644 --- a/signal-composer-binding/source.cpp +++ b/signal-composer-binding/source.cpp @@ -49,9 +49,12 @@ void SourceAPI::init() CtlSourceT source; source.uid = init_->uid; ActionExecOne(&source, init_, json_object_new_object()); + std::string sourceAPI_events = api_ + "/*"; + afb_api_event_handler_add(afbBindingV3root, sourceAPI_events.c_str(), SourceAPI::onSourceEvents, NULL); return; } - else if(api_ == afbBindingV3root->apiname) + + if(api_ == afbBindingV3root->apiname) {api_ = Composer::instance().ctlConfig()->api;} } @@ -60,6 +63,78 @@ std::string SourceAPI::api() const return api_; } +/// @brief callback for receiving message from low bindings. This will call back +/// an action defined in the configuration files depending on the events +/// received from an API. +/// +/// @param[in] object - an opaq pointer holding userdata +/// @param[in] event - event name +/// @param[in] object - eventual data that comes with the event +/// @param[in] object - the api that subscribed the event +/// +void SourceAPI::onSourceEvents(void *closure, const char *event_name, json_object *event_obj, AFB_ApiT api) +{ + std::vector> signals { Composer::instance().searchSignals(event_name) }; + + if(signals.empty()) + { + AFB_NOTICE("This event '%s' isn't registered within the signal composer configuration. Continue.", event_name); + return; + } + // If there is more than 1 element then maybe we can find a more + // detailled event name in JSON object as 1 event may carry several + // signals. Try to find that one. + if(signals.size() > 1) + { + bool found = false; + json_object_iterator iter = json_object_iter_begin(event_obj); + json_object_iterator iterEnd = json_object_iter_end(event_obj); + while(!json_object_iter_equal(&iter, &iterEnd)) + { + json_object *value = json_object_iter_peek_value(&iter); + if(json_object_is_type(value, json_type_string)) + { + std::string name = json_object_get_string(value); + for(auto& sig: signals) + { + if(*sig == name) + { + found = true; + sig->onReceivedCB(event_obj); + } + } + } + json_object_iter_next(&iter); + } + // If nothing found in JSON data then apply onReceived callback + // for all signals found + if(! found) + { + for(auto& sig: signals) + {sig->onReceivedCB(event_obj);} + } + } + else + { + signals[0]->onReceivedCB(event_obj); + } +} + +/// @brief callback for receiving message from low bindings. This will call back +/// an action defined in the configuration files depending on the events +/// received from an API. +/// +/// @param[in] object - an opaq pointer holding userdata +/// @param[in] event - event name +/// @param[in] object - eventual data that comes with the event +/// @param[in] object - the api that subscribed the event +/// +void SourceAPI::onSignalEvents(void *closure, const char *event_name, json_object *event_obj, AFB_ApiT api) +{ + Signal *sig = (Signal*) closure; + sig->onReceivedCB(event_obj); +} + const struct signalsDefault& SourceAPI::signalsDefault() const { return signalsDefault_; @@ -69,13 +144,17 @@ void SourceAPI::addSignal(const std::string& id, const std::string& event, std:: { std::shared_ptr sig = std::make_shared(id, event, depends, unit, metadata, retention, frequency, onReceived, getSignalsArgs); + if(onReceived && ! event.empty()) + afb_api_event_handler_add(afbBindingV3root, event.c_str(), SourceAPI::onSignalEvents, (void*)sig.get()); + newSignalsM_[id] = sig; } void SourceAPI::initSignals() { - Composer& composer = Composer::instance(); int err = 0; + Composer& composer = Composer::instance(); + for(auto& i: newSignalsM_) {i.second->attachToSourceSignals(composer);} -- cgit 1.2.3-korg