Skip to content

Commit

Permalink
Adding interfaces to support @key annotation (#796)
Browse files Browse the repository at this point in the history
Signed-off-by: Mario Dominguez <[email protected]>
Signed-off-by: Miguel Company <[email protected]>
Co-authored-by: Mario Dominguez <[email protected]>
  • Loading branch information
MiguelCompany and Mario-DL authored Apr 8, 2024
1 parent 4088280 commit a8d9f8b
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 0 deletions.
10 changes: 10 additions & 0 deletions rosidl_parser/rosidl_parser/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,16 @@ 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):
"""
Check whether any member has a particular annotation.
:param str name: the name of the annotation
:returns: True if there is at least one member with the annotation, False otherwise
"""
has_any = [member.name for member in self.members if member.has_annotation(name)]
return bool(has_any)


class Include:
"""An include statement."""
Expand Down
4 changes: 4 additions & 0 deletions rosidl_parser/test/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,23 +203,27 @@ def test_message_parser_annotations(message_idl_file):
assert structure.annotations[1].value == 'SHMEM_REF'

assert len(structure.members[2].annotations) == 1
assert structure.has_any_member_with_annotation('autoid') is False

assert structure.members[2].annotations[0].name == 'default'
assert len(structure.members[2].annotations[0].value) == 1
assert 'value' in structure.members[2].annotations[0].value
assert structure.members[2].annotations[0].value['value'] == 123
assert structure.has_any_member_with_annotation('default')

assert len(structure.members[3].annotations) == 2

assert structure.members[3].annotations[0].name == 'key'
assert structure.members[3].annotations[0].value is None
assert structure.has_any_member_with_annotation('key')

assert structure.members[3].annotations[1].name == 'range'
assert len(structure.members[3].annotations[1].value) == 2
assert 'min' in structure.members[3].annotations[1].value
assert structure.members[3].annotations[1].value['min'] == -10
assert 'max' in structure.members[3].annotations[1].value
assert structure.members[3].annotations[1].value['max'] == 10
assert structure.has_any_member_with_annotation('range')

assert isinstance(structure.members[32].type, BasicType)
assert structure.members[32].type.typename == 'float'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ typedef struct rosidl_typesupport_introspection_c__MessageMember_s
/// If the type_id_ value is rosidl_typesupport_introspection_c__ROS_TYPE_MESSAGE,
/// this points to an array describing the fields of the sub-interface.
const rosidl_message_type_support_t * members_;
/// True if this field is annotated as `@key`, false otherwise.
bool is_key_;
/// True if this field is an array type, false if it is any other type. An
/// array has the same value for / type_id_.
bool is_array_;
Expand Down Expand Up @@ -90,6 +92,8 @@ typedef struct rosidl_typesupport_introspection_c__MessageMembers_s
uint32_t member_count_;
/// The size of the interface structure in memory
size_t size_of_;
/// A boolean value indicating if there are any members annotated as `@key` in the structure.
bool has_any_key_member_;
/// A pointer to the array that describes each field of the interface
const rosidl_typesupport_introspection_c__MessageMember * members_;
/// The function used to initialise the interface's in-memory representation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ for index, member in enumerate(message.structure.members):
print(' 0, // upper bound of string')
# const rosidl_message_type_support_t * members_
print(' NULL, // members of sub message (initialized later)')
# bool is_key_
print(' %s, // is key' % ('true' if member.has_annotation('key') else 'false'))
# bool is_array_
print(' %s, // is array' % ('true' if isinstance(member.type, AbstractNestedType) else 'false'))
# size_t array_size_
Expand Down Expand Up @@ -276,6 +278,11 @@ static const rosidl_typesupport_introspection_c__MessageMembers @(function_prefi
"@(message.structure.namespaced_type.name)", // message name
@(len(message.structure.members)), // number of fields
sizeof(@('__'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))),
@[ if message.structure.has_any_member_with_annotation('key') ]@
true, // has_any_key_member_
@[ else]@
false, // has_any_key_member_
@[ end if]@
@(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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ typedef struct ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC MessageMember_s
/// If the type_id_ value is rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE
/// this points to an array describing the fields of the sub-interface.
const rosidl_message_type_support_t * members_;
/// True if this field is annotated as `@key`, false otherwise.
bool is_key_;
/// True if this field is an array, false if it is a unary type. An array has the same value for
/// type_id_.
bool is_array_;
Expand Down Expand Up @@ -97,6 +99,8 @@ typedef struct ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC MessageMembers_s
uint32_t member_count_;
/// The size of the interface structure in memory
size_t size_of_;
/// A boolean value indicating if there are any members annotated as `@key` in the structure.
bool has_any_key_member_;
/// A pointer to the array that describes each field of the interface
const MessageMember * members_;
/// The function used to initialise the interface's in-memory representation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ for index, member in enumerate(message.structure.members):
print(' 0, // upper bound of string')
# const rosidl_message_type_support_t * members_
print(' ::rosidl_typesupport_introspection_cpp::get_message_type_support_handle<%s>(), // members of sub message' % '::'.join(type_.namespaced_name()))
# bool is_key_
print(' %s, // is key' % ('true' if member.has_annotation('key') else 'false'))
# bool is_array_
print(' %s, // is array' % ('true' if isinstance(member.type, AbstractNestedType) else 'false'))
# size_t array_size_
Expand Down Expand Up @@ -242,6 +244,11 @@ static const ::rosidl_typesupport_introspection_cpp::MessageMembers @(message.st
"@(message.structure.namespaced_type.name)", // message name
@(len(message.structure.members)), // number of fields
sizeof(@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))),
@[ if message.structure.has_any_member_with_annotation('key') ]@
true, // has_any_key_member_
@[ else]@
false, // has_any_key_member_
@[ end if]@
@(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)
Expand Down

0 comments on commit a8d9f8b

Please sign in to comment.