15 #ifndef RCLCPP__ANY_SERVICE_CALLBACK_HPP_
16 #define RCLCPP__ANY_SERVICE_CALLBACK_HPP_
22 #include <type_traits>
25 #include "rclcpp/function_traits.hpp"
26 #include "rmw/types.h"
27 #include "tracetools/tracetools.h"
28 #include "tracetools/utils.hpp"
35 template<
typename T,
typename =
void>
44 decltype(std::declval<T>() == nullptr)>>: std::true_type {};
47 decltype(std::declval<T>() == nullptr), decltype(std::declval<T &>() = nullptr)>>
53 template<
typename ServiceT>
56 template<
typename ServiceT>
61 : callback_(std::monostate{})
66 typename std::enable_if_t<!detail::can_be_nullptr<CallbackT>::value,
int> = 0>
68 set(CallbackT && callback)
77 callback_.template emplace<SharedPtrCallback>(callback);
81 SharedPtrWithRequestHeaderCallback
84 callback_.template emplace<SharedPtrWithRequestHeaderCallback>(callback);
88 SharedPtrDeferResponseCallback
91 callback_.template emplace<SharedPtrDeferResponseCallback>(callback);
95 SharedPtrDeferResponseCallbackWithServiceHandle
98 callback_.template emplace<SharedPtrDeferResponseCallbackWithServiceHandle>(callback);
105 callback_.template emplace<ConstRefCallback>(callback);
106 }
else if constexpr (
109 ConstRefWithRequestHeaderCallback
112 callback_.template emplace<ConstRefWithRequestHeaderCallback>(callback);
116 callback_ = std::forward<CallbackT>(callback);
122 typename std::enable_if_t<detail::can_be_nullptr<CallbackT>::value,
int> = 0>
124 set(CallbackT && callback)
127 throw std::invalid_argument(
"AnyServiceCallback::set(): callback cannot be nullptr");
136 callback_.template emplace<SharedPtrCallback>(callback);
137 }
else if constexpr (
140 SharedPtrWithRequestHeaderCallback
143 callback_.template emplace<SharedPtrWithRequestHeaderCallback>(callback);
144 }
else if constexpr (
147 SharedPtrDeferResponseCallback
150 callback_.template emplace<SharedPtrDeferResponseCallback>(callback);
151 }
else if constexpr (
154 SharedPtrDeferResponseCallbackWithServiceHandle
157 callback_.template emplace<SharedPtrDeferResponseCallbackWithServiceHandle>(callback);
158 }
else if constexpr (
164 callback_.template emplace<ConstRefCallback>(callback);
165 }
else if constexpr (
168 ConstRefWithRequestHeaderCallback
171 callback_.template emplace<ConstRefWithRequestHeaderCallback>(callback);
175 callback_ = std::forward<CallbackT>(callback);
180 std::shared_ptr<typename ServiceT::Response>
183 const std::shared_ptr<rmw_request_id_t> & request_header,
184 std::shared_ptr<typename ServiceT::Request> request)
186 TRACETOOLS_TRACEPOINT(callback_start,
static_cast<const void *
>(
this),
false);
187 if (std::holds_alternative<std::monostate>(callback_)) {
190 throw std::runtime_error{
"unexpected request without any callback set"};
192 if (std::holds_alternative<SharedPtrDeferResponseCallback>(callback_)) {
193 const auto & cb = std::get<SharedPtrDeferResponseCallback>(callback_);
194 cb(request_header, std::move(request));
195 TRACETOOLS_TRACEPOINT(callback_end,
static_cast<const void *
>(
this));
198 if (std::holds_alternative<SharedPtrDeferResponseCallbackWithServiceHandle>(callback_)) {
199 const auto & cb = std::get<SharedPtrDeferResponseCallbackWithServiceHandle>(callback_);
200 cb(service_handle, request_header, std::move(request));
201 TRACETOOLS_TRACEPOINT(callback_end,
static_cast<const void *
>(
this));
205 auto response = std::make_shared<typename ServiceT::Response>();
206 if (std::holds_alternative<SharedPtrCallback>(callback_)) {
207 (void)request_header;
208 const auto & cb = std::get<SharedPtrCallback>(callback_);
209 cb(std::move(request), response);
210 }
else if (std::holds_alternative<SharedPtrWithRequestHeaderCallback>(callback_)) {
211 const auto & cb = std::get<SharedPtrWithRequestHeaderCallback>(callback_);
212 cb(request_header, std::move(request), response);
213 }
else if (std::holds_alternative<ConstRefCallback>(callback_)) {
214 if (
nullptr == request) {
215 throw std::runtime_error(
"dispatch called with a null request");
217 const auto & cb = std::get<ConstRefCallback>(callback_);
218 cb(*request, *response);
219 }
else if (std::holds_alternative<ConstRefWithRequestHeaderCallback>(callback_)) {
220 if (
nullptr == request_header ||
nullptr == request) {
221 throw std::runtime_error(
"dispatch called with a null request header or request");
223 const auto & cb = std::get<ConstRefWithRequestHeaderCallback>(callback_);
224 cb(*request_header, *request, *response);
226 TRACETOOLS_TRACEPOINT(callback_end,
static_cast<const void *
>(
this));
230 void register_callback_for_tracing()
232 #ifndef TRACETOOLS_DISABLED
234 [
this](
auto && arg) {
235 if (TRACETOOLS_TRACEPOINT_ENABLED(rclcpp_callback_register)) {
236 char * symbol = tracetools::get_symbol(arg);
237 TRACETOOLS_DO_TRACEPOINT(
238 rclcpp_callback_register,
239 static_cast<const void *
>(
this),
248 using SharedPtrCallback = std::function<
250 std::shared_ptr<typename ServiceT::Request>,
251 std::shared_ptr<typename ServiceT::Response>
253 using SharedPtrWithRequestHeaderCallback = std::function<
255 std::shared_ptr<rmw_request_id_t>,
256 std::shared_ptr<typename ServiceT::Request>,
257 std::shared_ptr<typename ServiceT::Response>
259 using SharedPtrDeferResponseCallback = std::function<
261 std::shared_ptr<rmw_request_id_t>,
262 std::shared_ptr<typename ServiceT::Request>
264 using SharedPtrDeferResponseCallbackWithServiceHandle = std::function<
267 std::shared_ptr<rmw_request_id_t>,
268 std::shared_ptr<typename ServiceT::Request>
272 using ConstRefCallback = std::function<
274 const typename ServiceT::Request &,
275 typename ServiceT::Response &
277 using ConstRefWithRequestHeaderCallback = std::function<
279 const rmw_request_id_t &,
280 const typename ServiceT::Request &,
281 typename ServiceT::Response &
287 SharedPtrWithRequestHeaderCallback,
288 SharedPtrDeferResponseCallback,
289 SharedPtrDeferResponseCallbackWithServiceHandle,
291 ConstRefWithRequestHeaderCallback> callback_;
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.