ctkEventBusManager.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * ctkEventBusManager.cpp
  3. * ctkEventBus
  4. *
  5. * Created by Paolo Quadrani on 27/03/09.ctkEventBusManager * Copyright 2010 B3C. All rights reserved.
  6. *
  7. * See Licence at: http://tiny.cc/QXJ4D
  8. *
  9. */
  10. #include "ctkEventBusManager.h"
  11. #include "ctkTopicRegistry.h"
  12. #include "ctkNetworkConnectorQtSoap.h"
  13. #include "ctkNetworkConnectorQXMLRPC.h"
  14. using namespace ctkEventBus;
  15. ctkEventBusManager::ctkEventBusManager() : m_EnableEventLogging(false), m_LogEventTopic("*"), m_SkipDetach(false) {
  16. // Create local event dispatcher.
  17. m_LocalDispatcher = new ctkEventDispatcherLocal();
  18. m_LocalDispatcher->setObjectName("Local Event Dispatcher");
  19. // Create the remote event dispatcher.
  20. m_RemoteDispatcher = new ctkEventDispatcherRemote();
  21. m_RemoteDispatcher->setObjectName("Remote Event Dispatcher");
  22. }
  23. ctkEventBusManager::~ctkEventBusManager() {
  24. ctkNetworkConnectorHash::iterator i = m_NetworkConnectorHash.begin();
  25. while(i != m_NetworkConnectorHash.end()) {
  26. delete i.value();
  27. ++i;
  28. }
  29. m_NetworkConnectorHash.clear();
  30. //disconnet detachFromEventBus
  31. m_SkipDetach = true;
  32. if(m_LocalDispatcher) {
  33. m_LocalDispatcher->resetHashes();
  34. delete m_LocalDispatcher;
  35. }
  36. if(m_RemoteDispatcher) {
  37. m_RemoteDispatcher->resetHashes();
  38. delete m_RemoteDispatcher;
  39. }
  40. }
  41. void ctkEventBusManager::plugNetworkConnector(const QString &protocol, ctkNetworkConnector *connector) {
  42. m_NetworkConnectorHash.insert(protocol, connector);
  43. }
  44. bool ctkEventBusManager::isLocalSignalPresent(const QString topic) const {
  45. return m_LocalDispatcher->isLocalSignalPresent(topic);
  46. }
  47. ctkEventBusManager* ctkEventBusManager::instance() {
  48. static ctkEventBusManager instanceEventBus;
  49. return &instanceEventBus;
  50. }
  51. void ctkEventBusManager::shutdown() {
  52. ctkEventBus::ctkTopicRegistry::instance()->shutdown();
  53. }
  54. void ctkEventBusManager::initializeNetworkConnectors() {
  55. plugNetworkConnector("SOAP", new ctkNetworkConnectorQtSoap());
  56. plugNetworkConnector("XMLRPC", new ctkNetworkConnectorQXMLRPC());
  57. }
  58. bool ctkEventBusManager::addEventProperty(ctkBusEvent &props) const {
  59. bool result(false);
  60. QString topic = props[TOPIC].toString();
  61. QObject *obj = props[OBJECT].value<QObject*>();
  62. if(props[TYPE].toInt() == ctkEventTypeLocal) {
  63. // Local event dispatching.
  64. if(props[SIGTYPE].toInt() == ctkSignatureTypeCallback) {
  65. result = m_LocalDispatcher->addObserver(props);
  66. } else {
  67. //Add topic to the ctkTopicRegistry
  68. result = ctkEventBus::ctkTopicRegistry::instance()->registerTopic(topic, obj);
  69. if(!result) {
  70. return result;
  71. }
  72. result = m_LocalDispatcher->registerSignal(props);
  73. }
  74. } else {
  75. // Remote event dispatching.
  76. if(props[SIGTYPE].toInt() == ctkSignatureTypeCallback) {
  77. result = m_RemoteDispatcher->addObserver(props);
  78. } else {
  79. //Add topic to the ctkTopicRegistry
  80. result = ctkEventBus::ctkTopicRegistry::instance()->registerTopic(topic, obj);
  81. if(!result) {
  82. return result;
  83. }
  84. result = m_RemoteDispatcher->registerSignal(props);
  85. }
  86. }
  87. result = connect(obj, SIGNAL(destroyed()), this, SLOT(detachObjectFromBus()));
  88. return result;
  89. }
  90. void ctkEventBusManager::detachObjectFromBus() {
  91. if(m_SkipDetach) {
  92. return;
  93. }
  94. QObject *obj = QObject::sender();
  95. removeObserver(obj, "", false);
  96. removeSignal(obj, "", false);
  97. }
  98. void ctkEventBusManager::removeObserver(const QObject *obj, const QString topic, bool qt_disconnect) {
  99. if(obj == NULL) {
  100. return;
  101. }
  102. m_LocalDispatcher->removeObserver(obj, topic, qt_disconnect);
  103. m_RemoteDispatcher->removeObserver(obj, topic, qt_disconnect);
  104. }
  105. void ctkEventBusManager::removeSignal(const QObject *obj, QString topic, bool qt_disconnect) {
  106. if(obj == NULL) {
  107. return;
  108. }
  109. //remove topic from the ctkTopicRegistry
  110. bool result = ctkEventBus::ctkTopicRegistry::instance()->unregisterTopic(topic);
  111. if(result) {
  112. return;
  113. }
  114. m_LocalDispatcher->removeSignal(obj, topic, qt_disconnect);
  115. m_RemoteDispatcher->removeSignal(obj, topic, qt_disconnect);
  116. }
  117. bool ctkEventBusManager::removeEventProperty(ctkBusEvent &props) const {
  118. if(props.eventType() == ctkEventTypeLocal) {
  119. // Local event dispatching.
  120. if(props[SIGTYPE].toInt() == ctkSignatureTypeCallback) {
  121. return m_LocalDispatcher->removeObserver(props);
  122. } else {
  123. return m_LocalDispatcher->removeSignal(props);
  124. }
  125. } else {
  126. // Remote event dispatching.
  127. if(props[SIGTYPE].toInt() == ctkSignatureTypeCallback) {
  128. return m_RemoteDispatcher->removeObserver(props);
  129. } else {
  130. return m_RemoteDispatcher->removeSignal(props);
  131. }
  132. }
  133. return false;
  134. }
  135. void ctkEventBusManager::notifyEvent(const QString topic, ctkEventType ev_type, ctkEventArgumentsList *argList, ctkGenericReturnArgument *returnArg) const {
  136. if(m_EnableEventLogging) {
  137. if(m_LogEventTopic == "*" || m_LogEventTopic == topic) {
  138. qDebug() << tr("Event notification for TOPIC: %1").arg(topic);
  139. }
  140. }
  141. //event dispatched in local channel
  142. ctkBusEvent *event_dic = new ctkBusEvent(topic, ev_type, 0, NULL, "");
  143. /*(*event_dic)[TOPIC] = topic;
  144. (*event_dic)[TYPE] = static_cast<int>(ev_type);*/
  145. notifyEvent(*event_dic, argList, returnArg);
  146. delete event_dic;
  147. }
  148. void ctkEventBusManager::notifyEvent(ctkBusEvent &event_dictionary, ctkEventArgumentsList *argList, ctkGenericReturnArgument *returnArg) const {
  149. //event dispatched in remote channel
  150. if(event_dictionary[TYPE].toInt() == ctkEventTypeLocal) {
  151. m_LocalDispatcher->notifyEvent(event_dictionary, argList, returnArg);
  152. } else {
  153. m_RemoteDispatcher->notifyEvent(event_dictionary, argList);
  154. }
  155. }
  156. void ctkEventBusManager::enableEventLogging(bool enable) {
  157. m_EnableEventLogging = enable;
  158. }
  159. void ctkEventBusManager::logEventTopic(const QString topic) {
  160. m_LogEventTopic = topic;
  161. }
  162. void ctkEventBusManager::logAllEvents() {
  163. m_LogEventTopic = "*";
  164. }
  165. bool ctkEventBusManager::createServer(const QString &communication_protocol, unsigned int listen_port) {
  166. if(m_NetworkConnectorHash.count() == 0) {
  167. initializeNetworkConnectors();
  168. }
  169. bool res(m_NetworkConnectorHash.contains(communication_protocol));
  170. if(res) {
  171. ctkNetworkConnector *connector = m_NetworkConnectorHash.value(communication_protocol);
  172. m_RemoteDispatcher->setNetworkConnectorServer(connector);
  173. //ctkNetworkConnector *connector = m_RemoteDispatcher->networkConnectorServer();
  174. res = connector != NULL;
  175. if(res) {
  176. m_RemoteDispatcher->networkConnectorServer()->createServer(listen_port);
  177. }
  178. }
  179. return res;
  180. }
  181. void ctkEventBusManager::startListen() {
  182. ctkNetworkConnector *connector = m_RemoteDispatcher->networkConnectorServer();
  183. if(connector) {
  184. connector->startListen();
  185. } else {
  186. qWarning("%s", tr("Server can not start. Create it first, then call startListen again!!").toLatin1().data());
  187. }
  188. }
  189. bool ctkEventBusManager::createClient(const QString &communication_protocol, const QString &server_host, unsigned int port) {
  190. if(m_NetworkConnectorHash.count() == 0) {
  191. initializeNetworkConnectors();
  192. }
  193. bool res(m_NetworkConnectorHash.contains(communication_protocol));
  194. if(res) {
  195. m_RemoteDispatcher->setNetworkConnectorClient(m_NetworkConnectorHash.value(communication_protocol));
  196. ctkNetworkConnector *connector = m_RemoteDispatcher->networkConnectorClient();
  197. res = connector != NULL;
  198. if(res) {
  199. m_RemoteDispatcher->networkConnectorClient()->createClient(server_host, port);
  200. }
  201. }
  202. return res;
  203. }