diff --git a/rosidl_typesupport_connext_c/bin/rosidl_typesupport_connext_c b/rosidl_typesupport_connext_c/bin/rosidl_typesupport_connext_c index 012c55b..cd9c350 100644 --- a/rosidl_typesupport_connext_c/bin/rosidl_typesupport_connext_c +++ b/rosidl_typesupport_connext_c/bin/rosidl_typesupport_connext_c @@ -28,10 +28,8 @@ def main(argv=sys.argv[1:]): help='The location of the file containing the generator arguments') args = parser.parse_args(argv) - generator_args = read_generator_arguments(args.generator_arguments_file) - try: - rc = generate_typesupport_connext_c(generator_args) + rc = generate_typesupport_connext_c(args.generator_arguments_file) except UnknownMessageType as e: print(str(e), file=sys.stderr) return 1 diff --git a/rosidl_typesupport_connext_c/cmake/rosidl_typesupport_connext_c_generate_interfaces.cmake b/rosidl_typesupport_connext_c/cmake/rosidl_typesupport_connext_c_generate_interfaces.cmake index 2a10c67..4087a78 100644 --- a/rosidl_typesupport_connext_c/cmake/rosidl_typesupport_connext_c_generate_interfaces.cmake +++ b/rosidl_typesupport_connext_c/cmake/rosidl_typesupport_connext_c_generate_interfaces.cmake @@ -1,4 +1,4 @@ -# Copyright 2016 Open Source Robotics Foundation, Inc. +# Copyright 2016-2018 Open Source Robotics Foundation, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,65 +12,29 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(_ros_idl_files "") -foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) - get_filename_component(_extension "${_idl_file}" EXT) - # Skip .srv files - if(_extension STREQUAL ".msg") - list(APPEND _ros_idl_files "${_idl_file}") - endif() -endforeach() - -set(_dds_idl_files "") +set(_output_path + "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_c/${PROJECT_NAME}") +set(_dds_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_cpp/${PROJECT_NAME}") set(_dds_idl_base_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_dds_idl") -foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) - get_filename_component(_extension "${_idl_file}" EXT) - if(_extension STREQUAL ".msg") - get_filename_component(_parent_folder "${_idl_file}" DIRECTORY) - get_filename_component(_parent_folder "${_parent_folder}" NAME) - get_filename_component(_name "${_idl_file}" NAME_WE) - list(APPEND _dds_idl_files - "${_dds_idl_base_path}/${PROJECT_NAME}/${_parent_folder}/dds_connext/${_name}_.idl") - endif() -endforeach() -set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_c/${PROJECT_NAME}") -set(_dds_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_cpp/${PROJECT_NAME}") +set(_dds_idl_files "") set(_generated_files "") set(_generated_external_files "") -foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) - get_filename_component(_parent_folder "${_idl_file}" DIRECTORY) +foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES}) + get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY) get_filename_component(_parent_folder "${_parent_folder}" NAME) - get_filename_component(_extension "${_idl_file}" EXT) - get_filename_component(_msg_name "${_idl_file}" NAME_WE) - string_camel_case_to_lower_case_underscore("${_msg_name}" _header_name) - if(_extension STREQUAL ".msg" AND _msg_name MATCHES "Response$|Request$") - # Don't do anything - elseif(_extension STREQUAL ".msg") - set(_allowed_parent_folders "msg" "srv" "action") - if(NOT _parent_folder IN_LIST _allowed_parent_folders) - message(FATAL_ERROR "Interface file with unknown parent folder: ${_idl_file}") - endif() - list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_.h") - list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_.cxx") - list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Plugin.h") - list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Plugin.cxx") - list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Support.h") - list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Support.cxx") - list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_c.h") - list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext_c/${_header_name}__type_support_c.cpp") - elseif(_extension STREQUAL ".srv") - set(_allowed_parent_folders "srv" "action") - if(NOT _parent_folder IN_LIST _allowed_parent_folders) - message(FATAL_ERROR "Interface file with unknown parent folder: ${_idl_file}") - endif() - list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_c.h") - list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext_c/${_header_name}__type_support_c.cpp") - list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext_c/${_header_name}__request__type_support_c.cpp") - list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext_c/${_header_name}__response__type_support_c.cpp") - else() - message(FATAL_ERROR "Interface file with unknown extension: ${_idl_file}") - endif() + get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE) + # Turn idl name into file names + string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name) + list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_.h") + list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_.cxx") + list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Plugin.h") + list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Plugin.cxx") + list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Support.h") + list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Support.cxx") + list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext/${_header_name}__type_support_c.cpp") + list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_c.h") + list(APPEND _dds_idl_files "${_dds_idl_base_path}/${PROJECT_NAME}/${_parent_folder}/dds_connext/${_idl_name}_.idl") endforeach() # If not on Windows, disable some warnings with Connext's generated code @@ -101,34 +65,30 @@ endif() set(_dependency_files "") set(_dependencies "") foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) - foreach(_idl_file ${${_pkg_name}_INTERFACE_FILES}) - get_filename_component(_extension "${_idl_file}" EXT) - if(_extension STREQUAL ".msg") - get_filename_component(_parent_folder "${_idl_file}" DIRECTORY) - get_filename_component(_parent_folder "${_parent_folder}" NAME) - get_filename_component(_name "${_idl_file}" NAME_WE) - set(_abs_idl_file "${${_pkg_name}_DIR}/../${_parent_folder}/dds_connext/${_name}_.idl") - normalize_path(_abs_idl_file "${_abs_idl_file}") - list(APPEND _dependency_files "${_abs_idl_file}") - set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}") - normalize_path(_abs_idl_file "${_abs_idl_file}") - list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}") - endif() + foreach(_idl_file ${${_pkg_name}_IDL_FILES}) + # ${{_pkg_name}_DIR} is absolute path ending in 'share//cmake', so go back one + # directory for IDL files + set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}") + normalize_path(_abs_idl_file "${_abs_idl_file}") + list(APPEND _dependency_files "${_abs_idl_file}") + list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}") endforeach() endforeach() set(target_dependencies "${rosidl_typesupport_connext_c_BIN}" ${rosidl_typesupport_connext_c_GENERATOR_FILES} + "${rosidl_typesupport_connext_c_TEMPLATE_DIR}/idl__rosidl_typesupport_connext_c.h.em" + "${rosidl_typesupport_connext_c_TEMPLATE_DIR}/idl__dds_connext__type_support_c.cpp.em" + "${rosidl_typesupport_connext_c_TEMPLATE_DIR}/msg__rosidl_typesupport_connext_c.h.em" "${rosidl_typesupport_connext_c_TEMPLATE_DIR}/msg__type_support_c.cpp.em" + "${rosidl_typesupport_connext_c_TEMPLATE_DIR}/srv__rosidl_typesupport_connext_c.h.em" "${rosidl_typesupport_connext_c_TEMPLATE_DIR}/srv__type_support_c.cpp.em" + ${rosidl_generate_interfaces_ABS_IDL_FILES} ${_dependency_files}) foreach(dep ${target_dependencies}) if(NOT EXISTS "${dep}") - get_property(is_generated SOURCE "${dep}" PROPERTY GENERATED) - if(NOT ${_is_generated}) message(FATAL_ERROR "Target dependency '${dep}' does not exist") - endif() endif() endforeach() @@ -136,7 +96,7 @@ set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_con rosidl_write_generator_arguments( "${generator_arguments_file}" PACKAGE_NAME "${PROJECT_NAME}" - ROS_INTERFACE_FILES "${rosidl_generate_interfaces_IDL_FILES}" + IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}" ROS_INTERFACE_DEPENDENCIES "${_dependencies}" OUTPUT_DIR "${_output_path}" TEMPLATE_DIR "${rosidl_typesupport_connext_c_TEMPLATE_DIR}" @@ -150,7 +110,7 @@ add_custom_command( --generator-arguments-file "${generator_arguments_file}" DEPENDS ${target_dependencies} - ${generated_external_files} + ${_generated_external_files} ${_dds_idl_files} COMMENT "Generating C type support for RTI Connext" VERBATIM diff --git a/rosidl_typesupport_connext_c/resource/idl__dds_connext__type_support_c.cpp.em b/rosidl_typesupport_connext_c/resource/idl__dds_connext__type_support_c.cpp.em new file mode 100644 index 0000000..9e4f00f --- /dev/null +++ b/rosidl_typesupport_connext_c/resource/idl__dds_connext__type_support_c.cpp.em @@ -0,0 +1,79 @@ +// generated from rosidl_typesupport_connext_c/resource/idl__dds_connext__type_support_c.cpp.em +// with input from @(package_name):@(interface_path) +// generated code does not contain a copyright notice + +#include +#include + +@{ +####################################################################### +# EmPy template for generating __type_support_c.cpp files +# +# Context: +# - package_name (string) +# - content (rosidl_parser.definition.IdlContent result of parsing IDL file) +# - interface_path (Path relative to the directory named after the package) +####################################################################### +include_directives = set() +####################################################################### +# Handle message +####################################################################### +from rosidl_parser.definition import Message +for message in content.get_elements_of_type(Message): + TEMPLATE( + 'msg__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + message=message, include_directives=include_directives + ) +####################################################################### +# Handle service +####################################################################### +from rosidl_parser.definition import Service +for service in content.get_elements_of_type(Service): + TEMPLATE( + 'srv__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + service=service, include_directives=include_directives + ) +####################################################################### +# Handle action +####################################################################### +from rosidl_parser.definition import Action +for action in content.get_elements_of_type(Action): + TEMPLATE( + 'msg__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + message=action.goal, + include_directives=include_directives + ) + TEMPLATE( + 'srv__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + service=action.send_goal_service, + include_directives=include_directives + ) + TEMPLATE( + 'msg__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + message=action.result, + include_directives=include_directives + ) + TEMPLATE( + 'srv__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + service=action.get_result_service, + include_directives=include_directives + ) + TEMPLATE( + 'msg__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + message=action.feedback, + include_directives=include_directives + ) + TEMPLATE( + 'msg__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + message=action.feedback_message, + include_directives=include_directives + ) +}@ diff --git a/rosidl_typesupport_connext_c/resource/idl__rosidl_typesupport_connext_c.h.em b/rosidl_typesupport_connext_c/resource/idl__rosidl_typesupport_connext_c.h.em new file mode 100644 index 0000000..c96243d --- /dev/null +++ b/rosidl_typesupport_connext_c/resource/idl__rosidl_typesupport_connext_c.h.em @@ -0,0 +1,83 @@ +// generated from rosidl_typesupport_connext_c/resource/idl__rosidl_typesupport_connext_c.h.em +// with input from @(package_name):@(interface_path) +// generated code does not contain a copyright notice + +@{ +####################################################################### +# EmPy template for generating __rosidl_typesupport_connext_c.h files +# +# Context: +# - package_name (string) +# - content (rosidl_parser.definition.IdlContent result of parsing IDL file) +# - interface_path (Path relative to the directory named after the package) +####################################################################### +from rosidl_cmake import convert_camel_case_to_lower_case_underscore +include_parts = [package_name] + list(interface_path.parents[0].parts) + \ + [convert_camel_case_to_lower_case_underscore(interface_path.stem)] +header_guard_variable = '__'.join([x.upper() for x in include_parts]) + \ + '__ROSIDL_TYPESUPPORT_CONNEXT_C_H_' +include_directives = set() +}@ + +#ifndef @(header_guard_variable) +#define @(header_guard_variable) + +@{ +####################################################################### +# Handle message +####################################################################### +from rosidl_parser.definition import Message +for message in content.get_elements_of_type(Message): + TEMPLATE( + 'msg__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, message=message, + include_directives=include_directives + ) +####################################################################### +# Handle service +####################################################################### +from rosidl_parser.definition import Service +for service in content.get_elements_of_type(Service): + TEMPLATE( + 'srv__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, service=service, + include_directives=include_directives + ) +####################################################################### +# Handle action +####################################################################### +from rosidl_parser.definition import Action +for action in content.get_elements_of_type(Action): + TEMPLATE( + 'msg__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, message=action.goal, + include_directives=include_directives + ) + TEMPLATE( + 'msg__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, message=action.result, + include_directives=include_directives + ) + TEMPLATE( + 'msg__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, message=action.feedback, + include_directives=include_directives + ) + TEMPLATE( + 'srv__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, service=action.send_goal_service, + include_directives=include_directives + ) + TEMPLATE( + 'srv__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, service=action.get_result_service, + include_directives=include_directives + ) + TEMPLATE( + 'msg__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, message=action.feedback_message, + include_directives=include_directives + ) +}@ + +#endif // @(header_guard_variable) diff --git a/rosidl_typesupport_connext_c/resource/msg__rosidl_typesupport_connext_c.h.em b/rosidl_typesupport_connext_c/resource/msg__rosidl_typesupport_connext_c.h.em index 4f62b0e..1ab58cc 100644 --- a/rosidl_typesupport_connext_c/resource/msg__rosidl_typesupport_connext_c.h.em +++ b/rosidl_typesupport_connext_c/resource/msg__rosidl_typesupport_connext_c.h.em @@ -1,45 +1,33 @@ -// generated from -// rosidl_typesupport_connext_c/resource/msg__rosidl_typesupport_connext_c.h.em -// generated code does not contain a copyright notice - -@####################################################################### -@# EmPy template for generating -@# __rosidl_typesupport_connext_c.h files -@# -@# Context: -@# - spec (rosidl_parser.MessageSpecification) -@# Parsed specification of the .msg file -@# - subfolder (string) -@# The subfolder / subnamespace of the message -@# Could be 'msg', 'srv' or 'action' -@# - get_header_filename_from_msg_name (function) -@####################################################################### -@ +@# Included from rosidl_typesupport_connext_c/resource/idl__rosidl_typesupport_connext_c.h.em @{ -header_guard_parts = [ - spec.base_type.pkg_name, subfolder, - get_header_filename_from_msg_name(spec.base_type.type) + '__rosidl_typesupport_connext_c_h'] -header_guard_variable = '__'.join([x.upper() for x in header_guard_parts]) + '_' +header_files = [ + 'rosidl_generator_c/message_type_support_struct.h', + 'rosidl_typesupport_interface/macros.h', + package_name + '/msg/rosidl_typesupport_connext_c__visibility_control.h' +] }@ -#ifndef @(header_guard_variable) -#define @(header_guard_variable) - -#include "rosidl_generator_c/message_type_support_struct.h" -#include "rosidl_typesupport_interface/macros.h" - -#include "@(spec.base_type.pkg_name)/msg/rosidl_typesupport_connext_c__visibility_control.h" +@[for header_file in header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ #ifdef __cplusplus extern "C" { #endif -ROSIDL_TYPESUPPORT_CONNEXT_C_PUBLIC_@(spec.base_type.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_C_PUBLIC_@(package_name) const rosidl_message_type_support_t * - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.base_type.pkg_name), @(subfolder), @(spec.base_type.type))(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join([package_name] + list(interface_path.parents[0].parts))), + @(message.structure.type.name))(); #ifdef __cplusplus } #endif - -#endif // @(header_guard_variable) diff --git a/rosidl_typesupport_connext_c/resource/msg__type_support_c.cpp.em b/rosidl_typesupport_connext_c/resource/msg__type_support_c.cpp.em index be86d3c..7179d54 100644 --- a/rosidl_typesupport_connext_c/resource/msg__type_support_c.cpp.em +++ b/rosidl_typesupport_connext_c/resource/msg__type_support_c.cpp.em @@ -1,40 +1,47 @@ -// generated from rosidl_typesupport_connext_c/resource/msg__type_support_c.cpp.em -// generated code does not contain a copyright notice - -@########################################################################## -@# EmPy template for generating __type_support_c.cpp files for Connext -@# -@# Context: -@# - spec (rosidl_parser.MessageSpecification) -@# Parsed specification of the .msg file -@# - pkg (string) -@# name of the containing package; equivalent to spec.base_type.pkg_name -@# - msg (string) -@# name of the message; equivalent to spec.msg_name -@# - type (string) -@# full type of the message; equivalent to spec.base_type.type -@# - subfolder (string) -@# The subfolder / subnamespace of the message -@# Could be 'msg', 'srv' or 'action' -@# - get_header_filename_from_msg_name (function) -@########################################################################## -@ -#include "@(spec.base_type.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.base_type.type))__rosidl_typesupport_connext_c.h" - -#include -#include +@# Included from rosidl_typesupport_connext_c/resource/idl__dds_connext__type_support_c.cpp.em +@{ +from rosidl_cmake import convert_camel_case_to_lower_case_underscore +from rosidl_generator_c import idl_structure_type_to_c_include_prefix +from rosidl_generator_c import idl_structure_type_to_c_typename +from rosidl_generator_c import idl_type_to_c +from rosidl_parser.definition import Array +from rosidl_parser.definition import BoundedSequence +from rosidl_parser.definition import BasicType +from rosidl_parser.definition import NamespacedType +from rosidl_parser.definition import NestedType +from rosidl_parser.definition import Sequence +from rosidl_parser.definition import String +from rosidl_parser.definition import WString +include_parts = [package_name] + list(interface_path.parents[0].parts) +include_base = '/'.join(include_parts) -#include "rcutils/types/uint8_array.h" +cpp_include_prefix = interface_path.stem +c_include_prefix = convert_camel_case_to_lower_case_underscore(cpp_include_prefix) -// Provides the rosidl_typesupport_connext_c__identifier symbol declaration. -#include "rosidl_typesupport_connext_c/identifier.h" -// Provides the definition of the message_type_support_callbacks_t struct. -#include "rosidl_typesupport_connext_cpp/message_type_support.h" +header_files = [ + include_base + '/' + c_include_prefix + '__rosidl_typesupport_connext_c.h', + 'rcutils/types/uint8_array.h', + 'rosidl_typesupport_connext_c/identifier.h', + 'rosidl_typesupport_connext_cpp/message_type_support.h', + package_name + '/msg/rosidl_typesupport_connext_c__visibility_control.h', + include_base + '/' + c_include_prefix + '__struct.h', + include_base + '/' + c_include_prefix + '__functions.h' +] -#include "@(pkg)/msg/rosidl_typesupport_connext_c__visibility_control.h" -@{header_file_name = get_header_filename_from_msg_name(type)}@ -#include "@(pkg)/@(subfolder)/@(header_file_name)__struct.h" -#include "@(pkg)/@(subfolder)/@(header_file_name)__functions.h" +dds_specific_header_files = [ + include_base + '/dds_connext/' + cpp_include_prefix + '_Support.h', + include_base + '/dds_connext/' + cpp_include_prefix + '_Plugin.h' +] +}@ +@[for header_file in header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ #ifndef _WIN32 # pragma GCC diagnostic push @@ -44,14 +51,22 @@ # pragma clang diagnostic ignored "-Wreturn-type-c-linkage" # endif #endif -#include "@(spec.base_type.pkg_name)/@(subfolder)/dds_connext/@(spec.base_type.type)_Support.h" -#include "@(spec.base_type.pkg_name)/@(subfolder)/dds_connext/@(spec.base_type.type)_Plugin.h" + +@[for header_file in dds_specific_header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ + #ifndef _WIN32 # pragma GCC diagnostic pop #endif // includes and forward declarations of message dependencies and their conversion functions - @# // Include the message header for each non-primitive field. #if defined(__cplusplus) extern "C" @@ -59,63 +74,93 @@ extern "C" #endif @{ -includes = {} -for field in spec.fields: - keys = set([]) - if field.type.is_primitive_type(): - if field.type.is_array: - keys.add('rosidl_generator_c/primitives_sequence.h') - keys.add('rosidl_generator_c/primitives_sequence_functions.h') - if field.type.type == 'string': - keys.add('rosidl_generator_c/string.h') - keys.add('rosidl_generator_c/string_functions.h') - else: - header_file_name = get_header_filename_from_msg_name(field.type.type) - keys.add('%s/msg/%s__functions.h' % (field.type.pkg_name, header_file_name)) - for key in keys: - if key not in includes: - includes[key] = set([]) - includes[key].add(field.name) +from collections import OrderedDict +includes = OrderedDict() +for member in message.structure.members: + if isinstance(member.type, Sequence) and isinstance(member.type.basetype, BasicType): + includes.setdefault('rosidl_generator_c/primitives_sequence.h', []).append(member.name) + includes.setdefault('rosidl_generator_c/primitives_sequence_functions.h', []).append(member.name) + continue + type_ = member.type + if isinstance(type_, NestedType): + type_ = type_.basetype + if isinstance(type_, String): + includes.setdefault('rosidl_generator_c/string.h', []).append(member.name) + includes.setdefault('rosidl_generator_c/string_functions.h', []).append(member.name) + if isinstance(type_, WString): + includes.setdefault('rosidl_generator_c/u16string.h', []).append(member.name) + includes.setdefault('rosidl_generator_c/u16string_functions.h', []).append(member.name) + if isinstance(type_, NamespacedType): + include_prefix = idl_structure_type_to_c_include_prefix(type_) + if include_prefix.endswith('__request'): + include_prefix = include_prefix[:-9] + elif include_prefix.endswith('__response'): + include_prefix = include_prefix[:-10] + if include_prefix.endswith('__goal'): + include_prefix = include_prefix[:-6] + elif include_prefix.endswith('__result'): + include_prefix = include_prefix[:-8] + elif include_prefix.endswith('__feedback'): + include_prefix = include_prefix[:-10] + includes.setdefault(include_prefix + '__struct.h', []).append(member.name) + includes.setdefault(include_prefix + '__functions.h', []).append(member.name) }@ -@[for key in sorted(includes.keys())]@ -#include "@(key)" // @(', '.join(includes[key])) -@[end for]@ +@[if includes]@ +// Include directives for member types +@[ for header_file, member_names in includes.items()]@ +@[ for member_name in member_names]@ +// Member '@(member_name)' +@[ end for]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[ end for]@ +@[end if]@ // forward declare type support functions @{ -forward_declares = {} -for field in spec.fields: - if not field.type.is_primitive_type(): - key = (field.type.pkg_name, field.type.type) - if key not in includes: - forward_declares[key] = set([]) - forward_declares[key].add(field.name) +from collections import OrderedDict +forward_declares = OrderedDict() +for member in message.structure.members: + type_ = member.type + if isinstance(type_, NestedType): + type_ = type_.basetype + if isinstance(type_, NamespacedType): + _, member_names = forward_declares.setdefault(type_.name, (type_, [])) + member_names.append(member.name) }@ -@[for key in sorted(forward_declares.keys())]@ -@[ if key[0] != pkg]@ -ROSIDL_TYPESUPPORT_CONNEXT_C_IMPORT_@(pkg) +@[for member_type, member_names in forward_declares.values()]@ +@[ for name in member_names]@ +// Member '@(name)' +@[ end for]@ +@[ if member_type.namespaces[0] != package_name]@ +ROSIDL_TYPESUPPORT_CONNEXT_C_IMPORT_@(package_name) @[ end if]@ const rosidl_message_type_support_t * - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(key[0]), msg, @(key[1]))(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join(member_type.namespaces)), + @(member_type.name))(); @[end for]@ @# // Make callback functions specific to this message type. - @{ -__dds_msg_type_prefix = "{0}::{1}::dds_::{2}_".format( - spec.base_type.pkg_name, subfolder, spec.base_type.type) +__ros_c_msg_type = '__'.join(message.structure.type.namespaces + [message.structure.type.name]) +__dds_cpp_msg_type_prefix = '::'.join(message.structure.type.namespaces + ['dds_', message.structure.type.name]) +__dds_cpp_msg_type = __dds_cpp_msg_type_prefix + '_' }@ -using __dds_msg_type = @(__dds_msg_type_prefix); -using __ros_msg_type = @(pkg)__@(subfolder)__@(type); - static DDS_TypeCode * -get_type_code() +_@(message.structure.type.name)__get_type_code() { - return @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::get_typecode(); + return @(__dds_cpp_msg_type_prefix)_TypeSupport::get_typecode(); } static bool -convert_ros_to_dds(const void * untyped_ros_message, void * untyped_dds_message) +_@(message.structure.type.name)__convert_ros_to_dds(const void * untyped_ros_message, void * untyped_dds_message) { if (!untyped_ros_message) { fprintf(stderr, "ros message handle is null\n"); @@ -125,56 +170,63 @@ convert_ros_to_dds(const void * untyped_ros_message, void * untyped_dds_message) fprintf(stderr, "dds message handle is null\n"); return false; } - const __ros_msg_type * ros_message = static_cast(untyped_ros_message); - __dds_msg_type * dds_message = static_cast<__dds_msg_type *>(untyped_dds_message); -@[if not spec.fields]@ + const @(__ros_c_msg_type) * ros_message = + static_cast(untyped_ros_message); + @(__dds_cpp_msg_type) * dds_message = + static_cast<@(__dds_cpp_msg_type) *>(untyped_dds_message); +@[if not message.structure.members]@ // No fields is a no-op. (void)dds_message; (void)ros_message; @[end if]@ -@[for field in spec.fields]@ - // Field name: @(field.name) +@[for member in message.structure.members]@ + // Member name: @(member.name) { -@[ if not field.type.is_primitive_type()]@ - const message_type_support_callbacks_t * @(field.type.pkg_name)__msg__@(field.type.type)__callbacks = +@{ +type_ = member.type +if isinstance(type_, NestedType): + type_ = type_.basetype +}@ +@[ if isinstance(type_, NamespacedType)]@ + const message_type_support_callbacks_t * @('__'.join(type_.namespaces + [type_.name]))__callbacks = static_cast( - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(field.type.pkg_name), msg, @(field.type.type) + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(', '.join(type_.namespaces)), @(type_.name) )()->data); @[ end if]@ -@[ if field.type.is_array]@ -@[ if field.type.array_size and not field.type.is_upper_bound]@ - size_t size = @(field.type.array_size); +@[ if isinstance(member.type, NestedType)]@ +@[ if isinstance(member.type, Array)]@ + size_t size = @(member.type.size); @[ else]@ - size_t size = ros_message->@(field.name).size; + size_t size = ros_message->@(member.name).size; if (size > (std::numeric_limits::max)()) { fprintf(stderr, "array size exceeds maximum DDS sequence size\n"); return false; } -@[ if field.type.is_upper_bound]@ - if (size > @(field.type.array_size)) { +@[ if isinstance(member.type, BoundedSequence)]@ + if (size > @(member.type.upper_bound)) { fprintf(stderr, "array size exceeds upper bound\n"); return false; } @[ end if]@ DDS_Long length = static_cast(size); - if (length > dds_message->@(field.name)_.maximum()) { - if (!dds_message->@(field.name)_.maximum(length)) { + if (length > dds_message->@(member.name)_.maximum()) { + if (!dds_message->@(member.name)_.maximum(length)) { fprintf(stderr, "failed to set maximum of sequence\n"); return false; } } - if (!dds_message->@(field.name)_.length(length)) { + if (!dds_message->@(member.name)_.length(length)) { fprintf(stderr, "failed to set length of sequence\n"); return false; } @[ end if]@ for (DDS_Long i = 0; i < static_cast(size); ++i) { -@[ if field.type.array_size and not field.type.is_upper_bound]@ - auto & ros_i = ros_message->@(field.name)[i]; +@[ if isinstance(member.type, Array)]@ + auto & ros_i = ros_message->@(member.name)[i]; @[ else]@ - auto & ros_i = ros_message->@(field.name).data[i]; + auto & ros_i = ros_message->@(member.name).data[i]; @[ end if]@ -@[ if field.type.type == 'string']@ +@[ if isinstance(type_, String)]@ const rosidl_generator_c__String * str = &ros_i; if (str->capacity == 0 || str->capacity <= str->size) { fprintf(stderr, "string capacity not greater than size\n"); @@ -184,21 +236,25 @@ convert_ros_to_dds(const void * untyped_ros_message, void * untyped_dds_message) fprintf(stderr, "string not null-terminated\n"); return false; } - dds_message->@(field.name)_[static_cast(i)] = DDS_String_dup(str->data); -@[ elif field.type.type == 'bool']@ - dds_message->@(field.name)_[i] = 1 ? ros_i : 0; -@[ elif field.type.is_primitive_type()]@ - dds_message->@(field.name)_[i] = ros_i; + dds_message->@(member.name)_[static_cast(i)] = DDS_String_dup(str->data); +@[ elif isinstance(type_, WString)]@ +@{ assert False, 'TBD'}@ +@[ elif isinstance(type_, BasicType)]@ +@[ if type_.type == 'boolean']@ + dds_message->@(member.name)_[i] = 1 ? ros_i : 0; +@[ else]@ + dds_message->@(member.name)_[i] = ros_i; +@[ end if]@ @[ else]@ - if (!@(field.type.pkg_name)__msg__@(field.type.type)__callbacks->convert_ros_to_dds( - &ros_i, &dds_message->@(field.name)_[i])) + if (!@(idl_structure_type_to_c_typename(type_))__callbacks->convert_ros_to_dds( + &ros_i, &dds_message->@(member.name)_[i])) { return false; } @[ end if]@ } -@[ elif field.type.type == 'string']@ - const rosidl_generator_c__String * str = &ros_message->@(field.name); +@[ elif isinstance(member.type, String)]@ + const rosidl_generator_c__String * str = &ros_message->@(member.name); if (str->capacity == 0 || str->capacity <= str->size) { fprintf(stderr, "string capacity not greater than size\n"); return false; @@ -207,24 +263,25 @@ convert_ros_to_dds(const void * untyped_ros_message, void * untyped_dds_message) fprintf(stderr, "string not null-terminated\n"); return false; } - dds_message->@(field.name)_ = DDS_String_dup(str->data); -@[ elif field.type.is_primitive_type()]@ - dds_message->@(field.name)_ = ros_message->@(field.name); + dds_message->@(member.name)_ = DDS_String_dup(str->data); +@[ elif isinstance(member.type, WString)]@ +@{ assert False, 'TBD'}@ +@[ elif isinstance(member.type, BasicType)]@ + dds_message->@(member.name)_ = ros_message->@(member.name); @[ else]@ - if (!@(field.type.pkg_name)__msg__@(field.type.type)__callbacks->convert_ros_to_dds( - &ros_message->@(field.name), &dds_message->@(field.name)_)) + if (!@(idl_structure_type_to_c_typename(member.type))__callbacks->convert_ros_to_dds( + &ros_message->@(member.name), &dds_message->@(member.name)_)) { return false; } @[ end if]@ } - @[end for]@ return true; } static bool -convert_dds_to_ros(const void * untyped_dds_message, void * untyped_ros_message) +_@(message.structure.type.name)__convert_dds_to_ros(const void * untyped_dds_message, void * untyped_ros_message) { if (!untyped_ros_message) { fprintf(stderr, "ros message handle is null\n"); @@ -234,97 +291,108 @@ convert_dds_to_ros(const void * untyped_dds_message, void * untyped_ros_message) fprintf(stderr, "dds message handle is null\n"); return false; } - const __dds_msg_type * dds_message = static_cast(untyped_dds_message); - __ros_msg_type * ros_message = static_cast<__ros_msg_type *>(untyped_ros_message); -@[if not spec.fields]@ + const @(__dds_cpp_msg_type) * dds_message = + static_cast(untyped_dds_message); + @(__ros_c_msg_type) * ros_message = + static_cast<@(__ros_c_msg_type) *>(untyped_ros_message); +@[if not message.structure.members]@ // No fields is a no-op. (void)dds_message; (void)ros_message; @[end if]@ -@[for field in spec.fields]@ - // Field name: @(field.name) +@[for member in message.structure.members]@ + // Member name: @(member.name) { -@[ if field.type.is_array]@ -@[ if field.type.array_size and not field.type.is_upper_bound]@ - DDS_Long size = @(field.type.array_size); -@[ else]@ @{ -if field.type.type == 'string': - array_init = 'rosidl_generator_c__String__Sequence__init' - array_fini = 'rosidl_generator_c__String__Sequence__fini' -elif field.type.is_primitive_type(): - array_init = 'rosidl_generator_c__{field.type.type}__Sequence__init'.format(**locals()) - array_fini = 'rosidl_generator_c__{field.type.type}__Sequence__fini'.format(**locals()) -else: - array_init = '{field.type.pkg_name}__msg__{field.type.type}__Sequence__init'.format(**locals()) - array_fini = '{field.type.pkg_name}__msg__{field.type.type}__Sequence__fini'.format(**locals()) +type_ = member.type +if isinstance(type_, NestedType): + type_ = type_.basetype }@ - DDS_Long size = dds_message->@(field.name)_.length(); - if (ros_message->@(field.name).data) { - @(array_fini)(&ros_message->@(field.name)); +@[ if isinstance(member.type, NestedType)]@ +@[ if isinstance(member.type, Array)]@ + DDS_Long size = @(member.type.size); +@[ else]@ + DDS_Long size = dds_message->@(member.name)_.length(); + if (ros_message->@(member.name).data) { + @(idl_type_to_c(member.type) + '__fini')(&ros_message->@(member.name)); } - if (!@(array_init)(&ros_message->@(field.name), size)) { - return "failed to create array for field '@(field.name)'"; + if (!@(idl_type_to_c(member.type) + '__init')(&ros_message->@(member.name), size)) { + return "failed to create array for field '@(member.name)'"; } @[ end if]@ for (DDS_Long i = 0; i < size; i++) { -@[ if field.type.array_size and not field.type.is_upper_bound]@ - auto & ros_i = ros_message->@(field.name)[i]; +@[ if isinstance(member.type, Array)]@ + auto & ros_i = ros_message->@(member.name)[i]; @[ else]@ - auto & ros_i = ros_message->@(field.name).data[i]; + auto & ros_i = ros_message->@(member.name).data[i]; @[ end if]@ -@[ if field.type.type == 'bool']@ - ros_i = (dds_message->@(field.name)_[i] != 0); -@[ elif field.type.type == 'string']@ +@[ if isinstance(type_, BasicType)]@ +@[ if type_.type == 'boolean']@ + ros_i = (dds_message->@(member.name)_[i] != 0); +@[ else]@ + ros_i = dds_message->@(member.name)_[i]; +@[ end if]@ +@[ elif isinstance(type_, String)]@ if (!ros_i.data) { rosidl_generator_c__String__init(&ros_i); } bool succeeded = rosidl_generator_c__String__assign( &ros_i, - dds_message->@(field.name)_[i]); + dds_message->@(member.name)_[i]); if (!succeeded) { - fprintf(stderr, "failed to assign string into field '@(field.name)'\n"); + fprintf(stderr, "failed to assign string into field '@(member.name)'\n"); return false; } -@[ elif field.type.is_primitive_type()]@ - ros_i = dds_message->@(field.name)_[i]; -@[ else]@ +@[ elif isinstance(type_, WString)]@ +@{ assert False, 'TBD'}@ +@[ elif isinstance(type_, NamespacedType)]@ const rosidl_message_type_support_t * ts = - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(field.type.pkg_name), msg, @(field.type.type))(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join(type_.namespaces)), + @(type_.name))(); const message_type_support_callbacks_t * callbacks = static_cast(ts->data); - callbacks->convert_dds_to_ros(&dds_message->@(field.name)_[i], &ros_i); + callbacks->convert_dds_to_ros(&dds_message->@(member.name)_[i], &ros_i); +@[ else]@ +@{ assert False, 'Unknown member base type'}@ @[ end if]@ } -@[ elif field.type.type == 'string']@ - if (!ros_message->@(field.name).data) { - rosidl_generator_c__String__init(&ros_message->@(field.name)); +@[ elif isinstance(member.type, String)]@ + if (!ros_message->@(member.name).data) { + rosidl_generator_c__String__init(&ros_message->@(member.name)); } bool succeeded = rosidl_generator_c__String__assign( - &ros_message->@(field.name), - dds_message->@(field.name)_); + &ros_message->@(member.name), + dds_message->@(member.name)_); if (!succeeded) { - fprintf(stderr, "failed to assign string into field '@(field.name)'\n"); + fprintf(stderr, "failed to assign string into field '@(member.name)'\n"); return false; } -@[ elif field.type.is_primitive_type()]@ - ros_message->@(field.name) = dds_message->@(field.name)_@(' == static_cast(true)' if field.type.type == 'bool' else ''); -@[ else]@ +@[ elif isinstance(member.type, WString)]@ +@{ assert False, 'TBD'}@ +@[ elif isinstance(member.type, BasicType)]@ + ros_message->@(member.name) = dds_message->@(member.name)_@(' == static_cast(true)' if member.type.type == 'boolean' else ''); +@[ elif isinstance(member.type, NamespacedType)]@ const rosidl_message_type_support_t * ts = - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(field.type.pkg_name), msg, @(field.type.type))(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join(member.type.namespaces)), + @(member.type.name))(); const message_type_support_callbacks_t * callbacks = static_cast(ts->data); - callbacks->convert_dds_to_ros(&dds_message->@(field.name)_, &ros_message->@(field.name)); + callbacks->convert_dds_to_ros(&dds_message->@(member.name)_, &ros_message->@(member.name)); +@[ else]@ +@{ assert False, 'Unknown member type'}@ @[ end if]@ } - @[end for]@ return true; } static bool -to_cdr_stream( +_@(message.structure.type.name)__to_cdr_stream( const void * untyped_ros_message, rcutils_uint8_array_t * cdr_stream) { @@ -334,18 +402,19 @@ to_cdr_stream( if (!cdr_stream) { return false; } - const __ros_msg_type * ros_message = static_cast(untyped_ros_message); - __dds_msg_type dds_message; - if (!convert_ros_to_dds(ros_message, &dds_message)) { + const @(__ros_c_msg_type) * ros_message = + static_cast(untyped_ros_message); + @(__dds_cpp_msg_type) dds_message; + if (!_@(message.structure.type.name)__convert_ros_to_dds(ros_message, &dds_message)) { return false; } // call the serialize function for the first time to get the expected length of the message unsigned int expected_length; - if (@(spec.base_type.type)_Plugin_serialize_to_cdr_buffer( + if (@(__dds_cpp_msg_type_prefix)_Plugin_serialize_to_cdr_buffer( NULL, &expected_length, &dds_message) != RTI_TRUE) { - fprintf(stderr, "failed to call @(spec.base_type.type)_Plugin_serialize_to_cdr_buffer()\n"); + fprintf(stderr, "failed to call @(__dds_cpp_msg_type_prefix)_Plugin_serialize_to_cdr_buffer()\n"); return false; } cdr_stream->buffer_length = expected_length; @@ -359,7 +428,7 @@ to_cdr_stream( } // call the function again and fill the buffer this time unsigned int buffer_length_uint = static_cast(cdr_stream->buffer_length); - if (@(spec.base_type.type)_Plugin_serialize_to_cdr_buffer( + if (@(__dds_cpp_msg_type_prefix)_Plugin_serialize_to_cdr_buffer( reinterpret_cast(cdr_stream->buffer), &buffer_length_uint, &dds_message) != RTI_TRUE) @@ -371,7 +440,7 @@ to_cdr_stream( } static bool -to_message( +_@(message.structure.type.name)__to_message( const rcutils_uint8_array_t * cdr_stream, void * untyped_ros_message) { @@ -382,13 +451,13 @@ to_message( return false; } - @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_ * dds_message = - @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::create_data(); + @(__dds_cpp_msg_type) * dds_message = + @(__dds_cpp_msg_type_prefix)_TypeSupport::create_data(); if (cdr_stream->buffer_length > (std::numeric_limits::max)()) { fprintf(stderr, "cdr_stream->buffer_length, unexpectedly larger than max unsigned int\n"); return false; } - if (@(spec.base_type.type)_Plugin_deserialize_from_cdr_buffer( + if (@(__dds_cpp_msg_type_prefix)_Plugin_deserialize_from_cdr_buffer( dds_message, reinterpret_cast(cdr_stream->buffer), static_cast(cdr_stream->buffer_length)) != RTI_TRUE) @@ -396,35 +465,37 @@ to_message( fprintf(stderr, "deserialize from cdr buffer failed\n"); return false; } - bool success = convert_dds_to_ros(dds_message, untyped_ros_message); - if (@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::delete_data(dds_message) != DDS_RETCODE_OK) { + bool success = _@(message.structure.type.name)__convert_dds_to_ros(dds_message, untyped_ros_message); + if (@(__dds_cpp_msg_type_prefix)_TypeSupport::delete_data(dds_message) != DDS_RETCODE_OK) { return false; } return success; } -@ @# // Collect the callback functions and provide a function to get the type support struct. - -static message_type_support_callbacks_t __callbacks = { - "@(pkg)", // package_name - "@(msg)", // message_name - get_type_code, // get_type_code - convert_ros_to_dds, // convert_ros_to_dds - convert_dds_to_ros, // convert_dds_to_ros - to_cdr_stream, // to_cdr_stream - to_message // to_message +static message_type_support_callbacks_t _@(message.structure.type.name)__callbacks = { + "@(package_name)", // package_name + "@(message.structure.type.name)", // message_name + _@(message.structure.type.name)__get_type_code, // get_type_code + _@(message.structure.type.name)__convert_ros_to_dds, // convert_ros_to_dds + _@(message.structure.type.name)__convert_dds_to_ros, // convert_dds_to_ros + _@(message.structure.type.name)__to_cdr_stream, // to_cdr_stream + _@(message.structure.type.name)__to_message // to_message }; -static rosidl_message_type_support_t __type_support = { +static rosidl_message_type_support_t _@(message.structure.type.name)__type_support = { rosidl_typesupport_connext_c__identifier, - &__callbacks, + &_@(message.structure.type.name)__callbacks, get_message_typesupport_handle_function, }; const rosidl_message_type_support_t * -ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(pkg), @(subfolder), @(msg))() { - return &__type_support; +ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join([package_name] + list(interface_path.parents[0].parts))), + @(message.structure.type.name))() +{ + return &_@(message.structure.type.name)__type_support; } #if defined(__cplusplus) diff --git a/rosidl_typesupport_connext_c/resource/srv__rosidl_typesupport_connext_c.h.em b/rosidl_typesupport_connext_c/resource/srv__rosidl_typesupport_connext_c.h.em index da34b1c..d1a0cf8 100644 --- a/rosidl_typesupport_connext_c/resource/srv__rosidl_typesupport_connext_c.h.em +++ b/rosidl_typesupport_connext_c/resource/srv__rosidl_typesupport_connext_c.h.em @@ -1,45 +1,51 @@ -// generated from -// rosidl_typesupport_connext_c/resource/srv__rosidl_typesupport_connext_c.h.em -// generated code does not contain a copyright notice - -@####################################################################### -@# EmPy template for generating -@# __rosidl_typesupport_connext_c.h files -@# -@# Context: -@# - spec (rosidl_parser.MessageSpecification) -@# Parsed specification of the .srv file -@# - subfolder (string) -@# The subfolder / subnamespace of the message -@# Either 'srv' or 'action' -@# - get_header_filename_from_srv_name (function) -@####################################################################### -@ +@# Included from rosidl_typesupport_connext_c/resource/srv__rosidl_typesupport_connext_c.h.em @{ -header_guard_parts = [ - spec.pkg_name, subfolder, - get_header_filename_from_msg_name(spec.srv_name) + '__rosidl_typesupport_connext_c_h'] -header_guard_variable = '__'.join([x.upper() for x in header_guard_parts]) + '_' +TEMPLATE( + 'msg__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, + message=service.request_message, + include_directives=include_directives +) }@ -#ifndef @(header_guard_variable) -#define @(header_guard_variable) -#include "rosidl_generator_c/service_type_support_struct.h" -#include "rosidl_typesupport_interface/macros.h" +@{ +TEMPLATE( + 'msg__rosidl_typesupport_connext_c.h.em', + package_name=package_name, interface_path=interface_path, + message=service.response_message, + include_directives=include_directives +) +}@ -#include "@(spec.pkg_name)/msg/rosidl_typesupport_connext_c__visibility_control.h" +@{ +header_files = [ + 'rosidl_generator_c/service_type_support_struct.h', + 'rosidl_typesupport_interface/macros.h', + package_name + '/msg/rosidl_typesupport_connext_c__visibility_control.h' +] +}@ +@[for header_file in header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ #ifdef __cplusplus extern "C" { #endif -ROSIDL_TYPESUPPORT_CONNEXT_C_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_C_PUBLIC_@(package_name) const rosidl_service_type_support_t * - ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.pkg_name), @(subfolder), @(spec.srv_name))(); + ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join([package_name] + list(interface_path.parents[0].parts))), + @(service.structure_type.name))(); #ifdef __cplusplus } #endif - -#endif // @(header_guard_variable) diff --git a/rosidl_typesupport_connext_c/resource/srv__type_support_c.cpp.em b/rosidl_typesupport_connext_c/resource/srv__type_support_c.cpp.em index 0d5ae3a..8376a3b 100644 --- a/rosidl_typesupport_connext_c/resource/srv__type_support_c.cpp.em +++ b/rosidl_typesupport_connext_c/resource/srv__type_support_c.cpp.em @@ -1,20 +1,32 @@ -// generated from rosidl_typesupport_connext_c/resource/srv__type_support_c.cpp.em -// generated code does not contain a copyright notice - -@####################################################################### -@# EmPy template for generating __type_support_c.cpp files -@# -@# Context: -@# - spec (rosidl_parser.ServiceSpecification) -@# Parsed specification of the .srv file -@# - subfolder (string) -@# The subfolder / subnamespace of the message -@# Either 'srv' or 'action' -@# - get_header_filename_from_msg_name (function) -@####################################################################### -@ -#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name))__rosidl_typesupport_connext_c.h" - +@# Included from rosidl_typesupport_connext_c/resource/idl__dds_connext__type_support_c.cpp.em +@{ +from rosidl_cmake import convert_camel_case_to_lower_case_underscore +include_parts = [package_name] + list(interface_path.parents[0].parts) +include_base = '/'.join(include_parts) +cpp_include_prefix = interface_path.stem + +c_include_prefix = convert_camel_case_to_lower_case_underscore(cpp_include_prefix) + +header_files = [ + include_base + '/' + c_include_prefix + '__rosidl_typesupport_connext_c.h', + 'rosidl_typesupport_connext_cpp/service_type_support.h', + 'rosidl_typesupport_connext_cpp/message_type_support.h', + 'rmw/rmw.h', + 'rosidl_typesupport_cpp/service_type_support.hpp', + 'rosidl_typesupport_connext_c/identifier.h', + package_name + '/msg/rosidl_typesupport_connext_c__visibility_control.h', + include_base + '/dds_connext/' + cpp_include_prefix + '_Support.h', + include_base + '/' + c_include_prefix + '.h', +# Re-use most of the functions from C++ typesupport + include_base + '/' + c_include_prefix + '__rosidl_typesupport_connext_cpp.hpp', +] + +dds_specific_header_files = [ + 'ndds/connext_cpp/connext_cpp_requester_details.h', + 'ndds/ndds_cpp.h', + 'ndds/ndds_requestreply_cpp.h' +] +}@ #ifdef Connext_GLIBCXX_USE_CXX11_ABI_ZERO #define _GLIBCXX_USE_CXX11_ABI 0 #endif @@ -27,36 +39,48 @@ # pragma clang diagnostic ignored "-Wreturn-type-c-linkage" # endif #endif -#include -#include -#include + +@[for header_file in dds_specific_header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include <@(header_file)> +@[end for]@ + #ifndef _WIN32 # pragma GCC diagnostic pop #endif -// Provides the definition of the service_type_support_callbacks_t struct. -#include -// Provides the definition of the message_type_support_callbacks_t struct. -#include - -#include "rmw/rmw.h" -#include "rmw/error_handling.h" -#include "rosidl_typesupport_cpp/service_type_support.hpp" -#include "rosidl_typesupport_connext_c/identifier.h" - -#include "@(spec.pkg_name)/msg/rosidl_typesupport_connext_c__visibility_control.h" -@{req_header_file_name = get_header_filename_from_msg_name(spec.srv_name + '__request')}@ -@{res_header_file_name = get_header_filename_from_msg_name(spec.srv_name + '__response')}@ -#include "@(spec.pkg_name)/@(subfolder)/@(req_header_file_name).h" -#include "@(spec.pkg_name)/@(subfolder)/@(res_header_file_name).h" - -#include "@(spec.pkg_name)/@(subfolder)/dds_connext/@(spec.srv_name)_Request_Support.h" -#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name + '_Request'))__rosidl_typesupport_connext_c.h" -#include "@(spec.pkg_name)/@(subfolder)/dds_connext/@(spec.srv_name)_Response_Support.h" -#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name + '_Response'))__rosidl_typesupport_connext_c.h" - -// Re-use most of the functions from C++ typesupport -#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name))__rosidl_typesupport_connext_cpp.hpp" +@[for header_file in header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ + +@{ +TEMPLATE( + 'msg__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + message=service.request_message, + include_directives=include_directives +) +}@ + +@{ +TEMPLATE( + 'msg__type_support_c.cpp.em', + package_name=package_name, interface_path=interface_path, + message=service.response_message, + include_directives=include_directives +) +}@ class DDSDomainParticipant; class DDSDataReader; @@ -67,13 +91,14 @@ extern "C" { #endif -// forward declare type support functions -const rosidl_message_type_support_t * - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.pkg_name), @(subfolder), @(spec.srv_name)_Request)(); -const rosidl_message_type_support_t * - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.pkg_name), @(subfolder), @(spec.srv_name)_Response)(); - -void * create_requester__@(subfolder)__@(spec.srv_name)( +@{ +__ros_srv_pkg_prefix = '::'.join(service.structure_type.namespaces) +__ros_request_msg_type = __ros_srv_pkg_prefix + '::' + service.request_message.structure.type.name +__ros_response_msg_type = __ros_srv_pkg_prefix + '::' + service.response_message.structure.type.name +__dds_request_msg_type = __ros_srv_pkg_prefix + '::dds_::' + service.request_message.structure.type.name + '_' +__dds_response_msg_type = __ros_srv_pkg_prefix + '::dds_::' + service.response_message.structure.type.name + '_' +}@ +static void * create_requester__@(service.structure_type.name)( void * untyped_participant, const char * request_topic_str, const char * response_topic_str, @@ -83,7 +108,7 @@ void * create_requester__@(subfolder)__@(spec.srv_name)( void ** untyped_writer, void * (*allocator)(size_t)) { - return @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::create_requester__@(spec.srv_name)( + return @('::'.join(service.structure_type.namespaces))::typesupport_connext_cpp::create_requester__@(service.structure_type.name)( untyped_participant, request_topic_str, response_topic_str, @@ -93,26 +118,28 @@ void * create_requester__@(subfolder)__@(spec.srv_name)( untyped_writer, allocator); } -const char * destroy_requester__@(subfolder)__@(spec.srv_name)( +static const char * destroy_requester__@(service.structure_type.name)( void * untyped_requester, void (* deallocator)(void *)) { - return @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::destroy_requester__@(spec.srv_name)( + return @('::'.join(service.structure_type.namespaces))::typesupport_connext_cpp::destroy_requester__@(service.structure_type.name)( untyped_requester, deallocator); } -int64_t send_request__@(subfolder)__@(spec.srv_name)( +static int64_t send_request__@(service.structure_type.name)( void * untyped_requester, const void * untyped_ros_request) { using RequesterType = connext::Requester< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; - connext::WriteSample< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_> request; + connext::WriteSample<@(__dds_request_msg_type)> request; const rosidl_message_type_support_t * ts = - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.pkg_name), @(subfolder), @(spec.srv_name)_Request)(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join(service.request_message.structure.type.namespaces)), + @(service.request_message.structure.type.name))(); const message_type_support_callbacks_t * callbacks = static_cast(ts->data); bool converted = callbacks->convert_ros_to_dds( @@ -130,7 +157,7 @@ int64_t send_request__@(subfolder)__@(spec.srv_name)( return sequence_number; } -void * create_replier__@(subfolder)__@(spec.srv_name)( +static void * create_replier__@(service.structure_type.name)( void * untyped_participant, const char * request_topic_str, const char * response_topic_str, @@ -140,7 +167,7 @@ void * create_replier__@(subfolder)__@(spec.srv_name)( void ** untyped_writer, void * (*allocator)(size_t)) { - return @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::create_replier__@(spec.srv_name)( + return @('::'.join(service.structure_type.namespaces))::typesupport_connext_cpp::create_replier__@(service.structure_type.name)( untyped_participant, request_topic_str, response_topic_str, @@ -151,22 +178,22 @@ void * create_replier__@(subfolder)__@(spec.srv_name)( allocator); } -const char * destroy_replier__@(subfolder)__@(spec.srv_name)( +static const char * destroy_replier__@(service.structure_type.name)( void * untyped_replier, void (* deallocator)(void *)) { - return @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::destroy_replier__@(spec.srv_name)( + return @('::'.join(service.structure_type.namespaces))::typesupport_connext_cpp::destroy_replier__@(service.structure_type.name)( untyped_replier, deallocator); } -bool take_request__@(subfolder)__@(spec.srv_name)( +static bool take_request__@(service.structure_type.name)( void * untyped_replier, rmw_request_id_t * request_header, void * untyped_ros_request) { using ReplierType = connext::Replier< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; if (!untyped_replier || !request_header || !untyped_ros_request) { return false; @@ -174,7 +201,7 @@ bool take_request__@(subfolder)__@(spec.srv_name)( ReplierType * replier = reinterpret_cast(untyped_replier); - connext::Sample<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_> request; + connext::Sample<@(__dds_request_msg_type)> request; bool taken = replier->take_request(request); if (!taken) { return false; @@ -184,7 +211,10 @@ bool take_request__@(subfolder)__@(spec.srv_name)( } const rosidl_message_type_support_t * ts = - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.pkg_name), @(subfolder), @(spec.srv_name)_Request)(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join(service.request_message.structure.type.namespaces)), + @(service.request_message.structure.type.name))(); const message_type_support_callbacks_t * callbacks = static_cast(ts->data); bool converted = callbacks->convert_dds_to_ros( @@ -200,19 +230,22 @@ bool take_request__@(subfolder)__@(spec.srv_name)( return true; } -bool take_response__@(subfolder)__@(spec.srv_name)( +static bool take_response__@(service.structure_type.name)( void * untyped_requester, rmw_request_id_t * request_header, void * untyped_ros_response) { - using RequesterType = connext::Requester<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_>; + using RequesterType = connext::Requester< + @(__dds_request_msg_type), + @(__dds_response_msg_type) + >; if (!untyped_requester || !request_header || !untyped_ros_response) { return false; } RequesterType * requester = reinterpret_cast(untyped_requester); - connext::Sample<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_> response; + connext::Sample<@(__dds_response_msg_type)> response; bool received = requester->take_reply(response); if (!received) { return false; @@ -227,7 +260,10 @@ bool take_response__@(subfolder)__@(spec.srv_name)( request_header->sequence_number = sequence_number; const rosidl_message_type_support_t * ts = - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.pkg_name), @(subfolder), @(spec.srv_name)_Response)(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join(service.response_message.structure.type.namespaces)), + @(service.response_message.structure.type.name))(); const message_type_support_callbacks_t * callbacks = static_cast(ts->data); bool converted = callbacks->convert_dds_to_ros( @@ -235,19 +271,25 @@ bool take_response__@(subfolder)__@(spec.srv_name)( return converted; } -bool send_response__@(subfolder)__@(spec.srv_name)( +bool send_response__@(service.structure_type.name)( void * untyped_replier, const rmw_request_id_t * request_header, const void * untyped_ros_response) { - using ReplierType = connext::Replier<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_>; + using ReplierType = connext::Replier< + @(__dds_request_msg_type), + @(__dds_response_msg_type) + >; if (!untyped_replier || !request_header || !untyped_ros_response) { return false; } - connext::WriteSample<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_> response; + connext::WriteSample<@(__dds_response_msg_type)> response; const rosidl_message_type_support_t * ts = - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.pkg_name), @(subfolder), @(spec.srv_name)_Response)(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join(service.response_message.structure.type.namespaces)), + @(service.response_message.structure.type.name))(); const message_type_support_callbacks_t * callbacks = static_cast(ts->data); bool converted = callbacks->convert_ros_to_dds( @@ -270,61 +312,64 @@ bool send_response__@(subfolder)__@(spec.srv_name)( return true; } -void * -get_request_datawriter__@(subfolder)__@(spec.srv_name)(void * untyped_requester) +static void * +get_request_datawriter__@(service.structure_type.name)(void * untyped_requester) { - return @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::get_request_datawriter__@(spec.srv_name)( + return @('::'.join(service.structure_type.namespaces))::typesupport_connext_cpp::get_request_datawriter__@(service.structure_type.name)( untyped_requester); } -void * -get_reply_datareader__@(subfolder)__@(spec.srv_name)(void * untyped_requester) +static void * +get_reply_datareader__@(service.structure_type.name)(void * untyped_requester) { - return @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::get_reply_datareader__@(spec.srv_name)( + return @('::'.join(service.structure_type.namespaces))::typesupport_connext_cpp::get_reply_datareader__@(service.structure_type.name)( untyped_requester); } -void * -get_request_datareader__@(subfolder)__@(spec.srv_name)(void * untyped_replier) +static void * +get_request_datareader__@(service.structure_type.name)(void * untyped_replier) { - return @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::get_request_datareader__@(spec.srv_name)( + return @('::'.join(service.structure_type.namespaces))::typesupport_connext_cpp::get_request_datareader__@(service.structure_type.name)( untyped_replier); } -void * -get_reply_datawriter__@(subfolder)__@(spec.srv_name)(void * untyped_replier) +static void * +get_reply_datawriter__@(service.structure_type.name)(void * untyped_replier) { - return @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::get_reply_datawriter__@(spec.srv_name)( + return @('::'.join(service.structure_type.namespaces))::typesupport_connext_cpp::get_reply_datawriter__@(service.structure_type.name)( untyped_replier); } -static service_type_support_callbacks_t __callbacks = { - "@(spec.pkg_name)", - "@(spec.srv_name)", - &create_requester__@(subfolder)__@(spec.srv_name), - &destroy_requester__@(subfolder)__@(spec.srv_name), - &create_replier__@(subfolder)__@(spec.srv_name), - &destroy_replier__@(subfolder)__@(spec.srv_name), - &send_request__@(subfolder)__@(spec.srv_name), - &take_request__@(subfolder)__@(spec.srv_name), - &send_response__@(subfolder)__@(spec.srv_name), - &take_response__@(subfolder)__@(spec.srv_name), - &get_request_datawriter__@(subfolder)__@(spec.srv_name), - &get_reply_datareader__@(subfolder)__@(spec.srv_name), - &get_request_datareader__@(subfolder)__@(spec.srv_name), - &get_reply_datawriter__@(subfolder)__@(spec.srv_name), +static service_type_support_callbacks_t _@(service.structure_type.name)__callbacks = { + "@(package_name)", + "@(service.structure_type.name)", + &create_requester__@(service.structure_type.name), + &destroy_requester__@(service.structure_type.name), + &create_replier__@(service.structure_type.name), + &destroy_replier__@(service.structure_type.name), + &send_request__@(service.structure_type.name), + &take_request__@(service.structure_type.name), + &send_response__@(service.structure_type.name), + &take_response__@(service.structure_type.name), + &get_request_datawriter__@(service.structure_type.name), + &get_reply_datareader__@(service.structure_type.name), + &get_request_datareader__@(service.structure_type.name), + &get_reply_datawriter__@(service.structure_type.name) }; -static rosidl_service_type_support_t __type_support = { +static rosidl_service_type_support_t _@(service.structure_type.name)__type_support = { rosidl_typesupport_connext_c__identifier, - &__callbacks, + &_@(service.structure_type.name)__callbacks, get_service_typesupport_handle_function, }; - const rosidl_service_type_support_t * -ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.pkg_name), @(subfolder), @(spec.srv_name))() { - return &__type_support; +ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME( + rosidl_typesupport_connext_c, + @(', '.join([package_name] + list(interface_path.parents[0].parts))), + @(service.structure_type.name))() +{ + return &_@(service.structure_type.name)__type_support; } #if defined(__cplusplus) diff --git a/rosidl_typesupport_connext_c/rosidl_typesupport_connext_c-extras.cmake.in b/rosidl_typesupport_connext_c/rosidl_typesupport_connext_c-extras.cmake.in index e6c2069..510e1d4 100644 --- a/rosidl_typesupport_connext_c/rosidl_typesupport_connext_c-extras.cmake.in +++ b/rosidl_typesupport_connext_c/rosidl_typesupport_connext_c-extras.cmake.in @@ -9,7 +9,7 @@ if(NOT Connext_FOUND) else() find_package(ament_cmake_core QUIET REQUIRED) ament_register_extension( - "rosidl_generate_interfaces" + "rosidl_generate_idl_interfaces" "rosidl_typesupport_connext_c" "rosidl_typesupport_connext_c_generate_interfaces.cmake") diff --git a/rosidl_typesupport_connext_c/rosidl_typesupport_connext_c/__init__.py b/rosidl_typesupport_connext_c/rosidl_typesupport_connext_c/__init__.py index a7b924c..b71f9a9 100644 --- a/rosidl_typesupport_connext_c/rosidl_typesupport_connext_c/__init__.py +++ b/rosidl_typesupport_connext_c/rosidl_typesupport_connext_c/__init__.py @@ -12,92 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os +from rosidl_cmake import generate_files -from rosidl_cmake import convert_camel_case_to_lower_case_underscore -from rosidl_cmake import expand_template -from rosidl_cmake import extract_message_types -from rosidl_cmake import get_newest_modification_time -from rosidl_parser import parse_message_file -from rosidl_parser import parse_service_file -from rosidl_parser import validate_field_types - -def generate_typesupport_connext_c(args): - template_dir = args['template_dir'] - mapping_msgs = { - os.path.join(template_dir, 'msg__rosidl_typesupport_connext_c.h.em'): - '%s__rosidl_typesupport_connext_c.h', - os.path.join(template_dir, 'msg__type_support_c.cpp.em'): - '%s__type_support_c.cpp', - } - - mapping_srvs = { - os.path.join(template_dir, 'srv__rosidl_typesupport_connext_c.h.em'): +def generate_typesupport_connext_c(arguments_file): + mapping = { + 'idl__rosidl_typesupport_connext_c.h.em': '%s__rosidl_typesupport_connext_c.h', - os.path.join(template_dir, 'srv__type_support_c.cpp.em'): - '%s__type_support_c.cpp', - } - - for template_file in mapping_msgs.keys(): - assert os.path.exists(template_file), 'Could not find template: ' + template_file - - for template_file in mapping_srvs.keys(): - assert os.path.exists(template_file), 'Could not find template: ' + template_file - - pkg_name = args['package_name'] - known_msg_types = extract_message_types( - pkg_name, args['ros_interface_files'], args.get('ros_interface_dependencies', [])) - - functions = { - 'get_header_filename_from_msg_name': convert_camel_case_to_lower_case_underscore, + 'idl__dds_connext__type_support_c.cpp.em': + 'dds_connext/%s__type_support_c.cpp' } - # generate_dds_connext_cpp() and therefore the make target depend on the additional files - # therefore they must be listed here even if the generated type support files are independent - latest_target_timestamp = get_newest_modification_time( - args['target_dependencies'] + args.get('additional_files', [])) - - for idl_file in args['ros_interface_files']: - extension = os.path.splitext(idl_file)[1] - subfolder = os.path.basename(os.path.dirname(idl_file)) - if extension == '.msg': - spec = parse_message_file(pkg_name, idl_file) - validate_field_types(spec, known_msg_types) - for template_file, generated_filename in mapping_msgs.items(): - generated_file = os.path.join(args['output_dir'], subfolder) - if generated_filename.endswith('.cpp'): - generated_file = os.path.join(generated_file, 'dds_connext_c') - generated_file = os.path.join( - generated_file, generated_filename % - convert_camel_case_to_lower_case_underscore(spec.base_type.type)) - - data = { - 'spec': spec, - 'pkg': spec.base_type.pkg_name, - 'msg': spec.msg_name, - 'type': spec.base_type.type, - 'subfolder': subfolder, - } - data.update(functions) - expand_template( - template_file, data, generated_file, - minimum_timestamp=latest_target_timestamp) - - elif extension == '.srv': - spec = parse_service_file(pkg_name, idl_file) - validate_field_types(spec, known_msg_types) - for template_file, generated_filename in mapping_srvs.items(): - generated_file = os.path.join(args['output_dir'], subfolder) - if generated_filename.endswith('.cpp'): - generated_file = os.path.join(generated_file, 'dds_connext_c') - generated_file = os.path.join( - generated_file, generated_filename % - convert_camel_case_to_lower_case_underscore(spec.srv_name)) - - data = {'spec': spec, 'subfolder': subfolder} - data.update(functions) - expand_template( - template_file, data, generated_file, - minimum_timestamp=latest_target_timestamp) - + generate_files(arguments_file, mapping) return 0 diff --git a/rosidl_typesupport_connext_cpp/bin/rosidl_typesupport_connext_cpp b/rosidl_typesupport_connext_cpp/bin/rosidl_typesupport_connext_cpp index 7652ca8..359f89d 100755 --- a/rosidl_typesupport_connext_cpp/bin/rosidl_typesupport_connext_cpp +++ b/rosidl_typesupport_connext_cpp/bin/rosidl_typesupport_connext_cpp @@ -3,12 +3,10 @@ import argparse import sys -from rosidl_cmake import extract_message_types from rosidl_cmake import read_generator_arguments from rosidl_parser import UnknownMessageType from rosidl_typesupport_connext_cpp import generate_cpp from rosidl_typesupport_connext_cpp import generate_dds_connext_cpp -from rosidl_typesupport_connext_cpp import parse_ros_interface_files def main(argv=sys.argv[1:]): @@ -31,15 +29,8 @@ def main(argv=sys.argv[1:]): generator_args = read_generator_arguments(args.generator_arguments_file) - message_specs, service_specs = parse_ros_interface_files( - generator_args['package_name'], generator_args['ros_interface_files']) - - known_msg_types = extract_message_types( - generator_args['package_name'], generator_args['ros_interface_files'], - generator_args.get('ros_interface_dependencies', [])) - try: - rc = generate_cpp(generator_args, message_specs, service_specs, known_msg_types) + rc = generate_cpp(args.generator_arguments_file) except UnknownMessageType as e: print(str(e), file=sys.stderr) return 1 @@ -51,11 +42,8 @@ def main(argv=sys.argv[1:]): args.dds_interface_base_path, generator_args.get('ros_interface_dependencies', []), generator_args['output_dir'], - args.idl_pp, - message_specs, - service_specs, + args.idl_pp ) - if __name__ == '__main__': sys.exit(main()) diff --git a/rosidl_typesupport_connext_cpp/cmake/rosidl_typesupport_connext_cpp_generate_interfaces.cmake b/rosidl_typesupport_connext_cpp/cmake/rosidl_typesupport_connext_cpp_generate_interfaces.cmake index 799b3d3..0b3654a 100644 --- a/rosidl_typesupport_connext_cpp/cmake/rosidl_typesupport_connext_cpp_generate_interfaces.cmake +++ b/rosidl_typesupport_connext_cpp/cmake/rosidl_typesupport_connext_cpp_generate_interfaces.cmake @@ -1,4 +1,4 @@ -# Copyright 2014-2015 Open Source Robotics Foundation, Inc. +# Copyright 2014-2018 Open Source Robotics Foundation, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,67 +12,33 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(_ros_idl_files "") -foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) - get_filename_component(_extension "${_idl_file}" EXT) - # Skip .srv files - if(_extension STREQUAL ".msg") - list(APPEND _ros_idl_files "${_idl_file}") - endif() -endforeach() - rosidl_generate_dds_interfaces( ${rosidl_generate_interfaces_TARGET}__dds_connext_idl - IDL_FILES ${_ros_idl_files} + IDL_TUPLES ${rosidl_generate_interfaces_IDL_TUPLES} DEPENDENCY_PACKAGE_NAMES ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES} OUTPUT_SUBFOLDERS "dds_connext" ) -set(_dds_idl_files "") +set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_cpp/${PROJECT_NAME}") set(_dds_idl_base_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_dds_idl") -foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) - get_filename_component(_extension "${_idl_file}" EXT) - if(_extension STREQUAL ".msg") - get_filename_component(_parent_folder "${_idl_file}" DIRECTORY) - get_filename_component(_parent_folder "${_parent_folder}" NAME) - get_filename_component(_name "${_idl_file}" NAME_WE) - list(APPEND _dds_idl_files - "${_dds_idl_base_path}/${PROJECT_NAME}/${_parent_folder}/dds_connext/${_name}_.idl") - endif() -endforeach() -set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_cpp/${PROJECT_NAME}") +set(_dds_idl_files "") set(_generated_files "") set(_generated_external_files "") -foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) - get_filename_component(_extension "${_idl_file}" EXT) - get_filename_component(_parent_folder "${_idl_file}" DIRECTORY) +foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES}) + get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY) get_filename_component(_parent_folder "${_parent_folder}" NAME) - get_filename_component(_msg_name "${_idl_file}" NAME_WE) - string_camel_case_to_lower_case_underscore("${_msg_name}" _header_name) - if(_extension STREQUAL ".msg") - set(_allowed_parent_folders "msg" "srv" "action") - if(NOT _parent_folder IN_LIST _allowed_parent_folders) - message(FATAL_ERROR "Interface file with unknown parent folder: ${_idl_file}") - endif() - list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_msg_name}_.h") - list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_msg_name}_.cxx") - list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Plugin.h") - list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Plugin.cxx") - list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Support.h") - list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Support.cxx") - list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_cpp.hpp") - list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext/${_header_name}__type_support.cpp") - elseif(_extension STREQUAL ".srv") - set(_allowed_parent_folders "srv" "action") - if(NOT _parent_folder IN_LIST _allowed_parent_folders) - message(FATAL_ERROR "Interface file with unknown parent folder: ${_idl_file}") - endif() - list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_cpp.hpp") - list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext/${_header_name}__type_support.cpp") - else() - message(FATAL_ERROR "Interface file with unknown extension: ${_idl_file}") - endif() + get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE) + string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name) + list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_idl_name}_.h") + list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_idl_name}_.cxx") + list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Plugin.h") + list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Plugin.cxx") + list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Support.h") + list(APPEND _generated_external_files "${_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Support.cxx") + list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_cpp.hpp") + list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext/${_header_name}__type_support.cpp") + list(APPEND _dds_idl_files "${_dds_idl_base_path}/${PROJECT_NAME}/${_parent_folder}/dds_connext/${_idl_name}_.idl") endforeach() # If not on Windows, disable some warnings with Connext's generated code @@ -103,36 +69,30 @@ endif() set(_dependency_files "") set(_dependencies "") foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) - foreach(_idl_file ${${_pkg_name}_INTERFACE_FILES}) - get_filename_component(_extension "${_idl_file}" EXT) - if(_extension STREQUAL ".msg") - get_filename_component(_parent_folder "${_idl_file}" DIRECTORY) - get_filename_component(_parent_folder "${_parent_folder}" NAME) - get_filename_component(_name "${_idl_file}" NAME_WE) - set(_abs_idl_file "${${_pkg_name}_DIR}/../${_parent_folder}/dds_connext/${_name}_.idl") - normalize_path(_abs_idl_file "${_abs_idl_file}") - list(APPEND _dependency_files "${_abs_idl_file}") - set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}") - normalize_path(_abs_idl_file "${_abs_idl_file}") - list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}") - endif() + foreach(_idl_file ${${_pkg_name}_IDL_FILES}) + # ${{_pkg_name}_DIR} is absolute path ending in 'share//cmake', so go back one + # directory for IDL files + set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}") + normalize_path(_abs_idl_file "${_abs_idl_file}") + list(APPEND _dependency_files "${_abs_idl_file}") + list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}") endforeach() endforeach() set(target_dependencies "${rosidl_typesupport_connext_cpp_BIN}" ${rosidl_typesupport_connext_cpp_GENERATOR_FILES} + "${rosidl_typesupport_connext_cpp_TEMPLATE_DIR}/idl__rosidl_typesupport_connext_cpp.hpp.em" + "${rosidl_typesupport_connext_cpp_TEMPLATE_DIR}/idl__dds_connext__type_support.cpp.em" "${rosidl_typesupport_connext_cpp_TEMPLATE_DIR}/msg__rosidl_typesupport_connext_cpp.hpp.em" "${rosidl_typesupport_connext_cpp_TEMPLATE_DIR}/msg__type_support.cpp.em" "${rosidl_typesupport_connext_cpp_TEMPLATE_DIR}/srv__rosidl_typesupport_connext_cpp.hpp.em" "${rosidl_typesupport_connext_cpp_TEMPLATE_DIR}/srv__type_support.cpp.em" + ${rosidl_generate_interfaces_ABS_IDL_FILES} ${_dependency_files}) foreach(dep ${target_dependencies}) if(NOT EXISTS "${dep}") - get_property(is_generated SOURCE "${dep}" PROPERTY GENERATED) - if(NOT ${_is_generated}) - message(FATAL_ERROR "Target dependency '${dep}' does not exist") - endif() + message(FATAL_ERROR "Target dependency '${dep}' does not exist") endif() endforeach() @@ -140,7 +100,7 @@ set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_con rosidl_write_generator_arguments( "${generator_arguments_file}" PACKAGE_NAME "${PROJECT_NAME}" - ROS_INTERFACE_FILES "${rosidl_generate_interfaces_IDL_FILES}" + IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}" ROS_INTERFACE_DEPENDENCIES "${_dependencies}" OUTPUT_DIR "${_output_path}" TEMPLATE_DIR "${rosidl_typesupport_connext_cpp_TEMPLATE_DIR}" @@ -225,7 +185,7 @@ ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix} foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) set(_msg_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/msg/dds_connext") set(_srv_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/srv/dds_connext") - set(_action_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/action/dds_connext_c") + set(_action_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/action/dds_connext") normalize_path(_msg_include_dir "${_msg_include_dir}") normalize_path(_srv_include_dir "${_srv_include_dir}") normalize_path(_action_include_dir "${_action_include_dir}") @@ -250,8 +210,8 @@ add_dependencies( ${rosidl_generate_interfaces_TARGET}__cpp ) add_dependencies( - ${rosidl_generate_interfaces_TARGET}__dds_connext_idl ${rosidl_generate_interfaces_TARGET}${_target_suffix} + ${rosidl_generate_interfaces_TARGET}__dds_connext_idl ) if(NOT rosidl_generate_interfaces_SKIP_INSTALL) diff --git a/rosidl_typesupport_connext_cpp/resource/idl__dds_connext__type_support.cpp.em b/rosidl_typesupport_connext_cpp/resource/idl__dds_connext__type_support.cpp.em new file mode 100644 index 0000000..df4cee7 --- /dev/null +++ b/rosidl_typesupport_connext_cpp/resource/idl__dds_connext__type_support.cpp.em @@ -0,0 +1,79 @@ +// generated from rosidl_typesupport_connext_cpp/resource/idl__dds_connext__type_support.cpp.em +// with input from @(package_name):@(interface_path) +// generated code does not contain a copyright notice + +#include +#include + +@{ +####################################################################### +# EmPy template for generating __type_support.cpp files +# +# Context: +# - package_name (string) +# - content (rosidl_parser.definition.IdlContent result of parsing IDL file) +# - interface_path (Path relative to the directory named after the package) +####################################################################### +include_directives = set() +####################################################################### +# Handle message +####################################################################### +from rosidl_parser.definition import Message +for message in content.get_elements_of_type(Message): + TEMPLATE( + 'msg__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + message=message, include_directives=include_directives + ) +####################################################################### +# Handle service +####################################################################### +from rosidl_parser.definition import Service +for service in content.get_elements_of_type(Service): + TEMPLATE( + 'srv__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + service=service, include_directives=include_directives + ) +####################################################################### +# Handle action +####################################################################### +from rosidl_parser.definition import Action +for action in content.get_elements_of_type(Action): + TEMPLATE( + 'msg__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + message=action.goal, + include_directives=include_directives + ) + TEMPLATE( + 'srv__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + service=action.send_goal_service, + include_directives=include_directives + ) + TEMPLATE( + 'msg__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + message=action.result, + include_directives=include_directives + ) + TEMPLATE( + 'srv__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + service=action.get_result_service, + include_directives=include_directives + ) + TEMPLATE( + 'msg__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + message=action.feedback, + include_directives=include_directives + ) + TEMPLATE( + 'msg__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + message=action.feedback_message, + include_directives=include_directives + ) +}@ diff --git a/rosidl_typesupport_connext_cpp/resource/idl__rosidl_typesupport_connext_cpp.hpp.em b/rosidl_typesupport_connext_cpp/resource/idl__rosidl_typesupport_connext_cpp.hpp.em new file mode 100644 index 0000000..fdcb33a --- /dev/null +++ b/rosidl_typesupport_connext_cpp/resource/idl__rosidl_typesupport_connext_cpp.hpp.em @@ -0,0 +1,84 @@ +// generated from rosidl_typesupport_connext_cpp/resource/idl__rosidl_typesupport_connext_cpp.hpp.em +// with input from @(package_name):@(interface_path) +// generated code does not contain a copyright notice + +@{ +####################################################################### +# EmPy template for generating __rosidl_typesupport_connext_cpp.hpp files +# +# Context: +# - package_name (string) +# - content (rosidl_parser.definition.IdlContent result of parsing IDL file) +# - interface_path (Path relative to the directory named after the package) +####################################################################### +from rosidl_cmake import convert_camel_case_to_lower_case_underscore +include_parts = [package_name] + list(interface_path.parents[0].parts) + \ + [convert_camel_case_to_lower_case_underscore(interface_path.stem)] +header_guard_variable = '__'.join([x.upper() for x in include_parts]) + \ + '__ROSIDL_TYPESUPPORT_CONNEXT_CPP_HPP_' +include_directives = set() +}@ + +#ifndef @(header_guard_variable) +#define @(header_guard_variable) + +@{ +####################################################################### +# Handle message +####################################################################### +from rosidl_parser.definition import Message +for message in content.get_elements_of_type(Message): + TEMPLATE( + 'msg__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, message=message, + include_directives=include_directives + ) +####################################################################### +# Handle service +####################################################################### +from rosidl_parser.definition import Service +for service in content.get_elements_of_type(Service): + TEMPLATE( + 'srv__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, service=service, + include_directives=include_directives + ) +####################################################################### +# Handle action +####################################################################### +from rosidl_parser.definition import Action +for action in content.get_elements_of_type(Action): + TEMPLATE( + 'msg__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, message=action.goal, + include_directives=include_directives + ) + TEMPLATE( + 'msg__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, message=action.result, + include_directives=include_directives + ) + TEMPLATE( + 'msg__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, message=action.feedback, + include_directives=include_directives + ) + TEMPLATE( + 'srv__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, service=action.send_goal_service, + include_directives=include_directives + ) + TEMPLATE( + 'srv__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, + service=action.get_result_service, + include_directives=include_directives + ) + TEMPLATE( + 'msg__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, message=action.feedback_message, + include_directives=include_directives + ) +}@ + +#endif // @(header_guard_variable) diff --git a/rosidl_typesupport_connext_cpp/resource/msg__rosidl_typesupport_connext_cpp.hpp.em b/rosidl_typesupport_connext_cpp/resource/msg__rosidl_typesupport_connext_cpp.hpp.em index c504763..d726f86 100644 --- a/rosidl_typesupport_connext_cpp/resource/msg__rosidl_typesupport_connext_cpp.hpp.em +++ b/rosidl_typesupport_connext_cpp/resource/msg__rosidl_typesupport_connext_cpp.hpp.em @@ -1,35 +1,31 @@ -// generated from -// rosidl_typesupport_connext_cpp/resource/msg__rosidl_typesupport_connext_cpp.hpp.em -// generated code does not contain a copyright notice - -@####################################################################### -@# EmPy template for generating -@# __rosidl_typesupport_connext_cpp.hpp files -@# -@# Context: -@# - spec (rosidl_parser.MessageSpecification) -@# Parsed specification of the .msg file -@# - subfolder (string) -@# The subfolder / subnamespace of the message -@# Either 'msg' or 'srv' -@# - get_header_filename_from_msg_name (function) -@####################################################################### -@ +@# Included from rosidl_typesupport_connext_cpp/resource/idl__rosidl_typesupport_connext_cpp.hpp.em @{ -header_guard_parts = [ - spec.base_type.pkg_name, subfolder, - get_header_filename_from_msg_name(spec.base_type.type) + '__rosidl_typesupport_connext_cpp_hpp'] -header_guard_variable = '__'.join([x.upper() for x in header_guard_parts]) + '_' +from rosidl_cmake import convert_camel_case_to_lower_case_underscore +include_parts = [package_name] + list(interface_path.parents[0].parts) +include_base = '/'.join(include_parts) +header_filename = convert_camel_case_to_lower_case_underscore(interface_path.stem) +header_files = [ + 'rosidl_generator_c/message_type_support_struct.h', + 'rosidl_typesupport_interface/macros.h', + package_name + '/msg/rosidl_typesupport_connext_cpp__visibility_control.h', + include_base + '/' + header_filename + '__struct.hpp' +] +dds_specific_header_files = [ + include_base + '/dds_connext/' + interface_path.stem + '_Support.h', + include_base + '/dds_connext/' + interface_path.stem + '_Plugin.h', + 'ndds/ndds_cpp.h' +] }@ -#ifndef @(header_guard_variable) -#define @(header_guard_variable) +@[for header_file in header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ -#include "rosidl_generator_c/message_type_support_struct.h" -#include "rosidl_typesupport_interface/macros.h" - -#include "@(spec.base_type.pkg_name)/msg/rosidl_typesupport_connext_cpp__visibility_control.h" - -#include "@(spec.base_type.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.base_type.type))__struct.hpp" #ifndef _WIN32 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-parameter" @@ -38,10 +34,17 @@ header_guard_variable = '__'.join([x.upper() for x in header_guard_parts]) + '_' # pragma clang diagnostic ignored "-Wreturn-type-c-linkage" # endif #endif -#include "@(spec.base_type.pkg_name)/@(subfolder)/dds_connext/@(spec.base_type.type)_Support.h" -#include "@(spec.base_type.pkg_name)/@(subfolder)/dds_connext/@(spec.base_type.type)_Plugin.h" -#include "ndds/ndds_cpp.h" +@[for header_file in dds_specific_header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ + #ifndef _WIN32 # pragma GCC diagnostic pop #endif @@ -54,57 +57,65 @@ class DDSDomainParticipant; class DDSDataWriter; class DDSDataReader; -namespace @(spec.base_type.pkg_name) -{ +@[for ns in message.structure.type.namespaces]@ -namespace @(subfolder) +namespace @(ns) { - +@[end for]@ +@{ +__ros_msg_pkg_prefix = '::'.join(message.structure.type.namespaces) +__ros_msg_type = __ros_msg_pkg_prefix + '::' + message.structure.type.name +__dds_msg_type_prefix = __ros_msg_pkg_prefix + '::dds_::' + message.structure.type.name +__dds_msg_type = __dds_msg_type_prefix + '_' +}@ namespace typesupport_connext_cpp { DDS_TypeCode * -get_type_code__@(spec.base_type.type)(); +get_type_code__@(message.structure.type.name)(); bool -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.base_type.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) convert_ros_message_to_dds( - const @(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type) & ros_message, - @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_ & dds_message); + const @(__ros_msg_type) & ros_message, + @(__dds_msg_type) & dds_message); bool -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.base_type.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) convert_dds_message_to_ros( - const @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_ & dds_message, - @(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type) & ros_message); + const @(__dds_msg_type) & dds_message, + @(__ros_msg_type) & ros_message); bool -to_cdr_stream__@(spec.base_type.type)( +to_cdr_stream__@(message.structure.type.name)( const void * untyped_ros_message, ConnextStaticCDRStream * cdr_stream); bool -to_message__@(spec.base_type.type)( +to_message__@(message.structure.type.name)( const ConnextStaticCDRStream * cdr_stream, void * untyped_ros_message); } // namespace typesupport_connext_cpp -} // namespace @(subfolder) +@[for ns in reversed(message.structure.type.namespaces)]@ +} // namespace @(ns) -} // namespace @(spec.base_type.pkg_name) +@[end for]@ #ifdef __cplusplus extern "C" { #endif -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.base_type.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) const rosidl_message_type_support_t * - ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_cpp, @(spec.base_type.pkg_name), @(subfolder), @(spec.base_type.type))(); + ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_cpp, + @(', '.join([package_name] + list(interface_path.parents[0].parts))), + @(message.structure.type.name))(); #ifdef __cplusplus } #endif -#endif // @(header_guard_variable) diff --git a/rosidl_typesupport_connext_cpp/resource/msg__type_support.cpp.em b/rosidl_typesupport_connext_cpp/resource/msg__type_support.cpp.em index 1775792..0d907de 100644 --- a/rosidl_typesupport_connext_cpp/resource/msg__type_support.cpp.em +++ b/rosidl_typesupport_connext_cpp/resource/msg__type_support.cpp.em @@ -1,138 +1,162 @@ -// generated from rosidl_typesupport_connext_cpp/resource/msg__type_support.cpp.em -// generated code does not contain a copyright notice - -@####################################################################### -@# EmPy template for generating __type_support.cpp files -@# -@# Context: -@# - spec (rosidl_parser.MessageSpecification) -@# Parsed specification of the .msg file -@# - subfolder (string) -@# The subfolder / subnamespace of the message -@# Could be 'msg', 'srv' or 'action' -@# - get_header_filename_from_msg_name (function) -@####################################################################### -@ -#include "@(spec.base_type.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.base_type.type))__rosidl_typesupport_connext_cpp.hpp" - -#include -#include - -#include "rcutils/types/uint8_array.h" - -#include "rosidl_typesupport_cpp/message_type_support.hpp" - -#include "rosidl_typesupport_connext_cpp/identifier.hpp" -#include "rosidl_typesupport_connext_cpp/message_type_support.h" -#include "rosidl_typesupport_connext_cpp/message_type_support_decl.hpp" +@# Included from rosidl_typesupport_connext_cpp/resource/idl__dds_connext__type_support.cpp.em +@{ +from rosidl_cmake import convert_camel_case_to_lower_case_underscore +from rosidl_parser.definition import Array +from rosidl_parser.definition import BasicType +from rosidl_parser.definition import BaseString +from rosidl_parser.definition import BoundedSequence +from rosidl_parser.definition import NamespacedType +from rosidl_parser.definition import NestedType +include_parts = [package_name] + list(interface_path.parents[0].parts) +include_base = '/'.join(include_parts) + +include_prefix = convert_camel_case_to_lower_case_underscore(interface_path.stem) + +header_files = [ + include_base + '/' + include_prefix + '__rosidl_typesupport_connext_cpp.hpp', + 'rcutils/types/uint8_array.h', + 'rosidl_typesupport_cpp/message_type_support.hpp', + 'rosidl_typesupport_connext_cpp/identifier.hpp', + 'rosidl_typesupport_connext_cpp/message_type_support.h', + 'rosidl_typesupport_connext_cpp/message_type_support_decl.hpp' +] +}@ +@[for header_file in header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ // forward declaration of message dependencies and their conversion functions -@[for field in spec.fields]@ -@[ if not field.type.is_primitive_type()]@ -namespace @(field.type.pkg_name) -{ -namespace msg +@[for member in message.structure.members]@ +@{ +type_ = member.type +if isinstance(type_, NestedType): + type_ = type_.basetype +}@ +@[ if isinstance(type_, NamespacedType)]@ +@[ for ns in type_.namespaces]@ +namespace @(ns) { +@[ end for]@ namespace dds_ { -class @(field.type.type)_; +class @(type_.name)_; } // namespace dds_ + namespace typesupport_connext_cpp { +@{ +member_ros_msg_pkg_prefix = '::'.join(type_.namespaces) +member_ros_msg_type = member_ros_msg_pkg_prefix + '::' + type_.name +member_dds_msg_type = member_ros_msg_pkg_prefix + '::dds_::' + type_.name + '_' +}@ + bool convert_ros_message_to_dds( - const @(field.type.pkg_name)::msg::@(field.type.type) &, - @(field.type.pkg_name)::msg::dds_::@(field.type.type)_ &); + const @(member_ros_msg_type) &, + @(member_dds_msg_type) &); bool convert_dds_message_to_ros( - const @(field.type.pkg_name)::msg::dds_::@(field.type.type)_ &, - @(field.type.pkg_name)::msg::@(field.type.type) &); + const @(member_dds_msg_type) &, + @(member_ros_msg_type) &); } // namespace typesupport_connext_cpp -} // namespace msg -} // namespace @(field.type.pkg_name) - -@[ end if]@ +@[ for ns in reversed(type_.namespaces)]@ +} // namespace @(ns) +@[ end for]@ +@[ end if]@ @[end for]@ -namespace @(spec.base_type.pkg_name) -{ +@[for ns in message.structure.type.namespaces]@ -namespace @(subfolder) +namespace @(ns) { +@[end for]@ namespace typesupport_connext_cpp { +@{ +__ros_msg_pkg_prefix = '::'.join(message.structure.type.namespaces) +__ros_msg_type = __ros_msg_pkg_prefix + '::' + message.structure.type.name +__dds_msg_type_prefix = __ros_msg_pkg_prefix + '::dds_::' + message.structure.type.name +__dds_msg_type = __dds_msg_type_prefix + '_' +}@ + DDS_TypeCode * -get_type_code__@(spec.base_type.type)() +get_type_code__@(message.structure.type.name)() { - return @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::get_typecode(); + return @(__dds_msg_type_prefix)_TypeSupport::get_typecode(); } bool convert_ros_message_to_dds( - const @(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type) & ros_message, - @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_ & dds_message) + const @(__ros_msg_type) & ros_message, + @(__dds_msg_type) & dds_message) { -@[if not spec.fields]@ +@[if not message.structure.members]@ (void)ros_message; (void)dds_message; @[end if]@ -@[for field in spec.fields]@ - // field.name @(field.name) -@[ if field.type.is_array]@ +@[for member in message.structure.members]@ + // member.name @(member.name) +@[ if isinstance(member.type, NestedType)]@ { -@[ if field.type.array_size and not field.type.is_upper_bound]@ - size_t size = @(field.type.array_size); +@[ if isinstance(member.type, Array)]@ + size_t size = @(member.type.size); @[ else]@ - size_t size = ros_message.@(field.name).size(); + size_t size = ros_message.@(member.name).size(); if (size > (std::numeric_limits::max)()) { throw std::runtime_error("array size exceeds maximum DDS sequence size"); } -@[ if field.type.is_upper_bound]@ - if (size > @(field.type.array_size)) { +@[ if isinstance(member.type, BoundedSequence)]@ + if (size > @(member.type.upper_bound)) { throw std::runtime_error("array size exceeds upper bound"); } @[ end if]@ DDS_Long length = static_cast(size); - if (length > dds_message.@(field.name)_.maximum()) { - if (!dds_message.@(field.name)_.maximum(length)) { + if (length > dds_message.@(member.name)_.maximum()) { + if (!dds_message.@(member.name)_.maximum(length)) { throw std::runtime_error("failed to set maximum of sequence"); } } - if (!dds_message.@(field.name)_.length(length)) { + if (!dds_message.@(member.name)_.length(length)) { throw std::runtime_error("failed to set length of sequence"); } @[ end if]@ for (size_t i = 0; i < size; i++) { -@[ if field.type.type == 'string']@ - DDS_String_free(dds_message.@(field.name)_[static_cast(i)]); - dds_message.@(field.name)_[static_cast(i)] = - DDS_String_dup(ros_message.@(field.name)[i].c_str()); -@[ elif field.type.is_primitive_type()]@ - dds_message.@(field.name)_[static_cast(i)] = - ros_message.@(field.name)[i]; +@[ if isinstance(member.type.basetype, BaseString)]@ + DDS_String_free(dds_message.@(member.name)_[static_cast(i)]); + dds_message.@(member.name)_[static_cast(i)] = + DDS_String_dup(ros_message.@(member.name)[i].c_str()); +@[ elif isinstance(member.type.basetype, BasicType)]@ + dds_message.@(member.name)_[static_cast(i)] = + ros_message.@(member.name)[i]; @[ else]@ if ( - !@(field.type.pkg_name)::msg::typesupport_connext_cpp::convert_ros_message_to_dds( - ros_message.@(field.name)[i], - dds_message.@(field.name)_[static_cast(i)])) + !@('::'.join(member.type.basetype.namespaces))::typesupport_connext_cpp::convert_ros_message_to_dds( + ros_message.@(member.name)[i], + dds_message.@(member.name)_[static_cast(i)])) { return false; } @[ end if]@ } } -@[ elif field.type.type == 'string']@ - DDS_String_free(dds_message.@(field.name)_); - dds_message.@(field.name)_ = - DDS_String_dup(ros_message.@(field.name).c_str()); -@[ elif field.type.is_primitive_type()]@ - dds_message.@(field.name)_ = - ros_message.@(field.name); +@[ elif isinstance(member.type, BaseString)]@ + DDS_String_free(dds_message.@(member.name)_); + dds_message.@(member.name)_ = + DDS_String_dup(ros_message.@(member.name).c_str()); +@[ elif isinstance(member.type, BasicType)]@ + dds_message.@(member.name)_ = + ros_message.@(member.name); @[ else]@ if ( - !@(field.type.pkg_name)::msg::typesupport_connext_cpp::convert_ros_message_to_dds( - ros_message.@(field.name), - dds_message.@(field.name)_)) + !@('::'.join(member.type.namespaces))::typesupport_connext_cpp::convert_ros_message_to_dds( + ros_message.@(member.name), + dds_message.@(member.name)_)) { return false; } @@ -144,46 +168,51 @@ convert_ros_message_to_dds( bool convert_dds_message_to_ros( - const @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_ & dds_message, - @(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type) & ros_message) + const @(__dds_msg_type) & dds_message, + @(__ros_msg_type) & ros_message) { -@[if not spec.fields]@ +@[if not message.structure.members]@ (void)ros_message; (void)dds_message; @[end if]@ -@[for field in spec.fields]@ - // field.name @(field.name) -@[ if field.type.is_array]@ +@[for member in message.structure.members]@ + // member.name @(member.name) +@[ if isinstance(member.type, NestedType)]@ { -@[ if field.type.array_size and not field.type.is_upper_bound]@ - size_t size = @(field.type.array_size); +@[ if isinstance(member.type, Array)]@ + size_t size = @(member.type.size); @[ else]@ - size_t size = dds_message.@(field.name)_.length(); - ros_message.@(field.name).resize(size); + size_t size = dds_message.@(member.name)_.length(); + ros_message.@(member.name).resize(size); @[ end if]@ for (size_t i = 0; i < size; i++) { -@[ if field.type.is_primitive_type()]@ - ros_message.@(field.name)[i] = - dds_message.@(field.name)_[static_cast(i)]@(' == DDS_BOOLEAN_TRUE' if field.type.type == 'bool' else ''); +@[ if isinstance(member.type.basetype, BasicType)]@ + ros_message.@(member.name)[i] = + dds_message.@(member.name)_[static_cast(i)]@(' == DDS_BOOLEAN_TRUE' if member.type.basetype.type == 'boolean' else ''); +@[ elif isinstance(member.type.basetype, BaseString)]@ + ros_message.@(member.name)[i] = + dds_message.@(member.name)_[static_cast(i)]; @[ else]@ if ( - !@(field.type.pkg_name)::msg::typesupport_connext_cpp::convert_dds_message_to_ros( - dds_message.@(field.name)_[static_cast(i)], - ros_message.@(field.name)[i])) + !@('::'.join(member.type.basetype.namespaces))::typesupport_connext_cpp::convert_dds_message_to_ros( + dds_message.@(member.name)_[static_cast(i)], + ros_message.@(member.name)[i])) { return false; } @[ end if]@ } } -@[ elif field.type.is_primitive_type()]@ - ros_message.@(field.name) = - dds_message.@(field.name)_@(' == DDS_BOOLEAN_TRUE' if field.type.type == 'bool' else ''); +@[ elif isinstance(member.type, BasicType)]@ + ros_message.@(member.name) = + dds_message.@(member.name)_@(' == DDS_BOOLEAN_TRUE' if member.type.type == 'boolean' else ''); +@[ elif isinstance(member.type, BaseString)]@ + ros_message.@(member.name) = dds_message.@(member.name)_; @[ else]@ if ( - !@(field.type.pkg_name)::msg::typesupport_connext_cpp::convert_dds_message_to_ros( - dds_message.@(field.name)_, - ros_message.@(field.name))) + !@('::'.join(member.type.namespaces))::typesupport_connext_cpp::convert_dds_message_to_ros( + dds_message.@(member.name)_, + ros_message.@(member.name))) { return false; } @@ -194,7 +223,7 @@ convert_dds_message_to_ros( } bool -to_cdr_stream__@(spec.base_type.type)( +to_cdr_stream__@(message.structure.type.name)( const void * untyped_ros_message, rcutils_uint8_array_t * cdr_stream) { @@ -206,11 +235,11 @@ to_cdr_stream__@(spec.base_type.type)( } // cast the untyped to the known ros message - const @(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type) & ros_message = - *(const @(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type) *)untyped_ros_message; + const @(__ros_msg_type) & ros_message = + *(const @(__ros_msg_type) *)untyped_ros_message; // create a respective connext dds type - @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_ * dds_message = @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::create_data(); + @(__dds_msg_type) * dds_message = @(__dds_msg_type_prefix)_TypeSupport::create_data(); if (!dds_message) { return false; } @@ -222,12 +251,12 @@ to_cdr_stream__@(spec.base_type.type)( // call the serialize function for the first time to get the expected length of the message unsigned int expected_length; - if (@(spec.base_type.type)_Plugin_serialize_to_cdr_buffer( + if (@(__dds_msg_type_prefix)_Plugin_serialize_to_cdr_buffer( NULL, &expected_length, dds_message) != RTI_TRUE) { - fprintf(stderr, "failed to call @(spec.base_type.type)_Plugin_serialize_to_cdr_buffer()\n"); + fprintf(stderr, "failed to call @(__dds_msg_type_prefix)_Plugin_serialize_to_cdr_buffer()\n"); return false; } cdr_stream->buffer_length = expected_length; @@ -241,21 +270,21 @@ to_cdr_stream__@(spec.base_type.type)( } // call the function again and fill the buffer this time unsigned int buffer_length_uint = static_cast(cdr_stream->buffer_length); - if (@(spec.base_type.type)_Plugin_serialize_to_cdr_buffer( + if (@(__dds_msg_type_prefix)_Plugin_serialize_to_cdr_buffer( reinterpret_cast(cdr_stream->buffer), &buffer_length_uint, dds_message) != RTI_TRUE) { return false; } - if (@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::delete_data(dds_message) != DDS_RETCODE_OK) { + if (@(__dds_msg_type_prefix)_TypeSupport::delete_data(dds_message) != DDS_RETCODE_OK) { return false; } return true; } bool -to_message__@(spec.base_type.type)( +to_message__@(message.structure.type.name)( const rcutils_uint8_array_t * cdr_stream, void * untyped_ros_message) { @@ -269,13 +298,13 @@ to_message__@(spec.base_type.type)( return false; } - @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_ * dds_message = - @(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::create_data(); + @(__dds_msg_type) * dds_message = + @(__dds_msg_type_prefix)_TypeSupport::create_data(); if (cdr_stream->buffer_length > (std::numeric_limits::max)()) { fprintf(stderr, "cdr_stream->buffer_length, unexpectedly larger than max unsigned int\n"); return false; } - if (@(spec.base_type.type)_Plugin_deserialize_from_cdr_buffer( + if (@(__dds_msg_type_prefix)_Plugin_deserialize_from_cdr_buffer( dds_message, reinterpret_cast(cdr_stream->buffer), static_cast(cdr_stream->buffer_length)) != RTI_TRUE) @@ -284,46 +313,47 @@ to_message__@(spec.base_type.type)( return false; } - @(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type) & ros_message = - *(@(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type) *)untyped_ros_message; + @(__ros_msg_type) & ros_message = + *(@(__ros_msg_type) *)untyped_ros_message; bool success = convert_dds_message_to_ros(*dds_message, ros_message); - if (@(spec.base_type.pkg_name)::@(subfolder)::dds_::@(spec.base_type.type)_TypeSupport::delete_data(dds_message) != DDS_RETCODE_OK) { + if (@(__dds_msg_type_prefix)_TypeSupport::delete_data(dds_message) != DDS_RETCODE_OK) { return false; } return success; } -static message_type_support_callbacks_t callbacks = { - "@(spec.base_type.pkg_name)", - "@(spec.base_type.type)", - &get_type_code__@(spec.base_type.type), +static message_type_support_callbacks_t _@(message.structure.type.name)__callbacks = { + "@(package_name)", + "@(message.structure.type.name)", + &get_type_code__@(message.structure.type.name), nullptr, nullptr, - &to_cdr_stream__@(spec.base_type.type), - &to_message__@(spec.base_type.type) + &to_cdr_stream__@(message.structure.type.name), + &to_message__@(message.structure.type.name) }; -static rosidl_message_type_support_t handle = { +static rosidl_message_type_support_t _@(message.structure.type.name)__handle = { rosidl_typesupport_connext_cpp::typesupport_identifier, - &callbacks, + &_@(message.structure.type.name)__callbacks, get_message_typesupport_handle_function, }; } // namespace typesupport_connext_cpp -} // namespace @(subfolder) +@[for ns in reversed(message.structure.type.namespaces)]@ +} // namespace @(ns) -} // namespace @(spec.base_type.pkg_name) +@[end for]@ namespace rosidl_typesupport_connext_cpp { template<> -ROSIDL_TYPESUPPORT_CONNEXT_CPP_EXPORT_@(spec.base_type.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_EXPORT_@(package_name) const rosidl_message_type_support_t * -get_message_type_support_handle<@(spec.base_type.pkg_name)::@(subfolder)::@(spec.base_type.type)>() +get_message_type_support_handle<@(__ros_msg_type)>() { - return &@(spec.base_type.pkg_name)::@(subfolder)::typesupport_connext_cpp::handle; + return &@(__ros_msg_pkg_prefix)::typesupport_connext_cpp::_@(message.structure.type.name)__handle; } } // namespace rosidl_typesupport_connext_cpp @@ -334,8 +364,12 @@ extern "C" #endif const rosidl_message_type_support_t * -ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_cpp, @(spec.base_type.pkg_name), @(subfolder), @(spec.base_type.type))() { - return &@(spec.base_type.pkg_name)::@(subfolder)::typesupport_connext_cpp::handle; +ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( + rosidl_typesupport_connext_cpp, + @(', '.join([package_name] + list(interface_path.parents[0].parts))), + @(message.structure.type.name))() +{ + return &@(__ros_msg_pkg_prefix)::typesupport_connext_cpp::_@(message.structure.type.name)__handle; } #ifdef __cplusplus diff --git a/rosidl_typesupport_connext_cpp/resource/srv__rosidl_typesupport_connext_cpp.hpp.em b/rosidl_typesupport_connext_cpp/resource/srv__rosidl_typesupport_connext_cpp.hpp.em index 6344d5f..f297206 100644 --- a/rosidl_typesupport_connext_cpp/resource/srv__rosidl_typesupport_connext_cpp.hpp.em +++ b/rosidl_typesupport_connext_cpp/resource/srv__rosidl_typesupport_connext_cpp.hpp.em @@ -1,47 +1,50 @@ -// generated from -// rosidl_typesupport_connext_cpp/resource/srv__rosidl_typesupport_connext_cpp.hpp.em -// generated code does not contain a copyright notice - -@####################################################################### -@# EmPy template for generating -@# __rosidl_typesupport_connext_cpp.hpp files -@# -@# Context: -@# - spec (rosidl_parser.MessageSpecification) -@# Parsed specification of the .srv file -@# - subfolder (string) -@# The subfolder / subnamespace of the message -@# Either 'srv' or 'action' -@# - get_header_filename_from_srv_name (function) -@####################################################################### -@ +@# Included from rosidl_typesupport_connext_cpp/resource/srv__rosidl_typesupport_connext_cpp.hpp.em @{ -header_guard_parts = [ - spec.pkg_name, subfolder, - get_header_filename_from_msg_name(spec.srv_name) + '__rosidl_typesupport_connext_cpp_hpp'] -header_guard_variable = '__'.join([x.upper() for x in header_guard_parts]) + '_' +TEMPLATE( + 'msg__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, + message=service.request_message, + include_directives=include_directives +) }@ -#ifndef @(header_guard_variable) -#define @(header_guard_variable) -#include - -#include "rosidl_typesupport_cpp/service_type_support.hpp" -#include "rosidl_typesupport_interface/macros.h" - -#include "@(spec.pkg_name)/msg/rosidl_typesupport_connext_cpp__visibility_control.h" - -namespace @(spec.pkg_name) -{ +@{ +TEMPLATE( + 'msg__rosidl_typesupport_connext_cpp.hpp.em', + package_name=package_name, interface_path=interface_path, + message=service.response_message, + include_directives=include_directives +) +}@ -namespace @(subfolder) +@{ +header_files = [ + 'rmw/types.h', + 'rosidl_typesupport_cpp/service_type_support.hpp', + 'rosidl_typesupport_interface/macros.h', + package_name + '/msg/rosidl_typesupport_connext_cpp__visibility_control.h' +] +}@ +@[for header_file in header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ + +@[for ns in service.structure_type.namespaces]@ +namespace @(ns) { - +@[end for]@ namespace typesupport_connext_cpp { -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) + +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) void * -create_requester__@(spec.srv_name)( +create_requester__@(service.structure_type.name)( void * untyped_participant, const char * request_topic_str, const char * response_topic_str, @@ -51,21 +54,21 @@ create_requester__@(spec.srv_name)( void ** untyped_writer, void * (*allocator)(size_t)); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) const char * -destroy_requester__@(spec.srv_name)( +destroy_requester__@(service.structure_type.name)( void * untyped_requester, void (* deallocator)(void *)); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) int64_t -send_request__@(spec.srv_name)( +send_request__@(service.structure_type.name)( void * untyped_requester, const void * untyped_ros_request); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) void * -create_replier__@(spec.srv_name)( +create_replier__@(service.structure_type.name)( void * untyped_participant, const char * request_topic_str, const char * response_topic_str, @@ -75,66 +78,66 @@ create_replier__@(spec.srv_name)( void ** untyped_writer, void * (*allocator)(size_t)); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) const char * -destroy_replier__@(spec.srv_name)( +destroy_replier__@(service.structure_type.name)( void * untyped_replier, void (* deallocator)(void *)); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) bool -take_request__@(spec.srv_name)( +take_request__@(service.structure_type.name)( void * untyped_replier, rmw_request_id_t * request_header, void * untyped_ros_request); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) bool -take_response__@(spec.srv_name)( +take_response__@(service.structure_type.name)( void * untyped_requester, rmw_request_id_t * request_header, void * untyped_ros_response); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) bool -send_response__@(spec.srv_name)( +send_response__@(service.structure_type.name)( void * untyped_replier, const rmw_request_id_t * request_header, const void * untyped_ros_response); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) void * -get_request_datawriter__@(spec.srv_name)(void * untyped_requester); +get_request_datawriter__@(service.structure_type.name)(void * untyped_requester); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) void * -get_reply_datareader__@(spec.srv_name)(void * untyped_requester); +get_reply_datareader__@(service.structure_type.name)(void * untyped_requester); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) void * -get_request_datareader__@(spec.srv_name)(void * untyped_replier); +get_request_datareader__@(service.structure_type.name)(void * untyped_replier); -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) void * -get_reply_datawriter__@(spec.srv_name)(void * untyped_replier); +get_reply_datawriter__@(service.structure_type.name)(void * untyped_replier); } // namespace typesupport_connext_cpp - -} // namespace @(subfolder) - -} // namespace @(spec.pkg_name) +@[for ns in reversed(service.structure_type.namespaces)]@ +} // namespace @(ns) +@[end for]@ #ifdef __cplusplus extern "C" { #endif -ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_PUBLIC_@(package_name) const rosidl_service_type_support_t * - ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_connext_cpp, @(spec.pkg_name), @(subfolder), @(spec.srv_name))(); + ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME( + rosidl_typesupport_connext_cpp, + @(', '.join([package_name] + list(interface_path.parents[0].parts))), + @(service.structure_type.name))(); #ifdef __cplusplus } #endif - -#endif // @(header_guard_variable) diff --git a/rosidl_typesupport_connext_cpp/resource/srv__type_support.cpp.em b/rosidl_typesupport_connext_cpp/resource/srv__type_support.cpp.em index 3bf71bd..6da2d6f 100644 --- a/rosidl_typesupport_connext_cpp/resource/srv__type_support.cpp.em +++ b/rosidl_typesupport_connext_cpp/resource/srv__type_support.cpp.em @@ -1,20 +1,29 @@ -// generated from rosidl_typesupport_connext_cpp/resource/srv__type_support.cpp.em -// generated code does not contain a copyright notice - -@####################################################################### -@# EmPy template for generating __type_support.cpp files -@# -@# Context: -@# - spec (rosidl_parser.ServiceSpecification) -@# Parsed specification of the .srv file -@# - subfolder (string) -@# The subfolder / subnamespace of the message -@# Either 'srv' or 'action' -@# - get_header_filename_from_msg_name (function) -@####################################################################### -@ -#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name))__rosidl_typesupport_connext_cpp.hpp" - +@# Included from rosidl_typesupport_connext_cpp/resource/idl__dds_connext__type_support.cpp.em +@{ +from rosidl_cmake import convert_camel_case_to_lower_case_underscore +include_parts = [package_name] + list(interface_path.parents[0].parts) +include_base = '/'.join(include_parts) +cpp_include_prefix = interface_path.stem + +c_include_prefix = convert_camel_case_to_lower_case_underscore(cpp_include_prefix) + +header_files = [ + include_base + '/' + c_include_prefix + '__rosidl_typesupport_connext_cpp.hpp', + 'rmw/error_handling.h', + 'rosidl_typesupport_connext_cpp/identifier.hpp', + 'rosidl_typesupport_connext_cpp/service_type_support.h', + 'rosidl_typesupport_connext_cpp/service_type_support_decl.hpp', + include_base + '/' + c_include_prefix + '__struct.hpp', + include_base + '/dds_connext/' + cpp_include_prefix + '_Support.h', + include_base + '/dds_connext/' + cpp_include_prefix + '_Plugin.h' +] + +dds_specific_header_files = [ + 'ndds/connext_cpp/connext_cpp_requester_details.h', + 'ndds/ndds_cpp.h', + 'ndds/ndds_requestreply_cpp.h' +] +}@ #ifdef Connext_GLIBCXX_USE_CXX11_ABI_ZERO #define _GLIBCXX_USE_CXX11_ABI 0 #endif @@ -27,38 +36,70 @@ # pragma clang diagnostic ignored "-Wreturn-type-c-linkage" # endif #endif -#include -#include -#include + +@[for header_file in dds_specific_header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include <@(header_file)> +@[end for]@ + #ifndef _WIN32 # pragma GCC diagnostic pop #endif -#include "rmw/error_handling.h" -#include "rosidl_typesupport_connext_cpp/identifier.hpp" -#include "rosidl_typesupport_connext_cpp/service_type_support.h" -#include "rosidl_typesupport_connext_cpp/service_type_support_decl.hpp" - -#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name))__struct.hpp" -#include "@(spec.pkg_name)/@(subfolder)/dds_connext/@(spec.srv_name)_Request_Support.h" -#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name + '_Request'))__rosidl_typesupport_connext_cpp.hpp" -#include "@(spec.pkg_name)/@(subfolder)/dds_connext/@(spec.srv_name)_Response_Support.h" -#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name + '_Response'))__rosidl_typesupport_connext_cpp.hpp" +@[for header_file in header_files]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[end for]@ + +@{ +TEMPLATE( + 'msg__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + message=service.request_message, + include_directives=include_directives +) +}@ + +@{ +TEMPLATE( + 'msg__type_support.cpp.em', + package_name=package_name, interface_path=interface_path, + message=service.response_message, + include_directives=include_directives +) +}@ class DDSDomainParticipant; class DDSDataReader; struct DDS_SampleIdentity_t; -namespace @(spec.pkg_name) -{ +@[for ns in service.structure_type.namespaces]@ -namespace @(subfolder) +namespace @(ns) { - +@[end for]@ namespace typesupport_connext_cpp { - -void * create_requester__@(spec.srv_name)( +@{ +__ros_srv_pkg_prefix = '::'.join(service.structure_type.namespaces) +__ros_srv_type = __ros_srv_pkg_prefix + '::' + service.structure_type.name +__ros_request_msg_type = __ros_srv_pkg_prefix + '::' + service.request_message.structure.type.name +__ros_response_msg_type = __ros_srv_pkg_prefix + '::' + service.response_message.structure.type.name +__dds_request_msg_type = __ros_srv_pkg_prefix + '::dds_::' + service.request_message.structure.type.name + '_' +__dds_response_msg_type = __ros_srv_pkg_prefix + '::dds_::' + service.response_message.structure.type.name + '_' +}@ + +void * create_requester__@(service.structure_type.name)( void * untyped_participant, const char * request_topic_str, const char * response_topic_str, @@ -69,8 +110,8 @@ void * create_requester__@(spec.srv_name)( void * (*allocator)(size_t)) { using RequesterType = connext::Requester< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; if (!untyped_participant || !request_topic_str || !response_topic_str || !untyped_reader) { return NULL; @@ -119,13 +160,13 @@ void * create_requester__@(spec.srv_name)( return requester; } -const char * destroy_requester__@(spec.srv_name)( +const char * destroy_requester__@(service.structure_type.name)( void * untyped_requester, void (* deallocator)(void *)) { using RequesterType = connext::Requester< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; auto requester = static_cast(untyped_requester); @@ -135,20 +176,20 @@ const char * destroy_requester__@(spec.srv_name)( return nullptr; } -int64_t send_request__@(spec.srv_name)( +int64_t send_request__@(service.structure_type.name)( void * untyped_requester, const void * untyped_ros_request) { - using ROSRequestType = @(spec.pkg_name)::@(subfolder)::@(spec.srv_name)_Request; + using ROSRequestType = @(__ros_request_msg_type); using RequesterType = connext::Requester< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; connext::WriteSample< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_> request; + @(__dds_request_msg_type)> request; const ROSRequestType & ros_request = *( static_cast(untyped_ros_request)); - @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::convert_ros_message_to_dds( + @(__ros_srv_pkg_prefix)::typesupport_connext_cpp::convert_ros_message_to_dds( ros_request, request.data()); RequesterType * requester = static_cast(untyped_requester); @@ -159,7 +200,7 @@ int64_t send_request__@(spec.srv_name)( return sequence_number; } -void * create_replier__@(spec.srv_name)( +void * create_replier__@(service.structure_type.name)( void * untyped_participant, const char * request_topic_str, const char * response_topic_str, @@ -170,8 +211,8 @@ void * create_replier__@(spec.srv_name)( void * (*allocator)(size_t)) { using ReplierType = connext::Replier< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; if (!untyped_participant || !request_topic_str || !response_topic_str || !untyped_reader) { return NULL; @@ -181,7 +222,10 @@ void * create_replier__@(spec.srv_name)( DDSDomainParticipant * participant = static_cast(untyped_participant); const DDS_DataReaderQos * datareader_qos = static_cast(untyped_datareader_qos); const DDS_DataWriterQos * datawriter_qos = static_cast(untyped_datawriter_qos); - connext::ReplierParams<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_> replier_params(participant); + connext::ReplierParams< + @(__dds_request_msg_type), + @(__dds_response_msg_type) + > replier_params(participant); // we create separate publishers and subscribers // because the default publisher is a singleton within @@ -220,13 +264,13 @@ void * create_replier__@(spec.srv_name)( return replier; } -const char * destroy_replier__@(spec.srv_name)( +const char * destroy_replier__@(service.structure_type.name)( void * untyped_replier, void (* deallocator)(void *)) { using ReplierType = connext::Replier< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; auto replier = static_cast(untyped_replier); @@ -236,16 +280,16 @@ const char * destroy_replier__@(spec.srv_name)( return nullptr; } -bool take_request__@(spec.srv_name)( +bool take_request__@(service.structure_type.name)( void * untyped_replier, rmw_request_id_t * request_header, void * untyped_ros_request) { using ReplierType = connext::Replier< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; - using ROSRequestType = @(spec.pkg_name)::@(subfolder)::@(spec.srv_name)_Request; + using ROSRequestType = @(__ros_request_msg_type); if (!untyped_replier || !request_header || !untyped_ros_request) { return false; } @@ -254,7 +298,7 @@ bool take_request__@(spec.srv_name)( ROSRequestType & ros_request = *static_cast(untyped_ros_request); - connext::Sample<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_> request; + connext::Sample<@(__dds_request_msg_type)> request; bool taken = replier->take_request(request); if (!taken) { return false; @@ -264,7 +308,7 @@ bool take_request__@(spec.srv_name)( } bool converted = - @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::convert_dds_message_to_ros(request.data(), ros_request); + @(__ros_srv_pkg_prefix)::typesupport_connext_cpp::convert_dds_message_to_ros(request.data(), ros_request); if (!converted) { return false; } @@ -276,13 +320,16 @@ bool take_request__@(spec.srv_name)( return true; } -bool take_response__@(spec.srv_name)( +bool take_response__@(service.structure_type.name)( void * untyped_requester, rmw_request_id_t * request_header, void * untyped_ros_response) { - using RequesterType = connext::Requester<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_>; - using ROSResponseType = @(spec.pkg_name)::@(subfolder)::@(spec.srv_name)_Response; + using RequesterType = connext::Requester< + @(__dds_request_msg_type), + @(__dds_response_msg_type) + >; + using ROSResponseType = @(__ros_response_msg_type); if (!untyped_requester || !request_header || !untyped_ros_response) { return false; } @@ -291,7 +338,7 @@ bool take_response__@(spec.srv_name)( ROSResponseType & ros_response = *static_cast(untyped_ros_response); - connext::Sample<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_> response; + connext::Sample<@(__dds_response_msg_type)> response; bool received = requester->take_reply(response); if (!received) { return false; @@ -306,25 +353,28 @@ bool take_response__@(spec.srv_name)( request_header->sequence_number = sequence_number; bool converted = - @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::convert_dds_message_to_ros(response.data(), ros_response); + @(__ros_srv_pkg_prefix)::typesupport_connext_cpp::convert_dds_message_to_ros(response.data(), ros_response); return converted; } -bool send_response__@(spec.srv_name)( +bool send_response__@(service.structure_type.name)( void * untyped_replier, const rmw_request_id_t * request_header, const void * untyped_ros_response) { - using ROSResponseType = const @(spec.pkg_name)::@(subfolder)::@(spec.srv_name)_Response; - using ReplierType = connext::Replier<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_>; + using ROSResponseType = const @(__ros_response_msg_type); + using ReplierType = connext::Replier< + @(__dds_request_msg_type), + @(__dds_response_msg_type) + >; if (!untyped_replier || !request_header || !untyped_ros_response) { return false; } - connext::WriteSample<@(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_> response; + connext::WriteSample<@(__dds_response_msg_type)> response; ROSResponseType & ros_response = *(reinterpret_cast(untyped_ros_response)); bool converted = - @(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::convert_ros_message_to_dds(ros_response, response.data()); + @(__ros_srv_pkg_prefix)::typesupport_connext_cpp::convert_ros_message_to_dds(ros_response, response.data()); if (!converted) { return false; } @@ -344,99 +394,100 @@ bool send_response__@(spec.srv_name)( } void * -get_request_datawriter__@(spec.srv_name)(void * untyped_requester) +get_request_datawriter__@(service.structure_type.name)(void * untyped_requester) { if (!untyped_requester) { return NULL; } using RequesterType = connext::Requester< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; RequesterType * requester = reinterpret_cast(untyped_requester); return requester->get_request_datawriter(); } void * -get_reply_datareader__@(spec.srv_name)(void * untyped_requester) +get_reply_datareader__@(service.structure_type.name)(void * untyped_requester) { if (!untyped_requester) { return NULL; } using RequesterType = connext::Requester< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; RequesterType * requester = reinterpret_cast(untyped_requester); return requester->get_reply_datareader(); } void * -get_request_datareader__@(spec.srv_name)(void * untyped_replier) +get_request_datareader__@(service.structure_type.name)(void * untyped_replier) { if (!untyped_replier) { return NULL; } using ReplierType = connext::Replier< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; ReplierType * replier = reinterpret_cast(untyped_replier); return replier->get_request_datareader(); } void * -get_reply_datawriter__@(spec.srv_name)(void * untyped_replier) +get_reply_datawriter__@(service.structure_type.name)(void * untyped_replier) { if (!untyped_replier) { return NULL; } using ReplierType = connext::Replier< - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Request_, - @(spec.pkg_name)::@(subfolder)::dds_::@(spec.srv_name)_Response_ + @(__dds_request_msg_type), + @(__dds_response_msg_type) >; ReplierType * replier = reinterpret_cast(untyped_replier); return replier->get_reply_datawriter(); } -static service_type_support_callbacks_t callbacks = { - "@(spec.pkg_name)", - "@(spec.srv_name)", - &create_requester__@(spec.srv_name), - &destroy_requester__@(spec.srv_name), - &create_replier__@(spec.srv_name), - &destroy_replier__@(spec.srv_name), - &send_request__@(spec.srv_name), - &take_request__@(spec.srv_name), - &send_response__@(spec.srv_name), - &take_response__@(spec.srv_name), - &get_request_datawriter__@(spec.srv_name), - &get_reply_datareader__@(spec.srv_name), - &get_request_datareader__@(spec.srv_name), - &get_reply_datawriter__@(spec.srv_name), +static service_type_support_callbacks_t _@(service.structure_type.name)__callbacks = { + "@(package_name)", + "@(service.structure_type.name)", + &create_requester__@(service.structure_type.name), + &destroy_requester__@(service.structure_type.name), + &create_replier__@(service.structure_type.name), + &destroy_replier__@(service.structure_type.name), + &send_request__@(service.structure_type.name), + &take_request__@(service.structure_type.name), + &send_response__@(service.structure_type.name), + &take_response__@(service.structure_type.name), + &get_request_datawriter__@(service.structure_type.name), + &get_reply_datareader__@(service.structure_type.name), + &get_request_datareader__@(service.structure_type.name), + &get_reply_datawriter__@(service.structure_type.name), }; -static rosidl_service_type_support_t handle = { +static rosidl_service_type_support_t _@(service.structure_type.name)__handle = { rosidl_typesupport_connext_cpp::typesupport_identifier, - &callbacks, + &_@(service.structure_type.name)__callbacks, get_service_typesupport_handle_function, }; } // namespace typesupport_connext_cpp -} // namespace @(subfolder) +@[for ns in reversed(service.structure_type.namespaces)]@ +} // namespace @(ns) -} // namespace @(spec.pkg_name) +@[end for]@ namespace rosidl_typesupport_connext_cpp { template<> -ROSIDL_TYPESUPPORT_CONNEXT_CPP_EXPORT_@(spec.pkg_name) +ROSIDL_TYPESUPPORT_CONNEXT_CPP_EXPORT_@(package_name) const rosidl_service_type_support_t * -get_service_type_support_handle<@(spec.pkg_name)::@(subfolder)::@(spec.srv_name)>() +get_service_type_support_handle<@(__ros_srv_type)>() { - return &@(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::handle; + return &@(__ros_srv_pkg_prefix)::typesupport_connext_cpp::_@(service.structure_type.name)__handle; } } // namespace rosidl_typesupport_connext_cpp @@ -447,8 +498,12 @@ extern "C" #endif const rosidl_service_type_support_t * -ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_connext_cpp, @(spec.pkg_name), @(subfolder), @(spec.srv_name))() { - return &@(spec.pkg_name)::@(subfolder)::typesupport_connext_cpp::handle; +ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME( + rosidl_typesupport_connext_cpp, + @(', '.join([package_name] + list(interface_path.parents[0].parts))), + @(service.structure_type.name))() +{ + return &@(__ros_srv_pkg_prefix)::typesupport_connext_cpp::_@(service.structure_type.name)__handle; } #ifdef __cplusplus diff --git a/rosidl_typesupport_connext_cpp/rosidl_typesupport_connext_cpp-extras.cmake.in b/rosidl_typesupport_connext_cpp/rosidl_typesupport_connext_cpp-extras.cmake.in index c31b555..5deef97 100644 --- a/rosidl_typesupport_connext_cpp/rosidl_typesupport_connext_cpp-extras.cmake.in +++ b/rosidl_typesupport_connext_cpp/rosidl_typesupport_connext_cpp-extras.cmake.in @@ -9,7 +9,7 @@ if(NOT Connext_FOUND) else() find_package(ament_cmake_core QUIET REQUIRED) ament_register_extension( - "rosidl_generate_interfaces" + "rosidl_generate_idl_interfaces" "rosidl_typesupport_connext_cpp" "rosidl_typesupport_connext_cpp_generate_interfaces.cmake") diff --git a/rosidl_typesupport_connext_cpp/rosidl_typesupport_connext_cpp/__init__.py b/rosidl_typesupport_connext_cpp/rosidl_typesupport_connext_cpp/__init__.py index 70ce221..4999ac2 100644 --- a/rosidl_typesupport_connext_cpp/rosidl_typesupport_connext_cpp/__init__.py +++ b/rosidl_typesupport_connext_cpp/rosidl_typesupport_connext_cpp/__init__.py @@ -16,31 +16,12 @@ import subprocess import sys -from rosidl_cmake import convert_camel_case_to_lower_case_underscore -from rosidl_cmake import expand_template -from rosidl_cmake import get_newest_modification_time -from rosidl_parser import parse_message_file -from rosidl_parser import parse_service_file -from rosidl_parser import validate_field_types - - -def parse_ros_interface_files(pkg_name, ros_interface_files): - message_specs = [] - service_specs = [] - for idl_file in ros_interface_files: - extension = os.path.splitext(idl_file)[1] - if extension == '.msg': - message_spec = parse_message_file(pkg_name, idl_file) - message_specs.append((idl_file, message_spec)) - elif extension == '.srv': - service_spec = parse_service_file(pkg_name, idl_file) - service_specs.append((idl_file, service_spec)) - return (message_specs, service_specs) +from rosidl_cmake import generate_files def generate_dds_connext_cpp( pkg_name, dds_interface_files, dds_interface_base_path, deps, - output_basepath, idl_pp, message_specs, service_specs): + output_basepath, idl_pp): include_dirs = [dds_interface_base_path] for dep in deps: @@ -53,7 +34,7 @@ def generate_dds_connext_cpp( if idl_base_path not in include_dirs: include_dirs.append(idl_base_path) - for index, idl_file in enumerate(dds_interface_files): + for idl_file in dds_interface_files: assert os.path.exists(idl_file), 'Could not find IDL file: ' + idl_file # get two level of parent folders for idl file @@ -117,7 +98,7 @@ def generate_dds_connext_cpp( def _inject_unused_attribute(pkg_name, msg_name, lines): # prepend attribute before constants of string type - prefix = 'static const DDS_Char * Constants__' + prefix = 'static const DDS_Char *' inject_prefix = '__attribute__((unused)) ' for index, line in enumerate(lines): if not line.lstrip().startswith(prefix): @@ -135,66 +116,12 @@ def _modify(filename, pkg_name, msg_name, callback): h.write('\n'.join(lines)) -def generate_cpp(args, message_specs, service_specs, known_msg_types): - template_dir = args['template_dir'] - mapping_msgs = { - os.path.join(template_dir, 'msg__rosidl_typesupport_connext_cpp.hpp.em'): +def generate_cpp(arguments_file): + mapping = { + 'idl__rosidl_typesupport_connext_cpp.hpp.em': '%s__rosidl_typesupport_connext_cpp.hpp', - os.path.join(template_dir, 'msg__type_support.cpp.em'): - '%s__type_support.cpp', + 'idl__dds_connext__type_support.cpp.em': + 'dds_connext/%s__type_support.cpp' } - mapping_srvs = { - os.path.join(template_dir, 'srv__rosidl_typesupport_connext_cpp.hpp.em'): - '%s__rosidl_typesupport_connext_cpp.hpp', - os.path.join(template_dir, 'srv__type_support.cpp.em'): - '%s__type_support.cpp', - } - - for template_file in mapping_msgs.keys(): - assert os.path.exists(template_file), 'Could not find template: ' + template_file - for template_file in mapping_srvs.keys(): - assert os.path.exists(template_file), 'Could not find template: ' + template_file - - functions = { - 'get_header_filename_from_msg_name': convert_camel_case_to_lower_case_underscore, - } - # generate_dds_connext_cpp() and therefore the make target depend on the additional files - # therefore they must be listed here even if the generated type support files are independent - latest_target_timestamp = get_newest_modification_time( - args['target_dependencies'] + args.get('additional_files', [])) - - for idl_file, spec in message_specs: - validate_field_types(spec, known_msg_types) - subfolder = os.path.basename(os.path.dirname(idl_file)) - for template_file, generated_filename in mapping_msgs.items(): - generated_file = os.path.join(args['output_dir'], subfolder) - if generated_filename.endswith('.cpp'): - generated_file = os.path.join(generated_file, 'dds_connext') - generated_file = os.path.join( - generated_file, generated_filename % - convert_camel_case_to_lower_case_underscore(spec.base_type.type)) - - data = {'spec': spec, 'subfolder': subfolder} - data.update(functions) - expand_template( - template_file, data, generated_file, - minimum_timestamp=latest_target_timestamp) - - for idl_file, spec in service_specs: - validate_field_types(spec, known_msg_types) - subfolder = os.path.basename(os.path.dirname(idl_file)) - for template_file, generated_filename in mapping_srvs.items(): - generated_file = os.path.join(args['output_dir'], subfolder) - if generated_filename.endswith('.cpp'): - generated_file = os.path.join(generated_file, 'dds_connext') - generated_file = os.path.join( - generated_file, generated_filename % - convert_camel_case_to_lower_case_underscore(spec.srv_name)) - - data = {'spec': spec, 'subfolder': subfolder} - data.update(functions) - expand_template( - template_file, data, generated_file, - minimum_timestamp=latest_target_timestamp) - + generate_files(arguments_file, mapping) return 0