10#ifndef NROS_CPP_ACTION_SERVER_HPP
11#define NROS_CPP_ACTION_SERVER_HPP
22#include "nros/size_bound.hpp"
34#include "nros_cpp_ffi.h"
38 size_t len,
void* ctx);
156 user_goal_fn_ctx_ =
nullptr;
157 user_goal_ctx_ =
nullptr;
158 return install_callbacks();
170 user_goal_fn_ctx_ = f;
171 user_goal_ctx_ = ctx;
172 user_goal_fn_ =
nullptr;
173 return install_callbacks();
182 user_cancel_fn_ctx_ =
nullptr;
183 user_cancel_ctx_ =
nullptr;
184 return install_callbacks();
195 user_cancel_fn_ctx_ = f;
196 user_cancel_ctx_ = ctx;
197 user_cancel_fn_ =
nullptr;
198 return install_callbacks();
219 user_accepted_fn_ctx_ =
nullptr;
220 user_accepted_ctx_ =
nullptr;
221 return install_callbacks();
230 user_accepted_fn_ctx_ = f;
231 user_accepted_ctx_ = ctx;
232 user_accepted_fn_ =
nullptr;
233 return install_callbacks();
244 uint8_t buf[::nros::detail::buffer_bounds<FeedbackType>::tx];
246 if (FeedbackType::ffi_serialize(&feedback, buf,
sizeof(buf), &len) != 0) {
249 return Result(nros_cpp_action_server_publish_feedback(
250 storage_, executor_,
reinterpret_cast<const uint8_t(*)[16]
>(goal_id), buf, len));
264 uint8_t buf[::nros::detail::buffer_bounds<ResultType>::tx];
266 if (ResultType::ffi_serialize(&result, buf,
sizeof(buf), &len) != 0) {
269 return Result(nros_cpp_action_server_complete_goal(
270 storage_, executor_,
reinterpret_cast<const uint8_t(*)[16]
>(goal_id),
271 static_cast<int32_t
>(status), buf, len));
289 using Fn = void (*)(
const uint8_t[16],
GoalStatus);
291 user_visitor_fn_ = Fn(f);
293 auto trampoline = [](
const uint8_t goal_id[16], int8_t status,
void* ctx) {
295 if (!self || self->user_visitor_fn_ ==
nullptr)
return;
296 self->user_visitor_fn_(goal_id,
static_cast<GoalStatus>(status));
298 Result ret(nros_cpp_action_server_for_each_active_goal(
300 reinterpret_cast<void (*)(
const uint8_t(*)[16], int8_t,
void*)
>(+trampoline),
this));
301 user_visitor_fn_ =
nullptr;
311 nros_cpp_action_server_destroy(storage_);
312 initialized_ =
false;
322 : executor_(other.executor_), user_goal_fn_(other.user_goal_fn_),
323 user_goal_fn_ctx_(other.user_goal_fn_ctx_), user_goal_ctx_(other.user_goal_ctx_),
324 user_cancel_fn_(other.user_cancel_fn_), user_cancel_fn_ctx_(other.user_cancel_fn_ctx_),
325 user_cancel_ctx_(other.user_cancel_ctx_), user_accepted_fn_(other.user_accepted_fn_),
326 user_accepted_fn_ctx_(other.user_accepted_fn_ctx_),
327 user_accepted_ctx_(other.user_accepted_ctx_), user_visitor_fn_(other.user_visitor_fn_),
328 initialized_(other.initialized_) {
329 if (other.initialized_) {
330 nros_cpp_action_server_relocate(other.storage_, storage_);
331 other.initialized_ =
false;
337 if (
this != &other) {
339 nros_cpp_action_server_destroy(storage_);
341 executor_ = other.executor_;
342 user_goal_fn_ = other.user_goal_fn_;
343 user_goal_fn_ctx_ = other.user_goal_fn_ctx_;
344 user_goal_ctx_ = other.user_goal_ctx_;
345 user_cancel_fn_ = other.user_cancel_fn_;
346 user_cancel_fn_ctx_ = other.user_cancel_fn_ctx_;
347 user_cancel_ctx_ = other.user_cancel_ctx_;
348 user_accepted_fn_ = other.user_accepted_fn_;
349 user_accepted_fn_ctx_ = other.user_accepted_fn_ctx_;
350 user_accepted_ctx_ = other.user_accepted_ctx_;
351 user_visitor_fn_ = other.user_visitor_fn_;
352 initialized_ = other.initialized_;
353 if (other.initialized_) {
354 nros_cpp_action_server_relocate(other.storage_, storage_);
355 other.initialized_ =
false;
365 : executor_(nullptr), user_goal_fn_(nullptr), user_goal_fn_ctx_(nullptr),
366 user_goal_ctx_(nullptr), user_cancel_fn_(nullptr), user_cancel_fn_ctx_(nullptr),
367 user_cancel_ctx_(nullptr), user_accepted_fn_(nullptr), user_accepted_fn_ctx_(nullptr),
368 user_accepted_ctx_(nullptr), user_visitor_fn_(nullptr), initialized_(false) {}
382 static int32_t goal_trampoline(
const uint8_t goal_id[16],
const uint8_t* data,
size_t len,
387 if (GoalType::ffi_deserialize(data, len, &g) != 0) {
390 if (self->user_goal_fn_ctx_ !=
nullptr) {
391 return static_cast<int32_t
>(self->user_goal_fn_ctx_(goal_id, g, self->user_goal_ctx_));
393 if (self->user_goal_fn_ !=
nullptr) {
394 return static_cast<int32_t
>(self->user_goal_fn_(goal_id, g));
399 static int32_t cancel_trampoline(
const uint8_t goal_id[16],
void* ctx) {
402 if (self->user_cancel_fn_ctx_ !=
nullptr) {
403 return static_cast<int32_t
>(self->user_cancel_fn_ctx_(goal_id, self->user_cancel_ctx_));
405 if (self->user_cancel_fn_ !=
nullptr) {
406 return static_cast<int32_t
>(self->user_cancel_fn_(goal_id));
411 static void accepted_trampoline(
const uint8_t goal_id[16],
void* ctx) {
414 if (self->user_accepted_fn_ctx_ !=
nullptr) {
415 self->user_accepted_fn_ctx_(goal_id, self->user_accepted_ctx_);
418 if (self->user_accepted_fn_ !=
nullptr) {
419 self->user_accepted_fn_(goal_id);
423 Result install_callbacks() {
424 bool goal_set = (user_goal_fn_ !=
nullptr) || (user_goal_fn_ctx_ !=
nullptr);
425 bool cancel_set = (user_cancel_fn_ !=
nullptr) || (user_cancel_fn_ctx_ !=
nullptr);
426 bool accepted_set = (user_accepted_fn_ !=
nullptr) || (user_accepted_fn_ctx_ !=
nullptr);
430 if (ret != 0)
return Result(ret);
440 alignas(8) uint8_t storage_[NROS_CPP_ACTION_SERVER_STORAGE_SIZE];
444 void* user_goal_ctx_;
447 void* user_cancel_ctx_;
450 void* user_accepted_ctx_;
455 char action_name_[256] = {};
467 const ActionServerOptions& options) {
470 nros_cpp_ret_t ret = nros_cpp_action_server_create(&handle_, action_name, A::TYPE_NAME,
471 A::Goal::TYPE_HASH, ffi_qos, out.storage_);
472 if (ret != 0)
return Result(ret);
479 uint8_t sched = (options.sched_context == SCHED_CONTEXT_UNSET)
481 :
static_cast<uint8_t
>(options.sched_context);
482 ret = nros_cpp_action_server_register(out.storage_, executor_handle_, action_name, A::TYPE_NAME,
483 A::Goal::TYPE_HASH, sched);
488 while (action_name[name_len] !=
'\0' && name_len + 1 <
sizeof(out.action_name_)) {
489 out.action_name_[name_len] = action_name[name_len];
492 out.action_name_[name_len] =
'\0';
493 out.executor_ = executor_handle_;
494 out.initialized_ =
true;
int32_t(* nros_cpp_goal_callback_t)(const uint8_t goal_id[16], const uint8_t *data, size_t len, void *ctx)
Definition action_server.hpp:37
nros_cpp_ret_t nros_cpp_action_server_set_callbacks(void *handle, nros_cpp_goal_callback_t goal_cb, nros_cpp_cancel_callback_t cancel_cb, void *ctx)
int32_t(* nros_cpp_cancel_callback_t)(const uint8_t goal_id[16], void *ctx)
Definition action_server.hpp:39
nros_cpp_ret_t nros_cpp_action_server_set_accepted_callback(void *handle, nros_cpp_accepted_callback_t accepted_cb, void *ctx)
void(* nros_cpp_accepted_callback_t)(const uint8_t goal_id[16], void *ctx)
Definition action_server.hpp:44
Definition action_server.hpp:125
void(*)(const uint8_t uuid[16]) TypedAcceptedFn
User-facing typed accepted-goal callback signature (issue 0796).
Definition action_server.hpp:141
ActionServer()
Definition action_server.hpp:364
Result for_each_active_goal(F f)
Definition action_server.hpp:288
bool is_valid() const
Check if the action server is initialized and valid.
Definition action_server.hpp:306
ActionServer & operator=(ActionServer &&other)
Definition action_server.hpp:336
typename A::Goal GoalType
Definition action_server.hpp:127
Result complete_goal(const uint8_t goal_id[16], GoalStatus status, const ResultType &result)
Definition action_server.hpp:261
void(*)(const uint8_t uuid[16], GoalStatus status) TypedVisitorFn
User-facing visitor signature for for_each_active_goal.
Definition action_server.hpp:145
Result set_goal_callback(F f)
Definition action_server.hpp:153
void(*)(const uint8_t uuid[16], void *ctx) TypedAcceptedFnWithCtx
User-facing typed accepted-goal callback signature with user context.
Definition action_server.hpp:143
Result set_cancel_callback(F f)
Definition action_server.hpp:179
Result set_cancel_callback_with_ctx(TypedCancelFnWithCtx f, void *ctx)
Definition action_server.hpp:193
~ActionServer()
Destructor — releases action server resources.
Definition action_server.hpp:309
Result publish_feedback(const uint8_t goal_id[16], const FeedbackType &feedback)
Definition action_server.hpp:241
CancelResponse(*)(const uint8_t uuid[16], void *ctx) TypedCancelFnWithCtx
User-facing typed cancel callback signature with user context (Phase 84.G9).
Definition action_server.hpp:139
Result set_goal_callback_with_ctx(TypedGoalFnWithCtx f, void *ctx)
Definition action_server.hpp:168
typename A::Feedback FeedbackType
Definition action_server.hpp:129
ActionServer(ActionServer &&other)
Definition action_server.hpp:321
GoalResponse(*)(const uint8_t uuid[16], const GoalType &goal, void *ctx) TypedGoalFnWithCtx
User-facing typed goal callback signature with user context (Phase 84.G9).
Definition action_server.hpp:135
GoalResponse(*)(const uint8_t uuid[16], const GoalType &goal) TypedGoalFn
User-facing typed goal callback signature.
Definition action_server.hpp:132
CancelResponse(*)(const uint8_t uuid[16]) TypedCancelFn
User-facing typed cancel callback signature.
Definition action_server.hpp:137
Result complete_goal(const uint8_t goal_id[16], const ResultType &result)
Definition action_server.hpp:276
Result set_accepted_callback(F f)
Definition action_server.hpp:216
typename A::Result ResultType
Definition action_server.hpp:128
Result set_accepted_callback_with_ctx(TypedAcceptedFnWithCtx f, void *ctx)
Definition action_server.hpp:228
Result create_action_server(ActionServer< A > &out, const char *action_name, const QoS &qos=QoS::services(), const ActionServerOptions &options={})
Definition action_server.hpp:466
Inline storage-size macros for opaque entity buffers.
int nros_cpp_ret_t
Definition future.hpp:21
GoalResponse
Goal acceptance response returned from the user's goal callback.
Definition action_server.hpp:57
CancelResponse
Definition action_server.hpp:71
GoalStatus
Definition action_server.hpp:92
@ Error
Generic failure not covered by a more specific code.
CancelReturnCode
Definition action_server.hpp:83
nros::Node and global session helpers.
nros::Result, nros::ErrorCode, and the NROS_TRY macro.