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>;
40 
50 
51  SharedPtrCallback shared_ptr_callback_;
52  SharedPtrWithInfoCallback shared_ptr_with_info_callback_;
53  ConstSharedPtrCallback const_shared_ptr_callback_;
54  ConstSharedPtrWithInfoCallback const_shared_ptr_with_info_callback_;
55  UniquePtrCallback unique_ptr_callback_;
56  UniquePtrWithInfoCallback unique_ptr_with_info_callback_;
57 
58 public:
60  : shared_ptr_callback_(nullptr), shared_ptr_with_info_callback_(nullptr),
61  const_shared_ptr_callback_(nullptr), const_shared_ptr_with_info_callback_(nullptr),
62  unique_ptr_callback_(nullptr), unique_ptr_with_info_callback_(nullptr)
63  {
64  message_allocator_ = std::make_shared<MessageAlloc>(*allocator.get());
65  allocator::set_allocator_for_deleter(&message_deleter_, message_allocator_.get());
66  }
67 
69 
70  template<
71  typename CallbackT,
72  typename std::enable_if<
74  CallbackT,
75  SharedPtrCallback
76  >::value
77  >::type * = nullptr
78  >
79  void set(CallbackT callback)
80  {
81  shared_ptr_callback_ = callback;
82  }
83 
84  template<
85  typename CallbackT,
86  typename std::enable_if<
88  CallbackT,
89  SharedPtrWithInfoCallback
90  >::value
91  >::type * = nullptr
92  >
93  void set(CallbackT callback)
94  {
95  shared_ptr_with_info_callback_ = callback;
96  }
97 
98  template<
99  typename CallbackT,
100  typename std::enable_if<
102  CallbackT,
103  ConstSharedPtrCallback
104  >::value
105  >::type * = nullptr
106  >
107  void set(CallbackT callback)
108  {
109  const_shared_ptr_callback_ = callback;
110  }
111 
112  template<
113  typename CallbackT,
114  typename std::enable_if<
116  CallbackT,
117  ConstSharedPtrWithInfoCallback
118  >::value
119  >::type * = nullptr
120  >
121  void set(CallbackT callback)
122  {
123  const_shared_ptr_with_info_callback_ = callback;
124  }
125 
126  template<
127  typename CallbackT,
128  typename std::enable_if<
130  CallbackT,
131  UniquePtrCallback
132  >::value
133  >::type * = nullptr
134  >
135  void set(CallbackT callback)
136  {
137  unique_ptr_callback_ = callback;
138  }
139 
140  template<
141  typename CallbackT,
142  typename std::enable_if<
144  CallbackT,
145  UniquePtrWithInfoCallback
146  >::value
147  >::type * = nullptr
148  >
149  void set(CallbackT callback)
150  {
151  unique_ptr_with_info_callback_ = callback;
152  }
153 
154  void dispatch(
155  std::shared_ptr<MessageT> message, const rmw_message_info_t & message_info)
156  {
157  (void)message_info;
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  MessageUniquePtr & message, const rmw_message_info_t & message_info)
181  {
182  (void)message_info;
183  if (shared_ptr_callback_) {
184  typename std::shared_ptr<MessageT> shared_message = std::move(message);
185  shared_ptr_callback_(shared_message);
186  } else if (shared_ptr_with_info_callback_) {
187  typename std::shared_ptr<MessageT> shared_message = std::move(message);
188  shared_ptr_with_info_callback_(shared_message, message_info);
189  } else if (const_shared_ptr_callback_) {
190  typename std::shared_ptr<MessageT const> const_shared_message = std::move(message);
191  const_shared_ptr_callback_(const_shared_message);
192  } else if (const_shared_ptr_with_info_callback_) {
193  typename std::shared_ptr<MessageT const> const_shared_message = std::move(message);
194  const_shared_ptr_with_info_callback_(const_shared_message, message_info);
195  } else if (unique_ptr_callback_) {
196  unique_ptr_callback_(std::move(message));
197  } else if (unique_ptr_with_info_callback_) {
198  unique_ptr_with_info_callback_(std::move(message), message_info);
199  } else {
200  throw std::runtime_error("unexpected message without any callback set");
201  }
202  }
203 
204 private:
205  std::shared_ptr<MessageAlloc> message_allocator_;
206  MessageDeleter message_deleter_;
207 };
208 
209 } // namespace rclcpp
210 
211 #endif // RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
AnySubscriptionCallback(std::shared_ptr< Alloc > allocator)
Definition: any_subscription_callback.hpp:59
Definition: allocator_common.hpp:24
void dispatch_intra_process(MessageUniquePtr &message, const rmw_message_info_t &message_info)
Definition: any_subscription_callback.hpp:179
void set_allocator_for_deleter(D *deleter, Alloc *alloc)
Definition: allocator_deleter.hpp:72
Definition: any_subscription_callback.hpp:34
typename std::allocator_traits< Alloc >::template rebind_traits< T > AllocRebind
Definition: allocator_common.hpp:30
Definition: function_traits.hpp:143
T move(T... args)
T get(T... args)
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:154