diff --git a/ipaacalib/cpp/CMakeLists.txt b/ipaacalib/cpp/CMakeLists.txt index ba3a102a656772ccebc65ac8d8496efcd68c9676..55395cc91303cd8c08a4ce372d2e6f4c519fb84b 100644 --- a/ipaacalib/cpp/CMakeLists.txt +++ b/ipaacalib/cpp/CMakeLists.txt @@ -62,6 +62,7 @@ set (SOURCE src/ipaaca.cc src/ipaaca-cmdline-parser.cc src/ipaaca-string-utils.cc + src/util/notifier.cc build/ipaaca/ipaaca.pb.cc ) diff --git a/ipaacalib/cpp/include/ipaaca/util/notifier.h b/ipaacalib/cpp/include/ipaaca/util/notifier.h new file mode 100644 index 0000000000000000000000000000000000000000..1a5d4e898848ab6e7c2f81c4089d6290f77d8cb5 --- /dev/null +++ b/ipaacalib/cpp/include/ipaaca/util/notifier.h @@ -0,0 +1,56 @@ +#ifndef __IPAACA_UTIL_NOTIFIER_H__ +#define __IPAACA_UTIL_NOTIFIER_H__ + +#include <ipaaca/ipaaca.h> + +#define _IPAACA_COMP_NOTIF_CATEGORY "componentNotify" + +#define _IPAACA_COMP_NOTIF_NAME "name" +#define _IPAACA_COMP_NOTIF_FUNCTION "function" +#define _IPAACA_COMP_NOTIF_STATE "state" +#define _IPAACA_COMP_NOTIF_SEND_CATS "send_categories" +#define _IPAACA_COMP_NOTIF_RECV_CATS "receive_categories" + +#define _IPAACA_COMP_NOTIF_STATE_NEW "new" +#define _IPAACA_COMP_NOTIF_STATE_OLD "old" +#define _IPAACA_COMP_NOTIF_STATE_DOWN "down" + +namespace ipaaca { +namespace util { + +class ComponentNotifier { + protected: + ComponentNotifier(const std::string& componentName, const std::string& componentFunction, const std::set<std::string>& sendCategories, const std::set<std::string>& receiveCategories); + ComponentNotifier(const std::string& componentName, const std::string& componentFunction, const std::set<std::string>& sendCategories, const std::set<std::string>& receiveCategories, ipaaca::OutputBuffer::ptr out_buf, ipaaca::InputBuffer::ptr in_buf); + public: + static boost::shared_ptr<ComponentNotifier> create(const std::string& componentName, const std::string& componentFunction, const std::set<std::string>& sendCategories, const std::set<std::string>& receiveCategories); + static boost::shared_ptr<ComponentNotifier> create(const std::string& componentName, const std::string& componentFunction, const std::set<std::string>& sendCategories, const std::set<std::string>& receiveCategories, ipaaca::OutputBuffer::ptr out_buf, ipaaca::InputBuffer::ptr in_buf); + public: + ~ComponentNotifier(); + protected: + void submit_notify(const std::string& current_state); + void handle_iu_event(ipaaca::IUInterface::ptr iu, ipaaca::IUEventType event_type, bool local); + public: + void add_notification_handler(ipaaca::IUEventHandlerFunction function); + void initialize(); + protected: + ipaaca::OutputBuffer::ptr out_buf; + ipaaca::InputBuffer::ptr in_buf; + ipaaca::Lock lock; + bool initialized; + std::vector<ipaaca::IUEventHandlerFunction> _handlers; + protected: + std::string name; + std::string function; + std::string state; + std::string send_categories; + std::string recv_categories; + public: + typedef boost::shared_ptr<ComponentNotifier> ptr; +}; + + +}} // of namespace ipaaca::util + +#endif + diff --git a/ipaacalib/cpp/src/util/notifier.cc b/ipaacalib/cpp/src/util/notifier.cc new file mode 100644 index 0000000000000000000000000000000000000000..a295e87ee64724e4082155bbf15a4d024740167e --- /dev/null +++ b/ipaacalib/cpp/src/util/notifier.cc @@ -0,0 +1,88 @@ +#include <ipaaca/util/notifier.h> + +namespace ipaaca { +namespace util { + +ComponentNotifier::~ComponentNotifier() +{ + if (initialized) { + submit_notify(_IPAACA_COMP_NOTIF_STATE_DOWN); + } +} + +ComponentNotifier::ComponentNotifier(const std::string& componentName, const std::string& componentFunction, const std::set<std::string>& sendCategories, const std::set<std::string>& recvCategories) +: initialized(false), name(componentName), function(componentFunction) +{ + send_categories = ipaaca::str_join(sendCategories, ","); + recv_categories = ipaaca::str_join(recvCategories, ","); + // create private in/out buffer pair since none was specified + out_buf = ipaaca::OutputBuffer::create(componentName); + in_buf = ipaaca::InputBuffer::create(componentName, _IPAACA_COMP_NOTIF_CATEGORY); +} + +ComponentNotifier::ComponentNotifier(const std::string& componentName, const std::string& componentFunction, const std::set<std::string>& sendCategories, const std::set<std::string>& receiveCategories, ipaaca::OutputBuffer::ptr outBuf, ipaaca::InputBuffer::ptr inBuf) +: initialized(false), name(componentName), function(componentFunction), out_buf(outBuf), in_buf(inBuf) +{ + send_categories = ipaaca::str_join(sendCategories, ","); + recv_categories = ipaaca::str_join(receiveCategories, ","); +} + +ComponentNotifier::ptr ComponentNotifier::create(const std::string& componentName, const std::string& componentFunction, const std::set<std::string>& sendCategories, const std::set<std::string>& recvCategories) +{ + return ComponentNotifier::ptr(new ComponentNotifier(componentName, componentFunction, sendCategories, recvCategories)); +} +ComponentNotifier::ptr ComponentNotifier::create(const std::string& componentName, const std::string& componentFunction, const std::set<std::string>& sendCategories, const std::set<std::string>& recvCategories, ipaaca::OutputBuffer::ptr outBuf, ipaaca::InputBuffer::ptr inBuf) +{ + return ComponentNotifier::ptr(new ComponentNotifier(componentName, componentFunction, sendCategories, recvCategories, outBuf, inBuf)); +} + +void ComponentNotifier::handle_iu_event(IUInterface::ptr iu, IUEventType event_type, bool local) +{ + //std::cout << "handle_iu_event: got an event" << std::endl; + if ((event_type == IU_ADDED) || (event_type == IU_UPDATED) || (event_type == IU_MESSAGE)) { + Locker locker(lock); + std::string cName = iu->payload()[_IPAACA_COMP_NOTIF_NAME]; + std::string cState = iu->payload()[_IPAACA_COMP_NOTIF_STATE]; + if (cName != name) { + //std::cout << " handle_iu_event: calling notification handlers" << std::endl; + // call all registered notification handlers + for (std::vector<IUEventHandlerFunction>::iterator it = _handlers.begin(); it != _handlers.end(); ++it) { + (*it)(iu, event_type, local); + } + // send own info only if the remote component is a newly initialized one + if (cState=="new") { + //std::cout << " handle_iu_event: Submitting own notification to new remote end" << std::endl; + submit_notify(_IPAACA_COMP_NOTIF_STATE_OLD); + } + } + } +} + +void ComponentNotifier::add_notification_handler(ipaaca::IUEventHandlerFunction function) +{ + Locker locker(lock); + _handlers.push_back(function); +} + +void ComponentNotifier::submit_notify(const std::string& current_state) +{ + ipaaca::Message::ptr iu = ipaaca::Message::create(_IPAACA_COMP_NOTIF_CATEGORY); + iu->payload()[_IPAACA_COMP_NOTIF_NAME] = name; + iu->payload()[_IPAACA_COMP_NOTIF_STATE] = current_state; + iu->payload()[_IPAACA_COMP_NOTIF_FUNCTION] = function; + iu->payload()[_IPAACA_COMP_NOTIF_SEND_CATS] = send_categories; + iu->payload()[_IPAACA_COMP_NOTIF_RECV_CATS] = recv_categories; + out_buf->add(iu); +} + +void ComponentNotifier::initialize() { + Locker locker(lock); + if (!initialized) { + initialized = true; + in_buf->register_handler(boost::bind(&ComponentNotifier::handle_iu_event, this, _1, _2, _3)); + submit_notify(_IPAACA_COMP_NOTIF_STATE_NEW); + } +} + +}} + diff --git a/ipaacalib/cpp/test/CMakeLists.txt b/ipaacalib/cpp/test/CMakeLists.txt index 938f9e56f70692a3b783bfbc029b18c3743e4654..48a93b3076055ea696023cad76ca03d201e024ab 100644 --- a/ipaacalib/cpp/test/CMakeLists.txt +++ b/ipaacalib/cpp/test/CMakeLists.txt @@ -41,9 +41,14 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_OLD_CODE_CONVENIENCE_FLAGS} ${CXX_ # add local include directory include_directories( ${PROJECT_SOURCE_DIR}/include ) +# add includes and builds from parent dir (ipaaca lib) +include_directories( ${PROJECT_SOURCE_DIR}/../include ) +include_directories( ${PROJECT_SOURCE_DIR}/../build ) +link_directories( ${PROJECT_SOURCE_DIR}/../build ) + # add lib and include directory from pulled dependencies -include_directories( ${PROJECT_SOURCE_DIR}/../../../dist/include ) -link_directories( ${PROJECT_SOURCE_DIR}/../../../dist/lib ) +include_directories( ${PROJECT_SOURCE_DIR}/../../../deps/include ) +link_directories( ${PROJECT_SOURCE_DIR}/../../../deps/lib ) # specify source files for ipaaca (auto-generated ones are in build/ ) set (SOURCE diff --git a/ipaacalib/python/src/ipaaca/util/notifier.py b/ipaacalib/python/src/ipaaca/util/notifier.py index 7f3f832af9339ac5b0ecb8639327707b07508ec5..227b90c85ae14114e55ef992d910fb2f7e764b67 100644 --- a/ipaacalib/python/src/ipaaca/util/notifier.py +++ b/ipaacalib/python/src/ipaaca/util/notifier.py @@ -50,15 +50,15 @@ class ComponentNotifier(object): self.outBuffer.add(notifyIU) def _handle_iu_event(self, iu, event_type, local): - print("handle, iuname:"+iu.payload[ComponentNotifier.NAME]+" component name: "+self.componentName+" state "+iu.payload[ComponentNotifier.STATE]) + #print("handle, iuname:"+iu.payload[ComponentNotifier.NAME]+" component name: "+self.componentName+" state "+iu.payload[ComponentNotifier.STATE]) if iu.payload[ComponentNotifier.NAME] == self.componentName: return with self.notificationHandlerLock: for h in self.notificationHandlers: h(iu, event_type, local) if iu.payload[ComponentNotifier.STATE] == "new": - print("submitting") - self._submit_notify(False) + #print("submitting") + self._submit_notify(False) def add_notification_handler(self, handler): with self.notificationHandlerLock: