15 #ifndef RCLCPP__EXPERIMENTAL__SUBSCRIPTION_INTRA_PROCESS_HPP_
16 #define RCLCPP__EXPERIMENTAL__SUBSCRIPTION_INTRA_PROCESS_HPP_
18 #include <rmw/types.h>
25 #include <type_traits>
30 #include "rclcpp/any_subscription_callback.hpp"
31 #include "rclcpp/context.hpp"
32 #include "rclcpp/experimental/buffers/intra_process_buffer.hpp"
33 #include "rclcpp/experimental/subscription_intra_process_buffer.hpp"
34 #include "rclcpp/logging.hpp"
35 #include "rclcpp/qos.hpp"
36 #include "rclcpp/time.hpp"
37 #include "rclcpp/type_support_decl.hpp"
38 #include "tracetools/tracetools.h"
42 namespace experimental
47 typename SubscribedType,
48 typename SubscribedTypeAlloc = std::allocator<SubscribedType>,
49 typename SubscribedTypeDeleter = std::default_delete<SubscribedType>,
50 typename ROSMessageType = SubscribedType,
51 typename Alloc = std::allocator<void>
57 SubscribedTypeDeleter,
64 SubscribedTypeDeleter,
71 using MessageAllocTraits =
72 typename SubscriptionIntraProcessBufferT::SubscribedTypeAllocatorTraits;
73 using MessageAlloc =
typename SubscriptionIntraProcessBufferT::SubscribedTypeAllocator;
74 using ConstMessageSharedPtr =
typename SubscriptionIntraProcessBufferT::ConstDataSharedPtr;
75 using MessageUniquePtr =
typename SubscriptionIntraProcessBufferT::SubscribedTypeUniquePtr;
76 using BufferUniquePtr =
typename SubscriptionIntraProcessBufferT::BufferUniquePtr;
77 using StatsHandlerFn = std::function<void(
const rmw_message_info_t &,
const rclcpp::Time &)>;
81 std::shared_ptr<Alloc> allocator,
82 rclcpp::Context::SharedPtr context,
83 const std::string & topic_name,
86 StatsHandlerFn stats_handler =
nullptr)
88 SubscribedTypeDeleter, ROSMessageType>(
89 std::make_shared<SubscribedTypeAlloc>(*allocator),
94 any_callback_(callback),
95 stats_handler_(std::move(stats_handler))
97 TRACETOOLS_TRACEPOINT(
98 rclcpp_subscription_callback_added,
99 static_cast<const void *
>(
this),
100 static_cast<const void *
>(&any_callback_));
104 #ifndef TRACETOOLS_DISABLED
105 any_callback_.register_callback_for_tracing();
119 if (this->buffer_->has_data()) {
122 this->trigger_guard_condition();
128 std::shared_ptr<void>
131 ConstMessageSharedPtr shared_msg;
132 MessageUniquePtr unique_msg;
134 if (any_callback_.use_take_shared_method()) {
135 shared_msg = this->buffer_->consume_shared();
140 unique_msg = this->buffer_->consume_unique();
146 if (this->buffer_->has_data()) {
149 this->trigger_guard_condition();
152 return std::static_pointer_cast<void>(
153 std::make_shared<std::pair<ConstMessageSharedPtr, MessageUniquePtr>>(
154 std::pair<ConstMessageSharedPtr, MessageUniquePtr>(
155 shared_msg, std::move(unique_msg)))
159 void execute(
const std::shared_ptr<void> & data)
override
161 execute_impl<SubscribedType>(data);
173 any_callback_.disable();
184 any_callback_.enable();
189 typename std::enable_if<std::is_same<T, rcl_serialized_message_t>::value,
void>::type
190 execute_impl(
const std::shared_ptr<void> &)
192 throw std::runtime_error(
"Subscription intra-process can't handle serialized messages");
196 typename std::enable_if<!std::is_same<T, rcl_serialized_message_t>::value,
void>::type
197 execute_impl(
const std::shared_ptr<void> & data)
199 if (
nullptr == data) {
203 rmw_message_info_t msg_info;
204 msg_info.publisher_gid = {0, {0}};
205 msg_info.from_intra_process =
true;
207 const auto nanos = std::chrono::time_point_cast<std::chrono::nanoseconds>(
208 std::chrono::system_clock::now());
209 if (stats_handler_) {
212 "Intra-process communication does not support accurate message age statistics");
216 msg_info.source_timestamp = nanos.time_since_epoch().count();
219 auto shared_ptr = std::static_pointer_cast<std::pair<ConstMessageSharedPtr, MessageUniquePtr>>(
222 if (any_callback_.use_take_shared_method()) {
223 ConstMessageSharedPtr shared_msg = shared_ptr->first;
224 any_callback_.dispatch_intra_process(shared_msg, msg_info);
226 MessageUniquePtr unique_msg = std::move(shared_ptr->second);
227 any_callback_.dispatch_intra_process(std::move(unique_msg), msg_info);
231 if (stats_handler_) {
232 stats_handler_(msg_info,
rclcpp::Time(nanos.time_since_epoch().count()));
236 AnySubscriptionCallback<MessageT, Alloc> any_callback_;
237 StatsHandlerFn stats_handler_;
Encapsulation of Quality of Service settings.
virtual RCLCPP_PUBLIC void enable_callbacks()
Enable the callbacks to be called.
virtual RCLCPP_PUBLIC void disable_callbacks()
Disable callbacks from being called.
void add_to_wait_set(rcl_wait_set_t &wait_set) override
Add the Waitable to a wait set.
void disable_callbacks() override
Disable callbacks from being called.
std::shared_ptr< void > take_data() override
Take the data so that it can be consumed with execute.
void enable_callbacks() override
Enable the callbacks to be called.
void add_to_wait_set(rcl_wait_set_t &wait_set) override
Add the Waitable to a wait set.
void execute(const std::shared_ptr< void > &data) override
Execute data that is passed in.
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.
Container for subscription's, guard condition's, etc to be waited on.