CTKPluginFramework_EventAdmin.dox 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /**
  2. \page PluginFramework_EventAdmin_Page Event Admin
  3. The Event Admin Service Specification, part of the OSGi Compendium specification,
  4. defines a general inter-plug-in communication mechanism. The communication conforms
  5. to the popular publish/subscribe paradigm and can be performed in a synchronous
  6. or asysnchronous manner.
  7. The main components in a publish/subscribe communication are:
  8. - <b>Event Publisher</b> - sends events or messages related to a specific topic
  9. - <b>Event Handler</b> (or Subscriber) - expresses interest in one or more topics and
  10. receives all the messages belonging to such topics.
  11. Events are composed of two attributes:
  12. - A \b topic defining the nature of the event. Topic names are usually arranged in a hierarchical namespace, where slashes are used to separate the levels (i.e. "org/commontk/PluginFrameworkEvent/STARTED") and
  13. - A set of \b properties describing the event.
  14. Read the <a href="http://www.osgi.org/Download/File?url=/download/r4v42/r4.cmpn.pdf">
  15. EventAdmin Service Specifications</a> (Chapter 113) for an in-depth explanation.
  16. \section EventAdmin_CreatePublisher Creating an Event Publisher
  17. An event publisher can either be a simple C++ class that creates events and sends
  18. them using the <code>ctkEventAdmin</code> service interface or a Qt signal which
  19. is registered as a "publisher" using the <code>ctkEventAdmin</code> service
  20. interface.
  21. \subsection EventAdmin_CreatePublisher_Class Using a simple C++ class
  22. The publisher is a function which creates a <code>ctkEvent</code> object and
  23. sends it by using the <code>ctkEventAdmin</code> service interface.
  24. \snippet EventAdmin-Intro/ctkSnippetReportManager.h Publish event
  25. The <code>ctkEventAdmin::sendEvent()</code> method sends the <code>ctkEvent</code>
  26. object synchronously. To send it asynchronously, use the <code>ctkEventAdmin::postEvent()</code>
  27. method, such as:
  28. \snippet EventAdmin-Intro/ctkSnippetReportManager.h Publish event async
  29. Synchronous event delivery is significantly more expensive than asynchronous
  30. delivery. Even for synchronous delivery event notifications could be
  31. handled in a separate thread (depending on the EventAdmin implementation). This
  32. implies that <code>sendEvent()</code> callers should generally not hold any
  33. locks when calling this method. Asynchronous delivery should be preferred
  34. over the synchronous delivery.
  35. \subsection EventAdmin_CreatePublisher_Signal Using a Qt signal
  36. Using a Qt signal to publish an event requires declaring a signal and registering (publishing)
  37. it with the Event Admin:
  38. \snippet EventAdmin-Intro/ctkSnippetReportManager.h Declare signal
  39. Register the signal using a specific topic (emitting the signal will always send
  40. <code>ctkEvent</code> objects with this topic as <code>EVENT_TOPIC</code> property):
  41. \snippet EventAdmin-Intro/ctkSnippetReportManager.h Register signal
  42. Emitting the signal will automatically create a <code>ctkEvent</code> object, sending
  43. it synchronuously or asynchronuously, depending on the Qt::ConnectionType used when
  44. publishing the signal.
  45. \snippet EventAdmin-Intro/ctkSnippetReportManager.h Emit signal
  46. \subsection EventAdmin_CreatePublisher_Compare Comparison
  47. The act of sending an event is simplified by using a Qt signal, after it was registered
  48. with the Event Admin. However, the Qt signal approach is less performant since the
  49. signal emission needs to go through the Qt meta object system. Further, the signal is
  50. tied to a specific event topic.
  51. \section EventAdmin_CreateHandler Creating and registering an Event Handler
  52. An event handler can either be a class implementing the <code>ctkEventHandler</code>
  53. interface which is registered as a service object or a Qt slot which is registered
  54. with the Event Admin (subscribed to certain topics).
  55. Event handlers should not spend too long in the event handling method. This will
  56. prevent other handlers from being notified. Long running operations should be executed
  57. in their own thread.
  58. Note that in general, your event handling code will be called from a separate thread.
  59. \subsection EventAdmin_CreateHandler_Service Event Handler as a Service
  60. Create an event handler by implementing the <code>ctkEventHandler</code> interface:
  61. \snippet EventAdmin-Intro/ctkSnippetReportManager.h Event Handler service
  62. To receive event notifications, the event handler must be registered as a service under the
  63. <code>ctkEventHandler</code> interface. When registering the service, a <code>QString</code>
  64. or <code>QStringList</code> property named <code>EVENT_TOPIC</code> must be specified. This
  65. property describes the list of topics in which the event handler is interested. For example:
  66. \snippet EventAdmin-Intro/main.cpp Event Handler service registration
  67. It is possible to use '*' as a wildcard in the final character of the <code>EVENT_TOPIC</code>:
  68. \snippet EventAdmin-Intro/main.cpp Event Handler service registration wildcard
  69. Finally, it is possible to specify an additional <code>EVENT_FILTER</code> property to filter
  70. event notifications. The filter expression follows the normal LDAP syntax:
  71. \snippet EventAdmin-Intro/main.cpp Event Handler service registration filter
  72. \subsection EventAdmin_CreateHandler_Slot Event Handler as a Qt slot
  73. Every Qt slot taking a <code>ctkEvent</code> object as an argument can be subscribed to
  74. receive event notifications. For example, a slot like
  75. \snippet EventAdmin-Intro/ctkSnippetReportManager.h Event Handler slot
  76. can be subscribed to receive events like
  77. \snippet EventAdmin-Intro/main.cpp Event Handler service registration slot
  78. You can use the same expressions for <code>EVENT_TOPIC</code> and
  79. <code>EVENT_FILTER</code> as in the examples above for registering the event
  80. handler as a service object implementing <code>ctkEventHandler</code>.
  81. Using Qt slots as Event Handlers will makes it easy to ensure that the event
  82. handling code is executed in the receiver's thread (the default connection type
  83. is Qt::AutoConnection).
  84. \subsection EventAdmin_CreateHandler_Compare Comparison
  85. Registering an event handler using either the <code>ctkEventHandler</code> interface or
  86. a Qt slot involves approximately the same amount of code. However, using slots
  87. will be less performant (which might be neglectable, depending on your use case) but the
  88. code will be automatically synchronized with the receiver thread.
  89. Further, subscribing slots means that you require a registered Event Admin service implementation.
  90. The <code>ctkEventHandler</code> approach does not need to know anything about the Event
  91. Admin, since you register your handler as a service object in the framework.
  92. */