-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Generate correct code for nested arrays of own type #748
base: rolling
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -150,6 +150,22 @@ enum | |
@[end if]@ | ||
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> | ||
|
||
@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | ||
@# We must define the sequence type before the type itself | ||
@# for the special case, that the type contains a sequence | ||
@# of the type itself. | ||
// forward declare type | ||
struct @(idl_structure_type_to_c_typename(message.structure.namespaced_type)); | ||
// Struct for a sequence of @(idl_structure_type_to_c_typename(message.structure.namespaced_type)). | ||
typedef struct @(idl_structure_type_sequence_to_c_typename(message.structure.namespaced_type)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I understand that you are putting the Sequence struct before the single struct, so that the single struct could contain as members a Sequence of itself, correct? If so, maybe add that to the comment for future readers. Could even put it in a template comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a comment |
||
{ | ||
struct @(idl_structure_type_to_c_typename(message.structure.namespaced_type)) * data; | ||
/// The number of valid items in data | ||
size_t size; | ||
/// The number of allocated items in data | ||
size_t capacity; | ||
} @(idl_structure_type_sequence_to_c_typename(message.structure.namespaced_type)); | ||
|
||
@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | ||
/// Struct defined in @(interface_path_to_string(interface_path)) in the package @(package_name). | ||
@{comments = message.structure.get_comment_lines()}@ | ||
|
@@ -179,13 +195,3 @@ typedef struct @(idl_structure_type_to_c_typename(message.structure.namespaced_t | |
} @(idl_structure_type_to_c_typename(message.structure.namespaced_type)); | ||
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> | ||
|
||
@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | ||
// Struct for a sequence of @(idl_structure_type_to_c_typename(message.structure.namespaced_type)). | ||
typedef struct @(idl_structure_type_sequence_to_c_typename(message.structure.namespaced_type)) | ||
{ | ||
@(idl_structure_type_to_c_typename(message.structure.namespaced_type)) * data; | ||
/// The number of valid items in data | ||
size_t size; | ||
/// The number of allocated items in data | ||
size_t capacity; | ||
} @(idl_structure_type_sequence_to_c_typename(message.structure.namespaced_type)); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,9 @@ include_parts = [package_name] + list(interface_path.parents[0].parts) + [ | |
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] | ||
include_base = '/'.join(include_parts) | ||
|
||
message_namespace = '::'.join([package_name] + list(interface_path.parents[0].parts)) | ||
message_namespaced_name = '::'.join([message_namespace, message.structure.namespaced_type.name]) | ||
|
||
header_files = [ | ||
'array', | ||
'cstddef', # providing offsetof() | ||
|
@@ -45,6 +48,19 @@ header_files = [ | |
@[ end if]@ | ||
#include "@(header_file)" | ||
@[end for]@ | ||
|
||
|
||
namespace rosidl_typesupport_introspection_cpp | ||
{ | ||
|
||
// forward declare template, as it may be used in MessageMember | ||
template<> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just a forward decl for a function defined lower down, right? If you could you add a comment to that effect? Is it not already declared in the If we do need the forward declaration here - then I want to point out this expression
Which is repeated many times in this file, and I think could be factored out into a variable at the top level block for easier reading and refactoring. Maybe factor out
And that would really simplify some of the expressions farther down, make them more readable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are declaring that a special instance of the template function (for the given template argument) is present, and will be defined later. If we don't do this, we will get a compile error. (Usage of template function before instantiation) I refactored the rest of the code as suggested. |
||
ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC | ||
const rosidl_message_type_support_t * | ||
get_message_type_support_handle<@(message_namespaced_name)>(); | ||
|
||
} // namespace rosidl_typesupport_introspection_cpp | ||
|
||
@[for ns in message.structure.namespaced_type.namespaces]@ | ||
|
||
namespace @(ns) | ||
|
@@ -57,12 +73,12 @@ namespace rosidl_typesupport_introspection_cpp | |
void @(message.structure.namespaced_type.name)_init_function( | ||
void * message_memory, rosidl_runtime_cpp::MessageInitialization _init) | ||
{ | ||
new (message_memory) @('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))(_init); | ||
new (message_memory) @(message_namespaced_name)(_init); | ||
} | ||
|
||
void @(message.structure.namespaced_type.name)_fini_function(void * message_memory) | ||
{ | ||
auto typed_message = static_cast<@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name])) *>(message_memory); | ||
auto typed_message = static_cast<@(message_namespaced_name) *>(message_memory); | ||
typed_message->~@(message.structure.namespaced_type.name)(); | ||
} | ||
|
||
|
@@ -241,7 +257,7 @@ static const ::rosidl_typesupport_introspection_cpp::MessageMembers @(message.st | |
"@('::'.join([package_name] + list(interface_path.parents[0].parts)))", // message namespace | ||
"@(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]))), | ||
sizeof(@(message_namespaced_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) | ||
|
@@ -269,7 +285,7 @@ namespace rosidl_typesupport_introspection_cpp | |
template<> | ||
ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC | ||
const rosidl_message_type_support_t * | ||
get_message_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))>() | ||
get_message_type_support_handle<@(message_namespaced_name)>() | ||
{ | ||
return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_introspection_cpp::@(message.structure.namespaced_type.name)_message_type_support_handle; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you hit a case where there was a multiple of a type in here?
all_type_descriptions
should be a unique set to begin withThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I ran into this problem.
//test gen rcl_interfaces/msg/ParameterValue {'type_name': 'rcl_interfaces/msg/ParameterValue', 'fields': [{'name': 'type', 'type': {'type_id': 3, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'bool_value', 'type': {'type_id': 15, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'integer_value', 'type': {'type_id': 8, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'double_value', 'type': {'type_id': 11, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'string_value', 'type': {'type_id': 17, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'byte_array_value', 'type': {'type_id': 160, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'bool_array_value', 'type': {'type_id': 159, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'integer_array_value', 'type': {'type_id': 152, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'double_array_value', 'type': {'type_id': 155, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'string_array_value', 'type': {'type_id': 161, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'value_array_value', 'type': {'type_id': 145, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': 'rcl_interfaces/msg/ParameterValue'}, 'default_value': ''}]}
static char rcl_interfaces__msg__ParameterValue__TYPE_NAME[] = "rcl_interfaces/msg/ParameterValue";
//test gen rcl_interfaces/msg/ParameterValue {'type_name': 'rcl_interfaces/msg/ParameterValue', 'fields': [{'name': 'type', 'type': {'type_id': 3, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'bool_value', 'type': {'type_id': 15, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'integer_value', 'type': {'type_id': 8, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'double_value', 'type': {'type_id': 11, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'string_value', 'type': {'type_id': 17, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'byte_array_value', 'type': {'type_id': 160, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'bool_array_value', 'type': {'type_id': 159, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'integer_array_value', 'type': {'type_id': 152, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'double_array_value', 'type': {'type_id': 155, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'string_array_value', 'type': {'type_id': 161, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': ''}, 'default_value': ''}, {'name': 'value_array_value', 'type': {'type_id': 145, 'capacity': 0, 'string_capacity': 0, 'nested_type_name': 'rcl_interfaces/msg/ParameterValue'}, 'default_value': ''}]}
static char rcl_interfaces__msg__ParameterValue__TYPE_NAME[] = "rcl_interfaces/msg/ParameterValue";
For an unknown reason, this is not an unique set....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I guess toplevel_msg['type_description'] and toplevel_msg['referenced_type_descriptions'] are equal in this special case ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, yeah - because you have
Then
toplevel_msg['referenced_type_descriptions']
contains as one of its members thetoplevel_msg['type_description']
. So, there can only be this one possible case where any type gets defined twice, and that's if it is self-referencing. I think this change is fine, given that. No need to add a special-case code when you can detect it generically like this.