15 #ifndef RCLCPP__GENERIC_SERVICE_HPP_
16 #define RCLCPP__GENERIC_SERVICE_HPP_
22 #include <type_traits>
26 #include "rclcpp/typesupport_helpers.hpp"
28 #include "rosidl_runtime_c/service_type_support_struct.h"
29 #include "rosidl_typesupport_introspection_cpp/identifier.hpp"
30 #include "rosidl_typesupport_introspection_cpp/service_introspection.hpp"
32 #include "service.hpp"
41 using SharedRequest = std::shared_ptr<void>;
42 using SharedResponse = std::shared_ptr<void>;
45 : callback_(std::monostate{})
50 typename std::enable_if_t<!detail::can_be_nullptr<CallbackT>::value,
int> = 0>
52 set(CallbackT && callback)
61 callback_.template emplace<SharedPtrCallback>(callback);
65 SharedPtrWithRequestHeaderCallback
68 callback_.template emplace<SharedPtrWithRequestHeaderCallback>(callback);
72 SharedPtrDeferResponseCallback
75 callback_.template emplace<SharedPtrDeferResponseCallback>(callback);
79 SharedPtrDeferResponseCallbackWithServiceHandle
82 callback_.template emplace<SharedPtrDeferResponseCallbackWithServiceHandle>(callback);
86 callback_ = std::forward<CallbackT>(callback);
92 typename std::enable_if_t<detail::can_be_nullptr<CallbackT>::value,
int> = 0>
94 set(CallbackT && callback)
97 throw std::invalid_argument(
"AnyServiceCallback::set(): callback cannot be nullptr");
106 callback_.template emplace<SharedPtrCallback>(callback);
107 }
else if constexpr (
110 SharedPtrWithRequestHeaderCallback
113 callback_.template emplace<SharedPtrWithRequestHeaderCallback>(callback);
114 }
else if constexpr (
117 SharedPtrDeferResponseCallback
120 callback_.template emplace<SharedPtrDeferResponseCallback>(callback);
121 }
else if constexpr (
124 SharedPtrDeferResponseCallbackWithServiceHandle
127 callback_.template emplace<SharedPtrDeferResponseCallbackWithServiceHandle>(callback);
131 callback_ = std::forward<CallbackT>(callback);
137 const std::shared_ptr<rclcpp::GenericService> & service_handle,
138 const std::shared_ptr<rmw_request_id_t> & request_header,
139 SharedRequest request,
140 SharedRequest response)
142 TRACETOOLS_TRACEPOINT(callback_start,
static_cast<const void *
>(
this),
false);
143 if (std::holds_alternative<std::monostate>(callback_)) {
146 throw std::runtime_error{
"unexpected request without any callback set"};
148 if (std::holds_alternative<SharedPtrDeferResponseCallback>(callback_)) {
149 const auto & cb = std::get<SharedPtrDeferResponseCallback>(callback_);
150 cb(request_header, std::move(request));
153 if (std::holds_alternative<SharedPtrDeferResponseCallbackWithServiceHandle>(callback_)) {
154 const auto & cb = std::get<SharedPtrDeferResponseCallbackWithServiceHandle>(callback_);
155 cb(service_handle, request_header, std::move(request));
159 if (std::holds_alternative<SharedPtrCallback>(callback_)) {
160 (void)request_header;
161 const auto & cb = std::get<SharedPtrCallback>(callback_);
162 cb(std::move(request), std::move(response));
163 }
else if (std::holds_alternative<SharedPtrWithRequestHeaderCallback>(callback_)) {
164 const auto & cb = std::get<SharedPtrWithRequestHeaderCallback>(callback_);
165 cb(request_header, std::move(request), std::move(response));
167 TRACETOOLS_TRACEPOINT(callback_end,
static_cast<const void *
>(
this));
171 void register_callback_for_tracing()
173 #ifndef TRACETOOLS_DISABLED
175 [
this](
auto && arg) {
176 if (TRACETOOLS_TRACEPOINT_ENABLED(rclcpp_callback_register)) {
177 char * symbol = tracetools::get_symbol(arg);
178 TRACETOOLS_DO_TRACEPOINT(
179 rclcpp_callback_register,
180 static_cast<const void *
>(
this),
189 using SharedPtrCallback = std::function<void (SharedRequest, SharedResponse)>;
190 using SharedPtrWithRequestHeaderCallback = std::function<
192 std::shared_ptr<rmw_request_id_t>,
196 using SharedPtrDeferResponseCallback = std::function<
198 std::shared_ptr<rmw_request_id_t>,
201 using SharedPtrDeferResponseCallbackWithServiceHandle = std::function<
203 std::shared_ptr<rclcpp::GenericService>,
204 std::shared_ptr<rmw_request_id_t>,
211 SharedPtrWithRequestHeaderCallback,
212 SharedPtrDeferResponseCallback,
213 SharedPtrDeferResponseCallbackWithServiceHandle> callback_;
218 public std::enable_shared_from_this<GenericService>
221 using Request =
void *;
222 using Response =
void *;
223 using SharedRequest = std::shared_ptr<void>;
224 using SharedResponse = std::shared_ptr<void>;
225 using CallbackType = std::function<void (
const SharedRequest, SharedResponse)>;
227 using CallbackWithHeaderType =
228 std::function<void (
const std::shared_ptr<rmw_request_id_t>,
248 std::shared_ptr<rcl_node_t> node_handle,
249 const std::string & service_name,
250 const std::string & service_type,
273 take_request(SharedRequest request_out, rmw_request_id_t & request_id_out);
276 std::shared_ptr<void>
277 create_request()
override;
280 std::shared_ptr<void>
284 std::shared_ptr<rmw_request_id_t>
285 create_request_header()
override;
290 std::shared_ptr<rmw_request_id_t> request_header,
291 std::shared_ptr<void> request)
override;
295 send_response(rmw_request_id_t & req_id, SharedResponse & response);
302 std::shared_ptr<rcpputils::SharedLibrary> ts_lib_;
303 const rosidl_typesupport_introspection_cpp::MessageMembers * request_members_;
304 const rosidl_typesupport_introspection_cpp::MessageMembers * response_members_;
RCLCPP_PUBLIC bool take_request(SharedRequest request_out, rmw_request_id_t &request_id_out)
Take the next request from the service.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
Options available for a rcl service.