From 69a763c7963e3fd5282ab850652481517ce2730e Mon Sep 17 00:00:00 2001 From: Tomoya Fujita Date: Wed, 15 Apr 2026 18:20:25 +0900 Subject: [PATCH] add rcl_publisher/subscription_event_type_is_supported(). Signed-off-by: Tomoya Fujita --- rcl/include/rcl/event.h | 48 +++++++++++++++++++++++++++++ rcl/src/rcl/event.c | 59 ++++++++++++++++++++++++++++++++++++ rcl/test/rcl/test_events.cpp | 51 ++++++++++++++++++++++++++++++- 3 files changed, 157 insertions(+), 1 deletion(-) diff --git a/rcl/include/rcl/event.h b/rcl/include/rcl/event.h index 9b7ddaa69..43a5ea4f5 100644 --- a/rcl/include/rcl/event.h +++ b/rcl/include/rcl/event.h @@ -203,6 +203,54 @@ RCL_PUBLIC bool rcl_event_is_valid(const rcl_event_t * event); +/// Check if a publisher event type is supported by the active RMW implementation. +/** + * This API allows application code to introspect at runtime whether a + * particular publisher event type is supported by the currently loaded + * RMW implementation, enabling portable code that adapts gracefully + * when switching between RMW implementations. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] event_type the publisher event type to check + * \return `true` if the event type is supported, `false` otherwise + */ +RCL_PUBLIC +RCL_WARN_UNUSED +bool +rcl_publisher_event_type_is_supported( + const rcl_publisher_event_type_t event_type); + +/// Check if a subscription event type is supported by the active RMW implementation. +/** + * This API allows application code to introspect at runtime whether a + * particular subscription event type is supported by the currently loaded + * RMW implementation, enabling portable code that adapts gracefully + * when switching between RMW implementations. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] event_type the subscription event type to check + * \return `true` if the event type is supported, `false` otherwise + */ +RCL_PUBLIC +RCL_WARN_UNUSED +bool +rcl_subscription_event_type_is_supported( + const rcl_subscription_event_type_t event_type); + /// Set the callback function for the event. /** * This API sets the callback function to be called whenever the diff --git a/rcl/src/rcl/event.c b/rcl/src/rcl/event.c index bd51b8452..dad0836e0 100644 --- a/rcl/src/rcl/event.c +++ b/rcl/src/rcl/event.c @@ -233,6 +233,65 @@ rcl_event_is_valid(const rcl_event_t * event) return true; } +bool +rcl_publisher_event_type_is_supported( + const rcl_publisher_event_type_t event_type) +{ + rmw_event_type_t rmw_event_type = RMW_EVENT_INVALID; + switch (event_type) { + case RCL_PUBLISHER_OFFERED_DEADLINE_MISSED: + rmw_event_type = RMW_EVENT_OFFERED_DEADLINE_MISSED; + break; + case RCL_PUBLISHER_LIVELINESS_LOST: + rmw_event_type = RMW_EVENT_LIVELINESS_LOST; + break; + case RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS: + rmw_event_type = RMW_EVENT_OFFERED_QOS_INCOMPATIBLE; + break; + case RCL_PUBLISHER_INCOMPATIBLE_TYPE: + rmw_event_type = RMW_EVENT_PUBLISHER_INCOMPATIBLE_TYPE; + break; + case RCL_PUBLISHER_MATCHED: + rmw_event_type = RMW_EVENT_PUBLICATION_MATCHED; + break; + } + if (rmw_event_type == RMW_EVENT_INVALID) { + return false; + } + return rmw_event_type_is_supported(rmw_event_type); +} + +bool +rcl_subscription_event_type_is_supported( + const rcl_subscription_event_type_t event_type) +{ + rmw_event_type_t rmw_event_type = RMW_EVENT_INVALID; + switch (event_type) { + case RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED: + rmw_event_type = RMW_EVENT_REQUESTED_DEADLINE_MISSED; + break; + case RCL_SUBSCRIPTION_LIVELINESS_CHANGED: + rmw_event_type = RMW_EVENT_LIVELINESS_CHANGED; + break; + case RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS: + rmw_event_type = RMW_EVENT_REQUESTED_QOS_INCOMPATIBLE; + break; + case RCL_SUBSCRIPTION_MESSAGE_LOST: + rmw_event_type = RMW_EVENT_MESSAGE_LOST; + break; + case RCL_SUBSCRIPTION_INCOMPATIBLE_TYPE: + rmw_event_type = RMW_EVENT_SUBSCRIPTION_INCOMPATIBLE_TYPE; + break; + case RCL_SUBSCRIPTION_MATCHED: + rmw_event_type = RMW_EVENT_SUBSCRIPTION_MATCHED; + break; + } + if (rmw_event_type == RMW_EVENT_INVALID) { + return false; + } + return rmw_event_type_is_supported(rmw_event_type); +} + rcl_ret_t rcl_event_set_callback( const rcl_event_t * event, diff --git a/rcl/test/rcl/test_events.cpp b/rcl/test/rcl/test_events.cpp index 89d21c868..ba44a0f6a 100644 --- a/rcl/test/rcl/test_events.cpp +++ b/rcl/test/rcl/test_events.cpp @@ -826,7 +826,7 @@ TEST_F(TestEventFixture, test_event_is_invalid) { */ TEST_F(TestEventFixture, test_sub_message_lost_event) { - if (!rmw_event_type_is_supported(RMW_EVENT_MESSAGE_LOST)) { + if (!rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_MESSAGE_LOST)) { GTEST_SKIP(); } @@ -1351,3 +1351,52 @@ TEST_F(TestEventFixture, test_sub_previous_matched_event) // So check if event count >= 1. EXPECT_GE(*matched_data.event_count, 1); } + +/* + * Test rcl_publisher_event_type_is_supported + */ +TEST_F(TestEventFixture, test_publisher_event_type_is_supported) +{ + // Verify rcl results are consistent with the underlying rmw results + EXPECT_EQ( + rcl_publisher_event_type_is_supported(RCL_PUBLISHER_OFFERED_DEADLINE_MISSED), + rmw_event_type_is_supported(RMW_EVENT_OFFERED_DEADLINE_MISSED)); + EXPECT_EQ( + rcl_publisher_event_type_is_supported(RCL_PUBLISHER_LIVELINESS_LOST), + rmw_event_type_is_supported(RMW_EVENT_LIVELINESS_LOST)); + EXPECT_EQ( + rcl_publisher_event_type_is_supported(RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS), + rmw_event_type_is_supported(RMW_EVENT_OFFERED_QOS_INCOMPATIBLE)); + EXPECT_EQ( + rcl_publisher_event_type_is_supported(RCL_PUBLISHER_INCOMPATIBLE_TYPE), + rmw_event_type_is_supported(RMW_EVENT_PUBLISHER_INCOMPATIBLE_TYPE)); + EXPECT_EQ( + rcl_publisher_event_type_is_supported(RCL_PUBLISHER_MATCHED), + rmw_event_type_is_supported(RMW_EVENT_PUBLICATION_MATCHED)); +} + +/* + * Test rcl_subscription_event_type_is_supported + */ +TEST_F(TestEventFixture, test_subscription_event_type_is_supported) +{ + // Verify rcl results are consistent with the underlying rmw results + EXPECT_EQ( + rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED), + rmw_event_type_is_supported(RMW_EVENT_REQUESTED_DEADLINE_MISSED)); + EXPECT_EQ( + rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_LIVELINESS_CHANGED), + rmw_event_type_is_supported(RMW_EVENT_LIVELINESS_CHANGED)); + EXPECT_EQ( + rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS), + rmw_event_type_is_supported(RMW_EVENT_REQUESTED_QOS_INCOMPATIBLE)); + EXPECT_EQ( + rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_MESSAGE_LOST), + rmw_event_type_is_supported(RMW_EVENT_MESSAGE_LOST)); + EXPECT_EQ( + rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_INCOMPATIBLE_TYPE), + rmw_event_type_is_supported(RMW_EVENT_SUBSCRIPTION_INCOMPATIBLE_TYPE)); + EXPECT_EQ( + rcl_subscription_event_type_is_supported(RCL_SUBSCRIPTION_MATCHED), + rmw_event_type_is_supported(RMW_EVENT_SUBSCRIPTION_MATCHED)); +}