2323#include < memory>
2424#include < sstream>
2525#include < string>
26+ #include < unordered_map>
27+ #include < utility>
2628#include < vector>
2729
2830#include " rcl/publisher.h"
@@ -109,9 +111,10 @@ class PublisherBase : public std::enable_shared_from_this<PublisherBase>
109111 get_publisher_handle () const ;
110112
111113 // / Get all the QoS event handlers associated with this publisher.
112- /* * \return The vector of QoS event handlers. */
114+ /* * \return The map of QoS event handlers. */
113115 RCLCPP_PUBLIC
114- const std::vector<std::shared_ptr<rclcpp::QOSEventHandlerBase>> &
116+ const
117+ std::unordered_map<rcl_publisher_event_type_t , std::shared_ptr<rclcpp::QOSEventHandlerBase>> &
115118 get_event_handlers () const ;
116119
117120 // / Get subscription count
@@ -193,6 +196,71 @@ class PublisherBase : public std::enable_shared_from_this<PublisherBase>
193196 uint64_t intra_process_publisher_id,
194197 IntraProcessManagerSharedPtr ipm);
195198
199+ // / Set a callback to be called when each new qos event instance occurs.
200+ /* *
201+ * The callback receives a size_t which is the number of events that occurred
202+ * since the last time this callback was called.
203+ * Normally this is 1, but can be > 1 if events occurred before any
204+ * callback was set.
205+ *
206+ * Since this callback is called from the middleware, you should aim to make
207+ * it fast and not blocking.
208+ * If you need to do a lot of work or wait for some other event, you should
209+ * spin it off to another thread, otherwise you risk blocking the middleware.
210+ *
211+ * Calling it again will clear any previously set callback.
212+ *
213+ * An exception will be thrown if the callback is not callable.
214+ *
215+ * This function is thread-safe.
216+ *
217+ * If you want more information available in the callback, like the qos event
218+ * or other information, you may use a lambda with captures or std::bind.
219+ *
220+ * \sa rclcpp::QOSEventHandlerBase::set_on_ready_callback
221+ *
222+ * \param[in] callback functor to be called when a new event occurs
223+ * \param[in] event_type identifier for the qos event we want to attach the callback to
224+ */
225+ void
226+ set_on_new_qos_event_callback (
227+ std::function<void (size_t )> callback,
228+ rcl_publisher_event_type_t event_type)
229+ {
230+ if (event_handlers_.count (event_type) == 0 ) {
231+ RCLCPP_WARN (
232+ rclcpp::get_logger (" rclcpp" ),
233+ " Calling set_on_new_qos_event_callback for non registered event_type" );
234+ return ;
235+ }
236+
237+ if (!callback) {
238+ throw std::invalid_argument (
239+ " The callback passed to set_on_new_qos_event_callback "
240+ " is not callable." );
241+ }
242+
243+ // The on_ready_callback signature has an extra `int` argument used to disambiguate between
244+ // possible different entities within a generic waitable.
245+ // We hide that detail to users of this method.
246+ std::function<void (size_t , int )> new_callback = std::bind (callback, std::placeholders::_1);
247+ event_handlers_[event_type]->set_on_ready_callback (new_callback);
248+ }
249+
250+ // / Unset the callback registered for new qos events, if any.
251+ void
252+ clear_on_new_qos_event_callback (rcl_publisher_event_type_t event_type)
253+ {
254+ if (event_handlers_.count (event_type) == 0 ) {
255+ RCLCPP_WARN (
256+ rclcpp::get_logger (" rclcpp" ),
257+ " Calling clear_on_new_qos_event_callback for non registered event_type" );
258+ return ;
259+ }
260+
261+ event_handlers_[event_type]->clear_on_ready_callback ();
262+ }
263+
196264protected:
197265 template <typename EventCallbackT>
198266 void
@@ -206,7 +274,7 @@ class PublisherBase : public std::enable_shared_from_this<PublisherBase>
206274 rcl_publisher_event_init,
207275 publisher_handle_,
208276 event_type);
209- event_handlers_.emplace_back ( handler);
277+ event_handlers_.insert ( std::make_pair (event_type, handler) );
210278 }
211279
212280 RCLCPP_PUBLIC
@@ -216,7 +284,8 @@ class PublisherBase : public std::enable_shared_from_this<PublisherBase>
216284
217285 std::shared_ptr<rcl_publisher_t > publisher_handle_;
218286
219- std::vector<std::shared_ptr<rclcpp::QOSEventHandlerBase>> event_handlers_;
287+ std::unordered_map<rcl_publisher_event_type_t ,
288+ std::shared_ptr<rclcpp::QOSEventHandlerBase>> event_handlers_;
220289
221290 using IntraProcessManagerWeakPtr =
222291 std::weak_ptr<rclcpp::experimental::IntraProcessManager>;
0 commit comments