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