15 #ifndef RCLCPP__EVENT_HANDLER_HPP_
16 #define RCLCPP__EVENT_HANDLER_HPP_
26 #include "rcl/error_handling.h"
27 #include "rcl/event_callback.h"
28 #include "rmw/impl/cpp/demangle.hpp"
29 #include "rmw/incompatible_qos_events_statuses.h"
30 #include "rmw/events_statuses/incompatible_type.h"
32 #include "rcutils/logging_macros.h"
34 #include "rclcpp/detail/cpp_callback_trampoline.hpp"
35 #include "rclcpp/exceptions.hpp"
36 #include "rclcpp/function_traits.hpp"
37 #include "rclcpp/logging.hpp"
38 #include "rclcpp/waitable.hpp"
43 using QOSDeadlineRequestedInfo = rmw_requested_deadline_missed_status_t;
44 using QOSDeadlineOfferedInfo = rmw_offered_deadline_missed_status_t;
45 using QOSLivelinessChangedInfo = rmw_liveliness_changed_status_t;
46 using QOSLivelinessLostInfo = rmw_liveliness_lost_status_t;
47 using QOSMessageLostInfo = rmw_message_lost_status_t;
48 using QOSOfferedIncompatibleQoSInfo = rmw_offered_qos_incompatible_event_status_t;
49 using QOSRequestedIncompatibleQoSInfo = rmw_requested_qos_incompatible_event_status_t;
51 using IncompatibleTypeInfo = rmw_incompatible_type_status_t;
52 using MatchedInfo = rmw_matched_status_t;
54 using QOSDeadlineRequestedCallbackType = std::function<void (QOSDeadlineRequestedInfo &)>;
55 using QOSDeadlineOfferedCallbackType = std::function<void (QOSDeadlineOfferedInfo &)>;
56 using QOSLivelinessChangedCallbackType = std::function<void (QOSLivelinessChangedInfo &)>;
57 using QOSLivelinessLostCallbackType = std::function<void (QOSLivelinessLostInfo &)>;
58 using QOSMessageLostCallbackType = std::function<void (QOSMessageLostInfo &)>;
59 using QOSOfferedIncompatibleQoSCallbackType = std::function<void (QOSOfferedIncompatibleQoSInfo &)>;
60 using QOSRequestedIncompatibleQoSCallbackType =
61 std::function<void (QOSRequestedIncompatibleQoSInfo &)>;
63 using IncompatibleTypeCallbackType = std::function<void (IncompatibleTypeInfo &)>;
64 using PublisherMatchedCallbackType = std::function<void (MatchedInfo &)>;
65 using SubscriptionMatchedCallbackType = std::function<void (MatchedInfo &)>;
70 QOSDeadlineOfferedCallbackType deadline_callback;
71 QOSLivelinessLostCallbackType liveliness_callback;
72 QOSOfferedIncompatibleQoSCallbackType incompatible_qos_callback;
73 IncompatibleTypeCallbackType incompatible_type_callback;
74 PublisherMatchedCallbackType matched_callback;
80 QOSDeadlineRequestedCallbackType deadline_callback;
81 QOSLivelinessChangedCallbackType liveliness_callback;
82 QOSRequestedIncompatibleQoSCallbackType incompatible_qos_callback;
83 QOSMessageLostCallbackType message_lost_callback;
84 IncompatibleTypeCallbackType incompatible_type_callback;
85 SubscriptionMatchedCallbackType matched_callback;
94 const rcl_error_state_t * error_state,
95 const std::string & prefix);
100 const std::string & prefix);
106 enum class EntityType : std::size_t
177 throw std::invalid_argument(
178 "The callback passed to set_on_ready_callback "
184 [callback,
this](
size_t number_of_events) {
186 callback(number_of_events,
static_cast<int>(EntityType::Event));
187 }
catch (
const std::exception & exception) {
191 "rclcpp::EventHandlerBase@" <<
this <<
192 " caught " << rmw::impl::cpp::demangle(exception) <<
193 " exception in user-provided callback for the 'on ready' callback: " <<
198 "rclcpp::EventHandlerBase@" <<
this <<
199 " caught unhandled exception in user-provided callback " <<
200 "for the 'on ready' callback");
204 std::lock_guard<std::recursive_mutex> lock(on_new_event_callback_mutex_);
209 set_on_new_event_callback(
210 rclcpp::detail::cpp_callback_trampoline<decltype(new_callback),
const void *,
size_t>,
211 static_cast<const void *
>(&new_callback));
214 on_new_event_callback_ = new_callback;
217 set_on_new_event_callback(
218 rclcpp::detail::cpp_callback_trampoline<
219 decltype(on_new_event_callback_),
const void *,
size_t>,
220 static_cast<const void *
>(&on_new_event_callback_));
227 std::lock_guard<std::recursive_mutex> lock(on_new_event_callback_mutex_);
228 if (on_new_event_callback_) {
229 set_on_new_event_callback(
nullptr,
nullptr);
230 on_new_event_callback_ =
nullptr;
235 std::vector<std::shared_ptr<rclcpp::TimerBase>>
244 set_on_new_event_callback(rcl_event_callback_t callback,
const void * user_data);
246 std::recursive_mutex on_new_event_callback_mutex_;
247 std::function<void(
size_t)> on_new_event_callback_{
nullptr};
250 size_t wait_set_event_index_;
253 template<
typename EventCallbackT,
typename ParentHandleT>
257 template<
typename InitFuncT,
typename EventTypeEnum>
259 const EventCallbackT & callback,
261 ParentHandleT parent_handle,
262 EventTypeEnum event_type)
263 : parent_handle_(parent_handle), event_callback_(callback)
266 rcl_ret_t ret = init_func(&event_handle_, parent_handle.get(), event_type);
273 rclcpp::exceptions::throw_from_rcl_error(ret,
"Failed to initialize event");
289 std::shared_ptr<void>
292 EventCallbackInfoT callback_info;
295 RCUTILS_LOG_ERROR_NAMED(
297 "Couldn't take event info: %s", rcl_get_error_string().str);
301 return std::static_pointer_cast<void>(std::make_shared<EventCallbackInfoT>(callback_info));
304 std::shared_ptr<void>
305 take_data_by_entity_id([[maybe_unused]]
size_t id)
override
312 execute(
const std::shared_ptr<void> & data)
override
314 std::unique_lock<std::mutex> event_callback_lock(event_callback_mutex_);
315 if (disabled_.load()) {
319 throw std::runtime_error(
"'data' is empty");
321 auto callback_ptr = std::static_pointer_cast<EventCallbackInfoT>(data);
322 event_callback_(*callback_ptr);
323 callback_ptr.reset();
335 std::lock_guard<std::recursive_mutex> on_new_event_lock(on_new_event_callback_mutex_);
336 if (on_new_event_callback_) {
337 set_on_new_event_callback(
nullptr,
nullptr);
340 std::lock_guard<std::mutex> event_callback_lock(event_callback_mutex_);
341 disabled_.store(
true);
353 std::lock_guard<std::recursive_mutex> on_new_event_lock(on_new_event_callback_mutex_);
354 if (on_new_event_callback_) {
355 set_on_new_event_callback(
356 rclcpp::detail::cpp_callback_trampoline<
357 decltype(on_new_event_callback_),
const void *,
size_t>,
358 static_cast<const void *
>(&on_new_event_callback_));
361 std::lock_guard<std::mutex> event_callback_lock(event_callback_mutex_);
362 disabled_.store(
false);
366 using EventCallbackInfoT =
typename std::remove_reference<
typename
369 ParentHandleT parent_handle_;
370 EventCallbackT event_callback_;
371 std::mutex event_callback_mutex_;
372 std::atomic_bool disabled_{
false};
RCLCPP_PUBLIC size_t get_number_of_ready_events() override
Get the number of ready events.
RCLCPP_PUBLIC void add_to_wait_set(rcl_wait_set_t &wait_set) override
Add the Waitable to a wait set.
void set_on_ready_callback(std::function< void(size_t, int)> callback) override
Set a callback to be called when each new event instance occurs.
RCLCPP_PUBLIC std::vector< std::shared_ptr< rclcpp::TimerBase > > get_timers() const override
Returns all timers used by this waitable.
RCLCPP_PUBLIC bool is_ready(const rcl_wait_set_t &wait_set) override
Check if the Waitable is ready.
void clear_on_ready_callback() override
Unset the callback registered for new events, if any.
void disable() override
Disable the event callback from being called when execute(..) invoked.
void enable() override
Enable the event callback to be called when execute(..) invoked.
void execute(const std::shared_ptr< void > &data) override
Execute any entities of the Waitable that are ready.
std::shared_ptr< void > take_data() override
Take data so that the callback cannot be scheduled again.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_take_event(const rcl_event_t *event, void *event_info)
RCL_PUBLIC RCL_WARN_UNUSED rcl_event_t rcl_get_zero_initialized_event(void)
Return a rcl_event_t struct with members set to NULL.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Structure which encapsulates a ROS QoS event handle.
Container for subscription's, guard condition's, etc to be waited on.
Contains callbacks for various types of events a Publisher can receive from the middleware.
Contains callbacks for non-message events that a Subscription can receive from the middleware.
#define RCL_RET_UNSUPPORTED
Unsupported return code.
#define RCL_RET_OK
Success return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.