Support for rclcpp::NodeOptions (#379)

* Move node_options into it's own header.

Signed-off-by: Michael Carroll <michael@openrobotics.org>

* Check before fini to avoid duplicate.

Signed-off-by: Michael Carroll <michael@openrobotics.org>
This commit is contained in:
Michael Carroll 2019-02-06 14:00:46 -06:00 committed by William Woodall
parent 114bc52891
commit b301180872
5 changed files with 211 additions and 109 deletions

View file

@ -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

View file

@ -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.
/**
* <hr>
* 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.

View file

@ -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.
/**
* <hr>
* 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.
*
* <hr>
* 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_

View file

@ -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)
{

View file

@ -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