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 
29 
30 namespace rclcpp
31 {
32 
33 template<typename MessageT, typename Alloc>
35 {
36  using MessageAllocTraits = allocator::AllocRebind<MessageT, Alloc>;
37  using MessageAlloc = typename MessageAllocTraits::allocator_type;
38  using MessageDeleter = allocator::Deleter<MessageAlloc, MessageT>;
41 
51 
52  SharedPtrCallback shared_ptr_callback_;
53  SharedPtrWithInfoCallback shared_ptr_with_info_callback_;
54  ConstSharedPtrCallback const_shared_ptr_callback_;
55  ConstSharedPtrWithInfoCallback const_shared_ptr_with_info_callback_;
56  UniquePtrCallback unique_ptr_callback_;
57  UniquePtrWithInfoCallback unique_ptr_with_info_callback_;
58 
59 public:
61  : shared_ptr_callback_(nullptr), shared_ptr_with_info_callback_(nullptr),
62  const_shared_ptr_callback_(nullptr), const_shared_ptr_with_info_callback_(nullptr),
63  unique_ptr_callback_(nullptr), unique_ptr_with_info_callback_(nullptr)
64  {
65  message_allocator_ = std::make_shared<MessageAlloc>(*allocator.get());
66  allocator::set_allocator_for_deleter(&message_deleter_, message_allocator_.get());
67  }
68 
70 
71  template<
72  typename CallbackT,
73  typename std::enable_if<
75  CallbackT,
77  >::value
78  >::type * = nullptr
79  >
80  void set(CallbackT callback)
81  {
82  shared_ptr_callback_ = callback;
83  }
84 
85  template<
86  typename CallbackT,
87  typename std::enable_if<
89  CallbackT,
91  >::value
92  >::type * = nullptr
93  >
94  void set(CallbackT callback)
95  {
96  shared_ptr_with_info_callback_ = callback;
97  }
98 
99  template<
100  typename CallbackT,
101  typename std::enable_if<
103  CallbackT,
105  >::value
106  >::type * = nullptr
107  >
108  void set(CallbackT callback)
109  {
110  const_shared_ptr_callback_ = callback;
111  }
112 
113  template<
114  typename CallbackT,
115  typename std::enable_if<
117  CallbackT,
119  >::value
120  >::type * = nullptr
121  >
122  void set(CallbackT callback)
123  {
124  const_shared_ptr_with_info_callback_ = callback;
125  }
126 
127  template<
128  typename CallbackT,
129  typename std::enable_if<
131  CallbackT,
133  >::value
134  >::type * = nullptr
135  >
136  void set(CallbackT callback)
137  {
138  unique_ptr_callback_ = callback;
139  }
140 
141  template<
142  typename CallbackT,
143  typename std::enable_if<
145  CallbackT,
147  >::value
148  >::type * = nullptr
149  >
150  void set(CallbackT callback)
151  {
152  unique_ptr_with_info_callback_ = callback;
153  }
154 
155  void dispatch(
156  std::shared_ptr<MessageT> message, const rmw_message_info_t & message_info)
157  {
158  if (shared_ptr_callback_) {
159  shared_ptr_callback_(message);
160  } else if (shared_ptr_with_info_callback_) {
161  shared_ptr_with_info_callback_(message, message_info);
162  } else if (const_shared_ptr_callback_) {
163  const_shared_ptr_callback_(message);
164  } else if (const_shared_ptr_with_info_callback_) {
165  const_shared_ptr_with_info_callback_(message, message_info);
166  } else if (unique_ptr_callback_) {
167  auto ptr = MessageAllocTraits::allocate(*message_allocator_.get(), 1);
168  MessageAllocTraits::construct(*message_allocator_.get(), ptr, *message);
169  unique_ptr_callback_(MessageUniquePtr(ptr, message_deleter_));
170  } else if (unique_ptr_with_info_callback_) {
171  auto ptr = MessageAllocTraits::allocate(*message_allocator_.get(), 1);
172  MessageAllocTraits::construct(*message_allocator_.get(), ptr, *message);
173  unique_ptr_with_info_callback_(MessageUniquePtr(ptr, message_deleter_), message_info);
174  } else {
175  throw std::runtime_error("unexpected message without any callback set");
176  }
177  }
178 
180  ConstMessageSharedPtr message, const rmw_message_info_t & message_info)
181  {
182  if (const_shared_ptr_callback_) {
183  const_shared_ptr_callback_(message);
184  } else if (const_shared_ptr_with_info_callback_) {
185  const_shared_ptr_with_info_callback_(message, message_info);
186  } else {
187  if (unique_ptr_callback_ || unique_ptr_with_info_callback_ ||
188  shared_ptr_callback_ || shared_ptr_with_info_callback_)
189  {
190  throw std::runtime_error("unexpected dispatch_intra_process const shared "
191  "message call with no const shared_ptr callback");
192  } else {
193  throw std::runtime_error("unexpected message without any callback set");
194  }
195  }
196  }
197 
199  MessageUniquePtr message, const rmw_message_info_t & message_info)
200  {
201  if (shared_ptr_callback_) {
202  typename std::shared_ptr<MessageT> shared_message = std::move(message);
203  shared_ptr_callback_(shared_message);
204  } else if (shared_ptr_with_info_callback_) {
205  typename std::shared_ptr<MessageT> shared_message = std::move(message);
206  shared_ptr_with_info_callback_(shared_message, message_info);
207  } else if (unique_ptr_callback_) {
208  unique_ptr_callback_(std::move(message));
209  } else if (unique_ptr_with_info_callback_) {
210  unique_ptr_with_info_callback_(std::move(message), message_info);
211  } else if (const_shared_ptr_callback_ || const_shared_ptr_with_info_callback_) {
212  throw std::runtime_error("unexpected dispatch_intra_process unique message call"
213  " with const shared_ptr callback");
214  } else {
215  throw std::runtime_error("unexpected message without any callback set");
216  }
217  }
218 
220  {
221  return const_shared_ptr_callback_ || const_shared_ptr_with_info_callback_;
222  }
223 
224 private:
225  std::shared_ptr<MessageAlloc> message_allocator_;
226  MessageDeleter message_deleter_;
227 };
228 
229 } // namespace rclcpp
230 
231 #endif // RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
void dispatch_intra_process(ConstMessageSharedPtr message, const rmw_message_info_t &message_info)
Definition: any_subscription_callback.hpp:179
This header provides the get_node_topics_interface() template function.
Definition: allocator_common.hpp:24
void dispatch_intra_process(MessageUniquePtr message, const rmw_message_info_t &message_info)
Definition: any_subscription_callback.hpp:198
void set_allocator_for_deleter(D *deleter, Alloc *alloc)
Definition: allocator_deleter.hpp:72
AnySubscriptionCallback(std::shared_ptr< Alloc > allocator)
Definition: any_subscription_callback.hpp:60
typename std::allocator_traits< Alloc >::template rebind_traits< T > AllocRebind
Definition: allocator_common.hpp:30
Definition: any_subscription_callback.hpp:34
Definition: function_traits.hpp:143
T move(T... args)
T get(T... args)
bool use_take_shared_method()
Definition: any_subscription_callback.hpp:219
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
void dispatch(std::shared_ptr< MessageT > message, const rmw_message_info_t &message_info)
Definition: any_subscription_callback.hpp:155