2424#include < memory>
2525#include < stdexcept>
2626#include < string>
27+ #include < utility>
2728
2829#include " exceptions.hpp"
2930#include " node.hpp"
3031#include " serialization.hpp"
3132#include " subscription.hpp"
3233#include " utils.hpp"
34+ #include " events_executor/rcl_support.hpp"
3335
3436using pybind11::literals::operator " " _a;
3537
3638namespace rclpy
3739{
40+ using events_executor::RclEventCallbackTrampoline;
41+
3842Subscription::Subscription (
3943 Node & node, py::object pymsg_type, std::string topic,
4044 py::object pyqos_profile)
@@ -87,6 +91,10 @@ Subscription::Subscription(
8791
8892void Subscription::destroy ()
8993{
94+ try {
95+ clear_on_new_message_callback ();
96+ } catch (RCLError) {
97+ }
9098 rcl_subscription_.reset ();
9199 node_.destroy ();
92100}
@@ -194,6 +202,41 @@ Subscription::get_publisher_count() const
194202 return count;
195203}
196204
205+ void
206+ Subscription::set_callback (
207+ rcl_event_callback_t callback,
208+ const void * user_data)
209+ {
210+ rcl_ret_t ret = rcl_subscription_set_on_new_message_callback (
211+ rcl_subscription_.get (),
212+ callback,
213+ user_data);
214+
215+ if (RCL_RET_OK != ret) {
216+ throw RCLError (std::string (" Failed to set the on new message callback for subscription: " ) +
217+ rcl_get_error_string ().str );
218+ }
219+ }
220+
221+ void
222+ Subscription::set_on_new_message_callback (std::function<void (size_t )> callback)
223+ {
224+ clear_on_new_message_callback ();
225+ on_new_message_callback_ = std::move (callback);
226+ set_callback (
227+ RclEventCallbackTrampoline,
228+ static_cast <const void *>(&on_new_message_callback_));
229+ }
230+
231+ void
232+ Subscription::clear_on_new_message_callback ()
233+ {
234+ if (on_new_message_callback_) {
235+ set_callback (nullptr , nullptr );
236+ on_new_message_callback_ = nullptr ;
237+ }
238+ }
239+
197240void
198241define_subscription (py::object module )
199242{
@@ -215,6 +258,10 @@ define_subscription(py::object module)
215258 " Return the resolved topic name of a subscription." )
216259 .def (
217260 " get_publisher_count" , &Subscription::get_publisher_count,
218- " Count the publishers from a subscription." );
261+ " Count the publishers from a subscription." )
262+ .def (
263+ " set_on_new_message_callback" , &Subscription::set_on_new_message_callback,
264+ py::arg (" callback" ))
265+ .def (" clear_on_new_message_callback" , &Subscription::clear_on_new_message_callback);
219266}
220267} // namespace rclpy
0 commit comments