rclcpp  master
C++ ROS Client Library API
any_subscription_callback.hpp
Go to the documentation of this file.
1 // Copyright 2014 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
16 #define RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
17 
18 #include <rmw/types.h>
19 
20 #include <functional>
21 #include <memory>
22 #include <stdexcept>
23 #include <type_traits>
24 #include <utility>
25 
28 #include "rclcpp/message_info.hpp"
30 #include "tracetools/tracetools.h"
31 #include "tracetools/utils.hpp"
32 
33 namespace rclcpp
34 {
35 
36 template<typename MessageT, typename Alloc>
38 {
39  using MessageAllocTraits = allocator::AllocRebind<MessageT, Alloc>;
40  using MessageAlloc = typename MessageAllocTraits::allocator_type;
41  using MessageDeleter = allocator::Deleter<MessageAlloc, MessageT>;
44 
54 
55  SharedPtrCallback shared_ptr_callback_;
56  SharedPtrWithInfoCallback shared_ptr_with_info_callback_;
57  ConstSharedPtrCallback const_shared_ptr_callback_;
58  ConstSharedPtrWithInfoCallback const_shared_ptr_with_info_callback_;
59  UniquePtrCallback unique_ptr_callback_;
60  UniquePtrWithInfoCallback unique_ptr_with_info_callback_;
61 
62 public:
64  : shared_ptr_callback_(nullptr), shared_ptr_with_info_callback_(nullptr),
65  const_shared_ptr_callback_(nullptr), const_shared_ptr_with_info_callback_(nullptr),
66  unique_ptr_callback_(nullptr), unique_ptr_with_info_callback_(nullptr)
67  {
68  message_allocator_ = std::make_shared<MessageAlloc>(*allocator.get());
69  allocator::set_allocator_for_deleter(&message_deleter_, message_allocator_.get());
70  }
71 
73 
74  template<
75  typename CallbackT,
76  typename std::enable_if<
78  CallbackT,
79  SharedPtrCallback
80  >::value
81  >::type * = nullptr
82  >
83  void set(CallbackT callback)
84  {
85  shared_ptr_callback_ = callback;
86  }
87 
88  template<
89  typename CallbackT,
90  typename std::enable_if<
92  CallbackT,
93  SharedPtrWithInfoCallback
94  >::value
95  >::type * = nullptr
96  >
97  void set(CallbackT callback)
98  {
99  shared_ptr_with_info_callback_ = callback;
100  }
101 
102  template<
103  typename CallbackT,
104  typename std::enable_if<
106  CallbackT,
107  ConstSharedPtrCallback
108  >::value
109  >::type * = nullptr
110  >
111  void set(CallbackT callback)
112  {
113  const_shared_ptr_callback_ = callback;
114  }
115 
116  template<
117  typename CallbackT,
118  typename std::enable_if<
120  CallbackT,
121  ConstSharedPtrWithInfoCallback
122  >::value
123  >::type * = nullptr
124  >
125  void set(CallbackT callback)
126  {
127  const_shared_ptr_with_info_callback_ = callback;
128  }
129 
130  template<
131  typename CallbackT,
132  typename std::enable_if<
134  CallbackT,
135  UniquePtrCallback
136  >::value
137  >::type * = nullptr
138  >
139  void set(CallbackT callback)
140  {
141  unique_ptr_callback_ = callback;
142  }
143 
144  template<
145  typename CallbackT,
146  typename std::enable_if<
148  CallbackT,
149  UniquePtrWithInfoCallback
150  >::value
151  >::type * = nullptr
152  >
153  void set(CallbackT callback)
154  {
155  unique_ptr_with_info_callback_ = callback;
156  }
157 
158  void dispatch(
159  std::shared_ptr<MessageT> message, const rclcpp::MessageInfo & message_info)
160  {
161  TRACEPOINT(callback_start, (const void *)this, false);
162  if (shared_ptr_callback_) {
163  shared_ptr_callback_(message);
164  } else if (shared_ptr_with_info_callback_) {
165  shared_ptr_with_info_callback_(message, message_info);
166  } else if (const_shared_ptr_callback_) {
167  const_shared_ptr_callback_(message);
168  } else if (const_shared_ptr_with_info_callback_) {
169  const_shared_ptr_with_info_callback_(message, message_info);
170  } else if (unique_ptr_callback_) {
171  auto ptr = MessageAllocTraits::allocate(*message_allocator_.get(), 1);
172  MessageAllocTraits::construct(*message_allocator_.get(), ptr, *message);
173  unique_ptr_callback_(MessageUniquePtr(ptr, message_deleter_));
174  } else if (unique_ptr_with_info_callback_) {
175  auto ptr = MessageAllocTraits::allocate(*message_allocator_.get(), 1);
176  MessageAllocTraits::construct(*message_allocator_.get(), ptr, *message);
177  unique_ptr_with_info_callback_(MessageUniquePtr(ptr, message_deleter_), message_info);
178  } else {
179  throw std::runtime_error("unexpected message without any callback set");
180  }
181  TRACEPOINT(callback_end, (const void *)this);
182  }
183 
185  ConstMessageSharedPtr message, const rclcpp::MessageInfo & message_info)
186  {
187  TRACEPOINT(callback_start, (const void *)this, true);
188  if (const_shared_ptr_callback_) {
189  const_shared_ptr_callback_(message);
190  } else if (const_shared_ptr_with_info_callback_) {
191  const_shared_ptr_with_info_callback_(message, message_info);
192  } else {
193  if (
194  unique_ptr_callback_ || unique_ptr_with_info_callback_ ||
195  shared_ptr_callback_ || shared_ptr_with_info_callback_)
196  {
197  throw std::runtime_error(
198  "unexpected dispatch_intra_process const shared "
199  "message call with no const shared_ptr callback");
200  } else {
201  throw std::runtime_error("unexpected message without any callback set");
202  }
203  }
204  TRACEPOINT(callback_end, (const void *)this);
205  }
206 
208  MessageUniquePtr message, const rclcpp::MessageInfo & message_info)
209  {
210  TRACEPOINT(callback_start, (const void *)this, true);
211  if (shared_ptr_callback_) {
212  typename std::shared_ptr<MessageT> shared_message = std::move(message);
213  shared_ptr_callback_(shared_message);
214  } else if (shared_ptr_with_info_callback_) {
215  typename std::shared_ptr<MessageT> shared_message = std::move(message);
216  shared_ptr_with_info_callback_(shared_message, message_info);
217  } else if (unique_ptr_callback_) {
218  unique_ptr_callback_(std::move(message));
219  } else if (unique_ptr_with_info_callback_) {
220  unique_ptr_with_info_callback_(std::move(message), message_info);
221  } else if (const_shared_ptr_callback_ || const_shared_ptr_with_info_callback_) {
222  throw std::runtime_error(
223  "unexpected dispatch_intra_process unique message call"
224  " with const shared_ptr callback");
225  } else {
226  throw std::runtime_error("unexpected message without any callback set");
227  }
228  TRACEPOINT(callback_end, (const void *)this);
229  }
230 
232  {
233  return const_shared_ptr_callback_ || const_shared_ptr_with_info_callback_;
234  }
235 
237  {
238 #ifndef TRACETOOLS_DISABLED
239  if (shared_ptr_callback_) {
240  TRACEPOINT(
241  rclcpp_callback_register,
242  (const void *)this,
243  get_symbol(shared_ptr_callback_));
244  } else if (shared_ptr_with_info_callback_) {
245  TRACEPOINT(
246  rclcpp_callback_register,
247  (const void *)this,
248  get_symbol(shared_ptr_with_info_callback_));
249  } else if (unique_ptr_callback_) {
250  TRACEPOINT(
251  rclcpp_callback_register,
252  (const void *)this,
253  get_symbol(unique_ptr_callback_));
254  } else if (unique_ptr_with_info_callback_) {
255  TRACEPOINT(
256  rclcpp_callback_register,
257  (const void *)this,
258  get_symbol(unique_ptr_with_info_callback_));
259  }
260 #endif // TRACETOOLS_DISABLED
261  }
262 
263 private:
264  std::shared_ptr<MessageAlloc> message_allocator_;
265  MessageDeleter message_deleter_;
266 };
267 
268 } // namespace rclcpp
269 
270 #endif // RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
std::shared_ptr
message_info.hpp
std::move
T move(T... args)
std::shared_ptr::get
T get(T... args)
std::function< void(const std::shared_ptr< MessageT >)>
rclcpp::AnySubscriptionCallback::dispatch_intra_process
void dispatch_intra_process(MessageUniquePtr message, const rclcpp::MessageInfo &message_info)
Definition: any_subscription_callback.hpp:207
rclcpp
This header provides the get_node_base_interface() template function.
Definition: allocator_common.hpp:24
rclcpp::AnySubscriptionCallback::dispatch
void dispatch(std::shared_ptr< MessageT > message, const rclcpp::MessageInfo &message_info)
Definition: any_subscription_callback.hpp:158
rclcpp::allocator::set_allocator_for_deleter
void set_allocator_for_deleter(D *deleter, Alloc *alloc)
Definition: allocator_deleter.hpp:72
allocator_common.hpp
std::enable_if
rclcpp::allocator::AllocRebind
typename std::allocator_traits< Alloc >::template rebind_traits< T > AllocRebind
Definition: allocator_common.hpp:30
rclcpp::AnySubscriptionCallback::dispatch_intra_process
void dispatch_intra_process(ConstMessageSharedPtr message, const rclcpp::MessageInfo &message_info)
Definition: any_subscription_callback.hpp:184
rclcpp::AnySubscriptionCallback
Definition: any_subscription_callback.hpp:37
std::runtime_error
rclcpp::AnySubscriptionCallback::use_take_shared_method
bool use_take_shared_method() const
Definition: any_subscription_callback.hpp:231
rclcpp::AnySubscriptionCallback::register_callback_for_tracing
void register_callback_for_tracing()
Definition: any_subscription_callback.hpp:236
rclcpp::function_traits::same_arguments
Definition: function_traits.hpp:159
function_traits.hpp
rclcpp::MessageInfo
Additional meta data about messages taken from subscriptions.
Definition: message_info.hpp:26
visibility_control.hpp
rclcpp::allocator::Deleter
typename std::conditional< std::is_same< typename std::allocator_traits< Alloc >::template rebind_alloc< T >, typename std::allocator< void >::template rebind< T >::other >::value, std::default_delete< T >, AllocatorDeleter< Alloc > >::type Deleter
Definition: allocator_deleter.hpp:101
rclcpp::AnySubscriptionCallback::set
void set(CallbackT callback)
Definition: any_subscription_callback.hpp:83
rclcpp::AnySubscriptionCallback::AnySubscriptionCallback
AnySubscriptionCallback(std::shared_ptr< Alloc > allocator)
Definition: any_subscription_callback.hpp:63
types.h
std::unique_ptr