diff --git a/rcl/include/rcl/time.h b/rcl/include/rcl/time.h index 7025f25..eec388b 100644 --- a/rcl/include/rcl/time.h +++ b/rcl/include/rcl/time.h @@ -102,6 +102,41 @@ RCL_WARN_UNUSED bool rcl_time_source_valid(rcl_time_source_t * time_source); +/// Initialize a time_source based on the passed type. +/** + * This will allocate all necessary internal structures, and initialize variables. + * + * \param[in] time_source_type the type identifying the time source to provide + * \param[in] time_source the handle to the time_source which is being initialized + * \return `RCL_RET_OK` if the time source was successfully initialized, or + * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or + * \return `RCL_RET_ERROR` an unspecified error occur. + */ +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_init_time_source( + enum rcl_time_source_type_t time_source_type, rcl_time_source_t * time_source +); + +/// Finalize a time_source. +/** + * This will deallocate all necessary internal structures, and clean up any variables. + * It can be combined with any of the init functions. + * + * Passing a time_source with type RCL_TIME_SOURCE_UNINITIALIZED will result in + * RCL_RET_INVALID_ARGUMENT being returned. + * + * \param[in] time_source the handle to the time_source which is being finalized + * \return `RCL_RET_OK` if the time source was successfully finalized, or + * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or + * \return `RCL_RET_ERROR` an unspecified error occur. + */ +RCL_PUBLIC +RCL_WARN_UNUSED +rcl_ret_t +rcl_fini_time_source(rcl_time_source_t * time_source); + /// Initialize a time_source as a RCL_ROS_TIME time source. /** * This will allocate all necessary internal structures, and initialize variables. diff --git a/rcl/src/rcl/time.c b/rcl/src/rcl/time.c index 90b5dd1..d52b099 100644 --- a/rcl/src/rcl/time.c +++ b/rcl/src/rcl/time.c @@ -88,6 +88,45 @@ rcl_time_source_valid(rcl_time_source_t * time_source) return true; } +rcl_ret_t +rcl_init_time_source( + enum rcl_time_source_type_t time_source_type, rcl_time_source_t * time_source +) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(time_source, RCL_RET_INVALID_ARGUMENT); + switch (time_source_type) { + case RCL_TIME_SOURCE_UNINITIALIZED: + rcl_init_generic_time_source(time_source); + return RCL_RET_OK; + case RCL_ROS_TIME: + return rcl_init_ros_time_source(time_source); + case RCL_SYSTEM_TIME: + return rcl_init_system_time_source(time_source); + case RCL_STEADY_TIME: + return rcl_init_steady_time_source(time_source); + default: + return RCL_RET_INVALID_ARGUMENT; + } +} + +rcl_ret_t +rcl_fini_time_source(rcl_time_source_t * time_source) +{ + RCL_CHECK_ARGUMENT_FOR_NULL(time_source, RCL_RET_INVALID_ARGUMENT); + switch (time_source->type) { + case RCL_ROS_TIME: + return rcl_fini_ros_time_source(time_source); + case RCL_SYSTEM_TIME: + return rcl_fini_system_time_source(time_source); + case RCL_STEADY_TIME: + return rcl_fini_steady_time_source(time_source); + case RCL_TIME_SOURCE_UNINITIALIZED: + // fall through + default: + return RCL_RET_INVALID_ARGUMENT; + } +} + rcl_ret_t rcl_init_ros_time_source(rcl_time_source_t * time_source) { diff --git a/rcl/test/rcl/test_time.cpp b/rcl/test/rcl/test_time.cpp index 8adee88..b386ae1 100644 --- a/rcl/test/rcl/test_time.cpp +++ b/rcl/test/rcl/test_time.cpp @@ -291,6 +291,44 @@ TEST(CLASSNAME(rcl_time, RMW_IMPLEMENTATION), default_time_source_instanciation) ASSERT_TRUE(rcl_time_source_valid(system_time_source)); } +TEST(CLASSNAME(rcl_time, RMW_IMPLEMENTATION), specific_time_source_instantiation) { + { + rcl_time_source_t uninitialized_time_source; + rcl_ret_t ret = rcl_init_time_source( + RCL_TIME_SOURCE_UNINITIALIZED, &uninitialized_time_source); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + EXPECT_EQ(uninitialized_time_source.type, RCL_TIME_SOURCE_UNINITIALIZED) << + "Expected time source of type RCL_TIME_SOURCE_UNINITIALIZED"; + } + { + rcl_time_source_t ros_time_source; + rcl_ret_t ret = rcl_init_time_source(RCL_ROS_TIME, &ros_time_source); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + EXPECT_EQ(ros_time_source.type, RCL_ROS_TIME) << + "Expected time source of type RCL_ROS_TIME"; + ret = rcl_fini_time_source(&ros_time_source); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + } + { + rcl_time_source_t system_time_source; + rcl_ret_t ret = rcl_init_time_source(RCL_SYSTEM_TIME, &system_time_source); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + EXPECT_EQ(system_time_source.type, RCL_SYSTEM_TIME) << + "Expected time source of type RCL_SYSTEM_TIME"; + ret = rcl_fini_time_source(&system_time_source); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + } + { + rcl_time_source_t steady_time_source; + rcl_ret_t ret = rcl_init_time_source(RCL_STEADY_TIME, &steady_time_source); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + EXPECT_EQ(steady_time_source.type, RCL_STEADY_TIME) << + "Expected time source of type RCL_STEADY_TIME"; + ret = rcl_fini_time_source(&steady_time_source); + EXPECT_EQ(ret, RCL_RET_OK) << rcl_get_error_string_safe(); + } +} + TEST(CLASSNAME(rcl_time, RMW_IMPLEMENTATION), rcl_time_difference) { rcl_ret_t ret; rcl_time_point_t a, b;