diff --git a/rcl/CMakeLists.txt b/rcl/CMakeLists.txt index 1f659df..c8ee073 100644 --- a/rcl/CMakeLists.txt +++ b/rcl/CMakeLists.txt @@ -44,6 +44,7 @@ set(${PROJECT_NAME}_sources src/rcl/logging_rosout.c src/rcl/logging.c src/rcl/node.c + src/rcl/node_options.c src/rcl/publisher.c src/rcl/remap.c src/rcl/rmw_implementation_identifier_check.c diff --git a/rcl/include/rcl/node.h b/rcl/include/rcl/node.h index 71f6f0b..74a77ca 100644 --- a/rcl/include/rcl/node.h +++ b/rcl/include/rcl/node.h @@ -26,12 +26,10 @@ extern "C" #include "rcl/arguments.h" #include "rcl/context.h" #include "rcl/macros.h" +#include "rcl/node_options.h" #include "rcl/types.h" #include "rcl/visibility_control.h" -/// Constant which indicates that the default domain id should be used. -#define RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID SIZE_MAX - struct rcl_guard_condition_t; struct rcl_node_impl_t; @@ -45,52 +43,6 @@ typedef struct rcl_node_t struct rcl_node_impl_t * impl; } rcl_node_t; -/// Structure which encapsulates the options for creating a rcl_node_t. -typedef struct rcl_node_options_t -{ - // bool anonymous_name; - - // rmw_qos_profile_t parameter_qos; - - /// If true, no parameter infrastructure will be setup. - // bool no_parameters; - - /// If set, then this value overrides the ROS_DOMAIN_ID environment variable. - /** - * It defaults to RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, which will cause the - * node to use the ROS domain ID set in the ROS_DOMAIN_ID environment - * variable, or on some systems 0 if the environment variable is not set. - * - * \todo TODO(wjwwood): - * Should we put a limit on the ROS_DOMAIN_ID value, that way we can have - * a safe value for the default RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID? - * (currently max size_t) - */ - size_t domain_id; - - /// Custom allocator used for internal allocations. - rcl_allocator_t allocator; - - /// If false then only use arguments in this struct, otherwise use global arguments also. - bool use_global_arguments; - - /// Command line arguments that apply only to this node. - rcl_arguments_t arguments; -} rcl_node_options_t; - -/// Return the default node options in a rcl_node_options_t. -/** - * The default values are: - * - * - domain_id = RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID - * - allocator = rcl_get_default_allocator() - * - use_global_arguments = true - * - arguments = rcl_get_zero_initialized_arguments() - */ -RCL_PUBLIC -rcl_node_options_t -rcl_node_get_default_options(void); - /// Return a rcl_node_t struct with members initialized to `NULL`. RCL_PUBLIC RCL_WARN_UNUSED @@ -221,31 +173,6 @@ RCL_WARN_UNUSED rcl_ret_t rcl_node_fini(rcl_node_t * node); -/// Copy one options structure into another. -/** - *
- * Attribute | Adherence - * ------------------ | ------------- - * Allocates Memory | Yes - * Thread-Safe | No - * Uses Atomics | No - * Lock-Free | Yes - * - * \param[in] options The structure to be copied. - * Its allocator is used to copy memory into the new structure. - * \param[out] options_out An options structure containing default values. - * \return `RCL_RET_OK` if the structure was copied successfully, or - * \return `RCL_RET_INVALID_ARGUMENT` if any function arguments are invalid, or - * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or - * \return `RCL_RET_ERROR` if an unspecified error occurs. - */ -RCL_PUBLIC -RCL_WARN_UNUSED -rcl_ret_t -rcl_node_options_copy( - const rcl_node_options_t * options, - rcl_node_options_t * options_out); - /// Return `true` if the node is valid, else `false`. /** * Also return `false` if the node pointer is `NULL` or the allocator is invalid. diff --git a/rcl/include/rcl/node_options.h b/rcl/include/rcl/node_options.h new file mode 100644 index 0000000..2512c9f --- /dev/null +++ b/rcl/include/rcl/node_options.h @@ -0,0 +1,127 @@ +// Copyright 2019 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCL__NODE_OPTIONS_H_ +#define RCL__NODE_OPTIONS_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rcl/allocator.h" +#include "rcl/arguments.h" + +/// Constant which indicates that the default domain id should be used. +#define RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID SIZE_MAX + +/// Structure which encapsulates the options for creating a rcl_node_t. +typedef struct rcl_node_options_t +{ + // bool anonymous_name; + + // rmw_qos_profile_t parameter_qos; + + /// If true, no parameter infrastructure will be setup. + // bool no_parameters; + + /// If set, then this value overrides the ROS_DOMAIN_ID environment variable. + /** + * It defaults to RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, which will cause the + * node to use the ROS domain ID set in the ROS_DOMAIN_ID environment + * variable, or on some systems 0 if the environment variable is not set. + * + * \todo TODO(wjwwood): + * Should we put a limit on the ROS_DOMAIN_ID value, that way we can have + * a safe value for the default RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID? + * (currently max size_t) + */ + size_t domain_id; + + /// Custom allocator used for internal allocations. + rcl_allocator_t allocator; + + /// If false then only use arguments in this struct, otherwise use global arguments also. + bool use_global_arguments; + + /// Command line arguments that apply only to this node. + rcl_arguments_t arguments; +} rcl_node_options_t; + +/// Return the default node options in a rcl_node_options_t. +/** + * The default values are: + * + * - domain_id = RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID + * - allocator = rcl_get_default_allocator() + * - use_global_arguments = true + * - arguments = rcl_get_zero_initialized_arguments() + */ +RCL_PUBLIC +rcl_node_options_t +rcl_node_get_default_options(void); + +/// Copy one options structure into another. +/** + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] options The structure to be copied. + * Its allocator is used to copy memory into the new structure. + * \param[out] options_out An options structure containing default values. + * \return `RCL_RET_OK` if the structure was copied successfully, or + * \return `RCL_RET_INVALID_ARGUMENT` if any function arguments are invalid, or + * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or + * \return `RCL_RET_ERROR` if an unspecified error occurs. + */ +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_node_options_copy( + const rcl_node_options_t * options, + rcl_node_options_t * options_out); + +/// Finalize the given node_options. +/** + * The given node_options must be non-`NULL` and valid, i.e. had + * `rcl_node_get_default_options()` called on it but not this function yet. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | No + * Uses Atomics | Yes + * Lock-Free | Yes + * + * \param[inout] node_options object to be finalized + * \return `RCL_RET_OK` if setup is successful, or + * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or + * \return `RCL_RET_ERROR` if an unspecified error occurs. + */ +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_node_options_fini(rcl_node_options_t * options); + +#ifdef __cplusplus +} +#endif + +#endif // RCL__NODE_OPTIONS_H_ diff --git a/rcl/src/rcl/node.c b/rcl/src/rcl/node.c index 34c9c26..536cddb 100644 --- a/rcl/src/rcl/node.c +++ b/rcl/src/rcl/node.c @@ -559,41 +559,6 @@ rcl_node_is_valid(const rcl_node_t * node) return true; } -rcl_node_options_t -rcl_node_get_default_options() -{ - // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING - static rcl_node_options_t default_options = { - .domain_id = RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, - .use_global_arguments = true, - }; - // Must set the allocator after because it is not a compile time constant. - default_options.allocator = rcl_get_default_allocator(); - default_options.arguments = rcl_get_zero_initialized_arguments(); - return default_options; -} - -rcl_ret_t -rcl_node_options_copy( - const rcl_node_options_t * options, - rcl_node_options_t * options_out) -{ - RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT); - RCL_CHECK_ARGUMENT_FOR_NULL(options_out, RCL_RET_INVALID_ARGUMENT); - if (options_out == options) { - RCL_SET_ERROR_MSG("Attempted to copy options into itself"); - return RCL_RET_INVALID_ARGUMENT; - } - options_out->domain_id = options->domain_id; - options_out->allocator = options->allocator; - options_out->use_global_arguments = options->use_global_arguments; - if (NULL != options->arguments.impl) { - rcl_ret_t ret = rcl_arguments_copy(&(options->arguments), &(options_out->arguments)); - return ret; - } - return RCL_RET_OK; -} - const char * rcl_node_get_name(const rcl_node_t * node) { diff --git a/rcl/src/rcl/node_options.c b/rcl/src/rcl/node_options.c new file mode 100644 index 0000000..3d7eddc --- /dev/null +++ b/rcl/src/rcl/node_options.c @@ -0,0 +1,82 @@ +// Copyright 2015 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rcl/node_options.h" + +#include "rcl/arguments.h" +#include "rcl/error_handling.h" +#include "rcl/logging_rosout.h" + +rcl_node_options_t +rcl_node_get_default_options() +{ + // !!! MAKE SURE THAT CHANGES TO THESE DEFAULTS ARE REFLECTED IN THE HEADER DOC STRING + static rcl_node_options_t default_options = { + .domain_id = RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID, + .use_global_arguments = true, + }; + // Must set the allocator after because it is not a compile time constant. + default_options.allocator = rcl_get_default_allocator(); + default_options.arguments = rcl_get_zero_initialized_arguments(); + return default_options; +} + +rcl_ret_t +rcl_node_options_copy( + const rcl_node_options_t * options, + rcl_node_options_t * options_out) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(options_out, RCL_RET_INVALID_ARGUMENT); + if (options_out == options) { + RCL_SET_ERROR_MSG("Attempted to copy options into itself"); + return RCL_RET_INVALID_ARGUMENT; + } + options_out->domain_id = options->domain_id; + options_out->allocator = options->allocator; + options_out->use_global_arguments = options->use_global_arguments; + if (NULL != options->arguments.impl) { + rcl_ret_t ret = rcl_arguments_copy(&(options->arguments), &(options_out->arguments)); + return ret; + } + return RCL_RET_OK; +} + +rcl_ret_t +rcl_node_options_fini( + rcl_node_options_t * options) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(options, RCL_RET_INVALID_ARGUMENT); + rcl_allocator_t allocator = options->allocator; + RCL_CHECK_ALLOCATOR(&allocator, return RCL_RET_INVALID_ARGUMENT); + + if (options->arguments.impl) { + rcl_ret_t ret = rcl_arguments_fini(&options->arguments); + if (RCL_RET_OK != ret) { + RCL_SET_ERROR_MSG("Failed to fini rcl arguments"); + return ret; + } + } + + return RCL_RET_OK; +} + +#ifdef __cplusplus +} +#endif