From 6a831d39c6439c36209bbae7c1dfb1379753ee26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Dom=C3=ADnguez=20L=C3=B3pez?= <116071334+Mario-DL@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:18:12 +0100 Subject: [PATCH] Refs #20596: Topic keys (humble backport) * Refs #20156: Add is_key_ field to identify member as key Signed-off-by: Mario Dominguez * Refs #20156: Add has_any_member_with_annotation() method for a struct Signed-off-by: Mario Dominguez * Refs #20310: Define v2 ABI identifier Signed-off-by: Mario Dominguez * Refs #20310: Update Message introspection with a new static key_members_array in the parent messagemembers Signed-off-by: Mario Dominguez * Refs #20310: Review suggestions Signed-off-by: Mario Dominguez * Refs #20310: NITs Signed-off-by: Mario Dominguez --------- Signed-off-by: Mario Dominguez --- rosidl_parser/rosidl_parser/definition.py | 9 ++++++++ .../identifier.h | 4 ++++ .../message_introspection.h | 2 ++ .../resource/msg__type_support.c.em | 22 +++++++++++++++++-- .../src/identifier.c | 1 + .../identifier.hpp | 4 ++++ .../message_introspection.hpp | 2 ++ .../resource/msg__type_support.cpp.em | 22 +++++++++++++++++-- .../src/identifier.cpp | 4 ++++ 9 files changed, 66 insertions(+), 4 deletions(-) diff --git a/rosidl_parser/rosidl_parser/definition.py b/rosidl_parser/rosidl_parser/definition.py index 20b6f7af8..713f94672 100644 --- a/rosidl_parser/rosidl_parser/definition.py +++ b/rosidl_parser/rosidl_parser/definition.py @@ -507,6 +507,15 @@ def __init__(self, namespaced_type: NamespacedType, members=None): self.namespaced_type = namespaced_type self.members = members or [] + def has_any_member_with_annotation(self, name: str): + """ + Returns whether any member has a particular annotation. + + :param name: the annotation name + """ + has_any = [member.name for member in self.members if member.has_annotation(name)] + return bool(has_any) + class Include: """An include statement.""" diff --git a/rosidl_typesupport_introspection_c/include/rosidl_typesupport_introspection_c/identifier.h b/rosidl_typesupport_introspection_c/include/rosidl_typesupport_introspection_c/identifier.h index 32f545536..787f6d255 100644 --- a/rosidl_typesupport_introspection_c/include/rosidl_typesupport_introspection_c/identifier.h +++ b/rosidl_typesupport_introspection_c/include/rosidl_typesupport_introspection_c/identifier.h @@ -26,6 +26,10 @@ extern "C" ROSIDL_TYPESUPPORT_INTROSPECTION_C_PUBLIC extern const char * rosidl_typesupport_introspection_c__identifier; +/// String identifying the typesupport introspection implementation in use. +ROSIDL_TYPESUPPORT_INTROSPECTION_C_PUBLIC +extern const char * rosidl_typesupport_introspection_c__identifier_v2; + #ifdef __cplusplus } #endif diff --git a/rosidl_typesupport_introspection_c/include/rosidl_typesupport_introspection_c/message_introspection.h b/rosidl_typesupport_introspection_c/include/rosidl_typesupport_introspection_c/message_introspection.h index d5d220e08..530d03a54 100644 --- a/rosidl_typesupport_introspection_c/include/rosidl_typesupport_introspection_c/message_introspection.h +++ b/rosidl_typesupport_introspection_c/include/rosidl_typesupport_introspection_c/message_introspection.h @@ -95,6 +95,8 @@ typedef struct rosidl_typesupport_introspection_c__MessageMembers_s void (* init_function)(void *, enum rosidl_runtime_c__message_initialization); /// The function used to clean up the interface's in-memory representation void (* fini_function)(void *); + /// A pointer to the array that indicates whether each field is annotated as @key + const bool * key_members_array_; } rosidl_typesupport_introspection_c__MessageMembers; #endif // ROSIDL_TYPESUPPORT_INTROSPECTION_C__MESSAGE_INTROSPECTION_H_ diff --git a/rosidl_typesupport_introspection_c/resource/msg__type_support.c.em b/rosidl_typesupport_introspection_c/resource/msg__type_support.c.em index 5a213df01..dd6b780b2 100644 --- a/rosidl_typesupport_introspection_c/resource/msg__type_support.c.em +++ b/rosidl_typesupport_introspection_c/resource/msg__type_support.c.em @@ -197,6 +197,23 @@ bool @(function_prefix)__resize_function__@(message.structure.namespaced_type.na @[ end if]@ @[ end if]@ @[end for]@ + +static bool @(function_prefix)__@(message.structure.namespaced_type.name)_key_members_array[@(len(message.structure.members))] = { +@{ +for index, member in enumerate(message.structure.members): + if member.has_annotation('key'): + if index < len(message.structure.members) - 1: + print(' true,') + else: + print(' true') + else: + if index < len(message.structure.members) - 1: + print(' false,') + else: + print(' false') +}@ +}; + static rosidl_typesupport_introspection_c__MessageMember @(function_prefix)__@(message.structure.namespaced_type.name)_message_member_array[@(len(message.structure.members))] = { @{ for index, member in enumerate(message.structure.members): @@ -274,7 +291,8 @@ static const rosidl_typesupport_introspection_c__MessageMembers @(function_prefi sizeof(@('__'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))), @(function_prefix)__@(message.structure.namespaced_type.name)_message_member_array, // message members @(function_prefix)__@(message.structure.namespaced_type.name)_init_function, // function to initialize message memory (memory has to be allocated) - @(function_prefix)__@(message.structure.namespaced_type.name)_fini_function // function to terminate message instance (will not free memory) + @(function_prefix)__@(message.structure.namespaced_type.name)_fini_function, // function to terminate message instance (will not free memory) + @(function_prefix)__@(message.structure.namespaced_type.name)_key_members_array // mapping to each field to know whether it is keyed or not }; // this is not const since it must be initialized on first access @@ -301,7 +319,7 @@ if isinstance(type_, AbstractNestedType): @[end for]@ if (!@(function_prefix)__@(message.structure.namespaced_type.name)_message_type_support_handle.typesupport_identifier) { @(function_prefix)__@(message.structure.namespaced_type.name)_message_type_support_handle.typesupport_identifier = - rosidl_typesupport_introspection_c__identifier; + rosidl_typesupport_introspection_c__identifier_v2; } return &@(function_prefix)__@(message.structure.namespaced_type.name)_message_type_support_handle; } diff --git a/rosidl_typesupport_introspection_c/src/identifier.c b/rosidl_typesupport_introspection_c/src/identifier.c index 60da35ce3..7691710a0 100644 --- a/rosidl_typesupport_introspection_c/src/identifier.c +++ b/rosidl_typesupport_introspection_c/src/identifier.c @@ -15,3 +15,4 @@ #include "rosidl_typesupport_introspection_c/identifier.h" const char * rosidl_typesupport_introspection_c__identifier = "rosidl_typesupport_introspection_c"; +const char * rosidl_typesupport_introspection_c__identifier_v2 = "rosidl_typesupport_introspection_c_v2"; \ No newline at end of file diff --git a/rosidl_typesupport_introspection_cpp/include/rosidl_typesupport_introspection_cpp/identifier.hpp b/rosidl_typesupport_introspection_cpp/include/rosidl_typesupport_introspection_cpp/identifier.hpp index 26d875511..097a97116 100644 --- a/rosidl_typesupport_introspection_cpp/include/rosidl_typesupport_introspection_cpp/identifier.hpp +++ b/rosidl_typesupport_introspection_cpp/include/rosidl_typesupport_introspection_cpp/identifier.hpp @@ -24,6 +24,10 @@ namespace rosidl_typesupport_introspection_cpp ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_IMPORT extern const char * typesupport_identifier; +/// String identifying the typesupport introspection implementation in use. +ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_IMPORT +extern const char * typesupport_identifier_v2; + } // namespace rosidl_typesupport_introspection_cpp #endif // ROSIDL_TYPESUPPORT_INTROSPECTION_CPP__IDENTIFIER_HPP_ diff --git a/rosidl_typesupport_introspection_cpp/include/rosidl_typesupport_introspection_cpp/message_introspection.hpp b/rosidl_typesupport_introspection_cpp/include/rosidl_typesupport_introspection_cpp/message_introspection.hpp index 2340f2c8c..291a01ed2 100644 --- a/rosidl_typesupport_introspection_cpp/include/rosidl_typesupport_introspection_cpp/message_introspection.hpp +++ b/rosidl_typesupport_introspection_cpp/include/rosidl_typesupport_introspection_cpp/message_introspection.hpp @@ -102,6 +102,8 @@ typedef struct ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC MessageMembers_s void (* init_function)(void *, rosidl_runtime_cpp::MessageInitialization); /// The function used to clean up the interface's in-memory representation void (* fini_function)(void *); + /// A pointer to the array that indicates whether each field is annotated as @key + const bool * key_members_array_; } MessageMembers; } // namespace rosidl_typesupport_introspection_cpp diff --git a/rosidl_typesupport_introspection_cpp/resource/msg__type_support.cpp.em b/rosidl_typesupport_introspection_cpp/resource/msg__type_support.cpp.em index 60cc226c4..7d815eaa6 100644 --- a/rosidl_typesupport_introspection_cpp/resource/msg__type_support.cpp.em +++ b/rosidl_typesupport_introspection_cpp/resource/msg__type_support.cpp.em @@ -162,6 +162,23 @@ void resize_function__@(message.structure.namespaced_type.name)__@(member.name)( @[ end if]@ @[ end if]@ @[end for]@ + +static const bool @(message.structure.namespaced_type.name)_key_members_array[@(len(message.structure.members))] = { +@{ +for index, member in enumerate(message.structure.members): + if member.has_annotation('key'): + if index < len(message.structure.members) - 1: + print(' true,') + else: + print(' true') + else: + if index < len(message.structure.members) - 1: + print(' false,') + else: + print(' false') +}@ +}; + static const ::rosidl_typesupport_introspection_cpp::MessageMember @(message.structure.namespaced_type.name)_message_member_array[@(len(message.structure.members))] = { @{ for index, member in enumerate(message.structure.members): @@ -239,11 +256,12 @@ static const ::rosidl_typesupport_introspection_cpp::MessageMembers @(message.st sizeof(@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))), @(message.structure.namespaced_type.name)_message_member_array, // message members @(message.structure.namespaced_type.name)_init_function, // function to initialize message memory (memory has to be allocated) - @(message.structure.namespaced_type.name)_fini_function // function to terminate message instance (will not free memory) + @(message.structure.namespaced_type.name)_fini_function, // function to terminate message instance (will not free memory) + @(message.structure.namespaced_type.name)_key_members_array // mapping to each field to know whether it is keyed or not }; static const rosidl_message_type_support_t @(message.structure.namespaced_type.name)_message_type_support_handle = { - ::rosidl_typesupport_introspection_cpp::typesupport_identifier, + ::rosidl_typesupport_introspection_cpp::typesupport_identifier_v2, &@(message.structure.namespaced_type.name)_message_members, get_message_typesupport_handle_function, }; diff --git a/rosidl_typesupport_introspection_cpp/src/identifier.cpp b/rosidl_typesupport_introspection_cpp/src/identifier.cpp index 4df544e23..d830962e7 100644 --- a/rosidl_typesupport_introspection_cpp/src/identifier.cpp +++ b/rosidl_typesupport_introspection_cpp/src/identifier.cpp @@ -20,4 +20,8 @@ namespace rosidl_typesupport_introspection_cpp ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_EXPORT const char * typesupport_identifier = "rosidl_typesupport_introspection_cpp"; + +ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_EXPORT +const char * typesupport_identifier_v2 = "rosidl_typesupport_introspection_cpp_v2"; + } // namespace rosidl_typesupport_introspection_cpp