15 #include "rcl/node_type_cache.h"
20 #include "rcl/type_description_conversions.h"
22 #include "rcl/error_handling.h"
25 #include "rcutils/error_handling.h"
26 #include "rcutils/types/hash_map.h"
27 #include "rcutils/types/rcutils_ret.h"
29 #include "./context_impl.h"
30 #include "./node_impl.h"
41 static size_t get_type_hash_hashmap_key(
const void * key)
44 const rosidl_type_hash_t * type_hash = key;
45 return *(
size_t *)type_hash->value;
48 static int cmp_type_hash(
const void * val1,
const void * val2)
50 return memcmp(val1, val2,
sizeof(rosidl_type_hash_t));
57 if (NULL != node->
impl->registered_types_by_type_hash.impl) {
62 rcutils_ret_t ret = rcutils_hash_map_init(
63 &node->
impl->registered_types_by_type_hash, 2,
sizeof(rosidl_type_hash_t),
65 get_type_hash_hashmap_key, cmp_type_hash,
68 if (RCUTILS_RET_OK != ret) {
70 RCL_SET_ERROR_MSG(
"Failed to initialize type cache hash map");
83 rosidl_type_hash_t key;
85 rcutils_ret_t hash_map_ret = rcutils_hash_map_get_next_key_and_data(
86 &node->
impl->registered_types_by_type_hash, NULL, &key,
87 &type_info_with_registrations);
89 if (RCUTILS_RET_NOT_INITIALIZED == hash_map_ret) {
93 while (RCUTILS_RET_OK == hash_map_ret) {
94 hash_map_ret = rcutils_hash_map_unset(
95 &node->
impl->registered_types_by_type_hash, &key);
96 if (hash_map_ret != RCUTILS_RET_OK) {
97 RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(
98 "Failed to clear out type informations [%s] during shutdown; memory "
100 rcutils_get_error_string().str);
104 type_description_interfaces__msg__TypeDescription__destroy(
105 type_info_with_registrations.
type_info.type_description);
106 type_description_interfaces__msg__TypeSource__Sequence__destroy(
107 type_info_with_registrations.
type_info.type_sources);
109 hash_map_ret = rcutils_hash_map_get_next_key_and_data(
110 &node->
impl->registered_types_by_type_hash, NULL, &key,
111 &type_info_with_registrations);
114 rcutils_ret_t rcutils_ret =
115 rcutils_hash_map_fini(&node->
impl->registered_types_by_type_hash);
120 rcl_ret_t rcl_node_type_cache_get_type_info(
122 const rosidl_type_hash_t * type_hash,
133 rcutils_hash_map_get(
134 &node->
impl->registered_types_by_type_hash,
135 type_hash, &type_info_with_registrations);
136 if (RCUTILS_RET_OK == ret) {
137 *type_info = type_info_with_registrations.
type_info;
139 }
else if (RCUTILS_RET_NOT_INITIALIZED == ret) {
146 rcl_ret_t rcl_node_type_cache_register_type(
147 const rcl_node_t * node,
const rosidl_type_hash_t * type_hash,
148 const rosidl_runtime_c__type_description__TypeDescription * type_description,
149 const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources)
159 const rcutils_ret_t rcutils_ret = rcutils_hash_map_get(
160 &node->
impl->registered_types_by_type_hash,
161 type_hash, &type_info_with_registrations);
163 if (RCUTILS_RET_OK == rcutils_ret) {
167 }
else if (RCUTILS_RET_NOT_FOUND == rcutils_ret) {
172 type_info_with_registrations.
type_info.type_description =
173 rcl_convert_type_description_runtime_to_msg(type_description);
174 if (type_info_with_registrations.
type_info.type_description == NULL) {
180 type_info_with_registrations.
type_info.type_sources =
181 rcl_convert_type_source_sequence_runtime_to_msg(type_description_sources);
182 if (type_info_with_registrations.
type_info.type_sources == NULL) {
184 type_description_interfaces__msg__TypeDescription__destroy(
185 type_info_with_registrations.
type_info.type_description);
193 if (RCUTILS_RET_OK !=
194 rcutils_hash_map_set(
195 &node->
impl->registered_types_by_type_hash,
196 type_hash, &type_info_with_registrations))
199 rcutils_reset_error();
200 RCL_SET_ERROR_MSG(
"Failed to update type info");
201 type_description_interfaces__msg__TypeDescription__destroy(
202 type_info_with_registrations.
type_info.type_description);
203 type_description_interfaces__msg__TypeSource__Sequence__destroy(
204 type_info_with_registrations.
type_info.type_sources);
211 rcl_ret_t rcl_node_type_cache_unregister_type(
213 const rosidl_type_hash_t * type_hash)
221 if (RCUTILS_RET_OK !=
222 rcutils_hash_map_get(
223 &node->
impl->registered_types_by_type_hash,
224 type_hash, &type_info))
226 RCL_SET_ERROR_MSG(
"Failed to unregister type, hash not present in map.");
231 if (RCUTILS_RET_OK !=
232 rcutils_hash_map_set(
233 &node->
impl->registered_types_by_type_hash,
234 type_hash, &type_info))
236 RCL_SET_ERROR_MSG(
"Failed to update type info");
240 if (RCUTILS_RET_OK !=
241 rcutils_hash_map_unset(
242 &node->
impl->registered_types_by_type_hash,
245 RCL_SET_ERROR_MSG(
"Failed to unregister type info");
249 type_description_interfaces__msg__TypeDescription__destroy(
251 type_description_interfaces__msg__TypeSource__Sequence__destroy(
rcl_allocator_t allocator
Allocator used during init and shutdown.
rcl_context_impl_t * impl
Implementation specific pointer.
Structure which encapsulates a ROS Node.
rcl_node_impl_t * impl
Private implementation pointer.
rcl_context_t * context
Context associated with this node.
size_t num_registrations
Counter to keep track of registrations.
rcl_type_info_t type_info
The actual type info.
#define RCL_RET_NOT_INIT
rcl_init() not yet called return code.
#define RCL_RET_OK
Success return code.
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
#define RCL_RET_ERROR
Unspecified error return code.
#define RCL_RET_NODE_INVALID
Invalid rcl_node_t given return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.