As seen in Figure 4.4: Listener Class Hierarchy, Listeners for some Entities derive from the Connext DDS Listeners for related Entities. This means that the derived Listener has all of the methods of its parent class. You can install Listeners at all levels of the object hierarchy. At the top is the DomainParticipantListener; only one can be installed in a DomainParticipant. Then every Subscriber and Publisher can have their own Listener. Finally, each Topic, DataReader and DataWriter can have their own listeners. All are optional.
Suppose, however, that an Entity does not install a Listener, or installs a Listener that does not have particular communication status selected in the bitmask. In this case, if/when that particular status changes for that Entity, the corresponding Listener for that Entity’s parent is called. Status changes are “propagated” from child Entity to parent Entity until a Listener is found that is registered for that status. Connext DDS will give up and drop the status-change event only if no Listeners have been installed in the object hierarchy to be called back for the specific status. This is true for plain communication statuses. Read communication statuses are handle somewhat differently, see 4.4.4.1 Processing Read Communication Statuses.
For example, suppose that Connext DDS finds a matching DataWriter for a local DataReader. This event will change the SUBSCRIPTION_MATCHED status. So the local DataReader object is checked to see if the application has installed a listener that handles the SUBSCRIPTION_MATCH status. If not, the Subscriber that created the DataReader is checked to see if it has a listener installed that handles the same event. If not, the DomainParticipant is checked. The DomainParticipantListener methods are called only if none of the descendent Entities of the DomainParticipant have listeners that handle the particular status that has changed. Again, all listeners are optional. Your application does not have to handle any communication statuses.
Table 4.5 Listener Callback Functions lists the callback functions that are available for each Entity’s status listener.
Entity Listener for: |
Callback Functions |
|
---|---|---|
DomainParticipants |
Topics |
on_inconsistent_topic() |
Publishers and DataWriters |
on_liveliness_lost() |
|
on_offered_deadline_missed() |
||
on_offered_incompatible_qos() |
||
on_publication_matched() |
||
on_reliable_reader_activity_changed() |
||
on_reliable_writer_cache_changed() |
||
Subscribers |
on_data_on_readers() |
|
Subscribers and DataReaders |
on_data_available |
|
on_liveliness_changed() |
||
on_requested_deadline_missed() |
||
on_requested_incompatible_qos() |
||
on_sample_lost() |
||
on_sample_rejected() |
||
on_subscription_matched() |
The processing of the DATA_ON_READERS and DATA_AVAILABLE read communication statuses are handled slightly differently since, when new data arrives for a DataReader, both statuses change simultaneously. However, only one, if any, Listener will be called to handle the event.
If there is a Listener installed to handle the DATA_ON_READERS status in the DataReader’s Subscriber or in the DomainParticipant, then that Listener’s on_data_on_readers() function will be called back. The DataReaderListener’s on_data_available() function is called only if the DATA_ON_READERS status is not handle by any relevant listeners.
This can be useful if you have generic processing to do whenever new data arrives for any DataReader. You can execute the generic code in the on_data_on_readers() method, and then dispatch the processing of the actual data to the specific DataReaderListener’s on_data_available() function by calling the notify_datareaders() method on the Subscriber.
For example:
void on_data_on_readers (DDSSubscriber *subscriber)
{ // Do some general processing that needs to be done // whenever new data arrives, but is independent of // any particular DataReader < generic processing code here > // Now dispatch the actual processing of the data // to the specific DataReader for which the data // was received subscriber->notify_datareaders(); }
© 2020 RTI