From b8fd304546704e03c6bf437dadbbadbb0d6af68c Mon Sep 17 00:00:00 2001 From: methylDragon Date: Mon, 20 Mar 2023 15:50:38 -0700 Subject: [PATCH 01/27] Implement dynamic typesupport wrappers Signed-off-by: methylDragon --- rclcpp/CMakeLists.txt | 6 + .../detail/dynamic_data_impl.hpp | 326 +++++++++ .../detail/dynamic_type_builder_impl.hpp | 162 +++++ .../dynamic_typesupport/dynamic_data.hpp | 373 ++++++++++ .../dynamic_typesupport/dynamic_message.hpp | 105 +++ .../dynamic_message_type.hpp | 93 +++ .../dynamic_serialization_support.hpp | 110 +++ .../dynamic_typesupport/dynamic_type.hpp | 196 ++++++ .../dynamic_type_builder.hpp | 318 +++++++++ rclcpp/include/rclcpp/rclcpp.hpp | 13 + rclcpp/package.xml | 1 + .../dynamic_typesupport/dynamic_data.cpp | 642 ++++++++++++++++++ .../dynamic_typesupport/dynamic_message.cpp | 61 ++ .../dynamic_message_type.cpp | 57 ++ .../dynamic_serialization_support.cpp | 131 ++++ .../dynamic_typesupport/dynamic_type.cpp | 320 +++++++++ .../dynamic_type_builder.cpp | 492 ++++++++++++++ 17 files changed, 3406 insertions(+) create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp create mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp create mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp create mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp create mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp create mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp create mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index 6979d980f8..583aeece44 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -49,6 +49,12 @@ set(${PROJECT_NAME}_SRCS src/rclcpp/detail/rmw_implementation_specific_subscription_payload.cpp src/rclcpp/detail/utilities.cpp src/rclcpp/duration.cpp + src/rclcpp/dynamic_typesupport/dynamic_data.cpp + src/rclcpp/dynamic_typesupport/dynamic_message.cpp + src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp + src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp + src/rclcpp/dynamic_typesupport/dynamic_type.cpp + src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp src/rclcpp/event.cpp src/rclcpp/exceptions/exceptions.cpp src/rclcpp/executable_list.cpp diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp new file mode 100644 index 0000000000..d2e77247ae --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp @@ -0,0 +1,326 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_ + +#include +#include +#include +#include + +#include +#include +#include "rclcpp/exceptions.hpp" + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_ +#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#endif + + +#define __DYNAMIC_DATA_GET_VALUE_BY_ID_FN(ValueT, FunctionT) \ + template<> \ + ValueT \ + DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) \ + { \ + ValueT out; \ + rosidl_dynamic_typesupport_dynamic_data_get_ ## FunctionT ## _value( \ + rosidl_dynamic_data_.get(), id, &out); \ + return out; \ + } + +#define __DYNAMIC_DATA_GET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ + template<> \ + ValueT \ + DynamicData::get_value(const std::string & name) \ + { \ + return get_value(get_member_id(name)); \ + } + +#define __DYNAMIC_DATA_SET_VALUE_BY_ID_FN(ValueT, FunctionT) \ + template<> \ + void \ + DynamicData::set_value(rosidl_dynamic_typesupport_member_id_t id, ValueT value) \ + { \ + rosidl_dynamic_typesupport_dynamic_data_set_ ## FunctionT ## _value( \ + rosidl_dynamic_data_.get(), id, value); \ + } + +#define __DYNAMIC_DATA_SET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ + template<> \ + void \ + DynamicData::set_value(const std::string & name, ValueT value) \ + { \ + set_value(get_member_id(name), value); \ + } + +#define __DYNAMIC_DATA_INSERT_VALUE(ValueT, FunctionT) \ + template<> \ + rosidl_dynamic_typesupport_member_id_t \ + DynamicData::insert_value(ValueT value) \ + { \ + rosidl_dynamic_typesupport_member_id_t out; \ + rosidl_dynamic_typesupport_dynamic_data_insert_ ## FunctionT ## _value( \ + rosidl_dynamic_data_.get(), value, &out); \ + return out; \ + } + +#define DYNAMIC_DATA_DEFINITIONS(ValueT, FunctionT) \ + __DYNAMIC_DATA_GET_VALUE_BY_ID_FN(ValueT, FunctionT) \ + __DYNAMIC_DATA_GET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ + __DYNAMIC_DATA_SET_VALUE_BY_ID_FN(ValueT, FunctionT) \ + __DYNAMIC_DATA_SET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ + __DYNAMIC_DATA_INSERT_VALUE(ValueT, FunctionT) + + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + +/** + * Since we're in a ROS layer, these should support all ROS interface C++ types as found in: + * https://docs.ros.org/en/rolling/Concepts/About-ROS-Interfaces.html + * + * Explicitly: + * - Basic types: bool, byte, char + * - Float types: float, double + * - Int types: int8_t, int16_t, int32_t, int64_t + * - Unsigned int types: uint8_t, uint16_t, uint32_t, uint64_t + * - String types: std::string, std::u16string + */ + +DYNAMIC_DATA_DEFINITIONS(bool, bool); +// DYNAMIC_DATA_DEFINITIONS(std::byte, byte); +DYNAMIC_DATA_DEFINITIONS(char, char); +DYNAMIC_DATA_DEFINITIONS(float, float32); +DYNAMIC_DATA_DEFINITIONS(double, float64); +DYNAMIC_DATA_DEFINITIONS(int8_t, int8); +DYNAMIC_DATA_DEFINITIONS(int16_t, int16); +DYNAMIC_DATA_DEFINITIONS(int32_t, int32); +DYNAMIC_DATA_DEFINITIONS(int64_t, int64); +DYNAMIC_DATA_DEFINITIONS(uint8_t, uint8); +DYNAMIC_DATA_DEFINITIONS(uint16_t, uint16); +DYNAMIC_DATA_DEFINITIONS(uint32_t, uint32); +DYNAMIC_DATA_DEFINITIONS(uint64_t, uint64); +// DYNAMIC_DATA_DEFINITIONS(std::string, std::string); +// DYNAMIC_DATA_DEFINITIONS(std::u16string, std::u16string); + +// Byte and String getters have a different implementation and are defined below + + +// BYTE ============================================================================================ +template<> +std::byte +DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) +{ + unsigned char out; + rosidl_dynamic_typesupport_dynamic_data_get_byte_value(get_rosidl_dynamic_data(), id, &out); + return static_cast(out); +} + + +template<> +std::byte +DynamicData::get_value(const std::string & name) +{ + return get_value(get_member_id(name)); +} + + +template<> +void +DynamicData::set_value( + rosidl_dynamic_typesupport_member_id_t id, const std::byte value) +{ + rosidl_dynamic_typesupport_dynamic_data_set_byte_value( + rosidl_dynamic_data_.get(), id, static_cast(value)); +} + + +template<> +void +DynamicData::set_value(const std::string & name, const std::byte value) +{ + set_value(get_member_id(name), value); +} + + +template<> +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_value(const std::byte value) +{ + rosidl_dynamic_typesupport_member_id_t out; + rosidl_dynamic_typesupport_dynamic_data_insert_byte_value( + rosidl_dynamic_data_.get(), static_cast(value), &out); + return out; +} + + +// STRINGS ========================================================================================= +template<> +std::string +DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) +{ + size_t buf_length; + char * buf = nullptr; + rosidl_dynamic_typesupport_dynamic_data_get_string_value( + get_rosidl_dynamic_data(), id, &buf, &buf_length); + auto out = std::string(buf, buf_length); + free(buf); + return out; +} + + +template<> +std::u16string +DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) +{ + size_t buf_length; + char16_t * buf = nullptr; + rosidl_dynamic_typesupport_dynamic_data_get_wstring_value( + get_rosidl_dynamic_data(), id, &buf, &buf_length); + auto out = std::u16string(buf, buf_length); + free(buf); + return out; +} + + +template<> +std::string +DynamicData::get_value(const std::string & name) +{ + return get_value(get_member_id(name)); +} + + +template<> +std::u16string +DynamicData::get_value(const std::string & name) +{ + return get_value(get_member_id(name)); +} + + +template<> +void +DynamicData::set_value( + rosidl_dynamic_typesupport_member_id_t id, const std::string value) +{ + rosidl_dynamic_typesupport_dynamic_data_set_string_value( + rosidl_dynamic_data_.get(), id, value.c_str(), value.size()); +} + + +template<> +void +DynamicData::set_value( + rosidl_dynamic_typesupport_member_id_t id, const std::u16string value) +{ + rosidl_dynamic_typesupport_dynamic_data_set_wstring_value( + rosidl_dynamic_data_.get(), id, value.c_str(), value.size()); +} + + +template<> +void +DynamicData::set_value(const std::string & name, const std::string value) +{ + set_value(get_member_id(name), value); +} + + +template<> +void +DynamicData::set_value(const std::string & name, const std::u16string value) +{ + set_value(get_member_id(name), value); +} + + +template<> +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_value(const std::string value) +{ + rosidl_dynamic_typesupport_member_id_t out; + rosidl_dynamic_typesupport_dynamic_data_insert_string_value( + rosidl_dynamic_data_.get(), value.c_str(), value.size(), &out); + return out; +} + + +template<> +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_value(const std::u16string value) +{ + rosidl_dynamic_typesupport_member_id_t out; + rosidl_dynamic_typesupport_dynamic_data_insert_wstring_value( + rosidl_dynamic_data_.get(), value.c_str(), value.size(), &out); + return out; +} + + +// THROW FOR UNSUPPORTED TYPES ===================================================================== +template +ValueT +DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) +{ + throw rclcpp::exceptions::UnimplementedError("get_value is not implemented for input type"); +} + + +template +ValueT +DynamicData::get_value(const std::string & name) +{ + throw rclcpp::exceptions::UnimplementedError("get_value is not implemented for input type"); +} + + +template +void +DynamicData::set_value( + rosidl_dynamic_typesupport_member_id_t id, ValueT value) +{ + throw rclcpp::exceptions::UnimplementedError("set_value is not implemented for input type"); +} + + +template +void +DynamicData::set_value(const std::string & name, ValueT value) +{ + throw rclcpp::exceptions::UnimplementedError("set_value is not implemented for input type"); +} + + +template +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_value(ValueT value) +{ + throw rclcpp::exceptions::UnimplementedError("insert_value is not implemented for input type"); +} + + +} // namespace dynamic_typesupport +} // namespace rclcpp + +#undef __DYNAMIC_DATA_GET_VALUE_BY_ID_FN +#undef __DYNAMIC_DATA_GET_VALUE_BY_NAME_FN +#undef __DYNAMIC_DATA_SET_VALUE_BY_ID_FN +#undef __DYNAMIC_DATA_SET_VALUE_BY_NAME_FN +#undef __DYNAMIC_DATA_INSERT_VALUE +#undef DYNAMIC_DATA_DEFINITIONS + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp new file mode 100644 index 0000000000..e71d4702bd --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp @@ -0,0 +1,162 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_TYPE_BUILDER_IMPL_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_TYPE_BUILDER_IMPL_HPP_ + +#include +#include +#include +#include + +#include +#include +#include "rclcpp/exceptions.hpp" + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_ +#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#endif + + +#define __DYNAMIC_TYPE_BUILDER_ADD_MEMBER_FN(MemberT, FunctionT) \ + template<> \ + void \ + DynamicTypeBuilder::add_member( \ + rosidl_dynamic_typesupport_member_id_t id, const std::string & name) \ + { \ + rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## _member( \ + rosidl_dynamic_type_builder_.get(), id, name.c_str(), name.size()); \ + } + +#define __DYNAMIC_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN(MemberT, FunctionT) \ + template<> \ + void \ + DynamicTypeBuilder::add_array_member( \ + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length) \ + { \ + rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## _array_member( \ + rosidl_dynamic_type_builder_.get(), id, name.c_str(), name.size(), array_length); \ + } + +#define __DYNAMIC_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ + template<> \ + void \ + DynamicTypeBuilder::add_unbounded_sequence_member( \ + rosidl_dynamic_typesupport_member_id_t id, const std::string & name) \ + { \ + rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## _unbounded_sequence_member( \ + rosidl_dynamic_type_builder_.get(), id, name.c_str(), name.size()); \ + } + +#define __DYNAMIC_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ + template<> \ + void \ + DynamicTypeBuilder::add_bounded_sequence_member( \ + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound) \ + { \ + rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## _bounded_sequence_member( \ + rosidl_dynamic_type_builder_.get(), id, name.c_str(), name.size(), sequence_bound); \ + } + +#define DYNAMIC_TYPE_BUILDER_DEFINITIONS(MemberT, FunctionT) \ + __DYNAMIC_TYPE_BUILDER_ADD_MEMBER_FN(MemberT, FunctionT) \ + __DYNAMIC_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN(MemberT, FunctionT) \ + __DYNAMIC_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ + __DYNAMIC_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ + + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + +/** + * Since we're in a ROS layer, these should support all ROS interface C++ types as found in: + * https://docs.ros.org/en/rolling/Concepts/About-ROS-Interfaces.html + * + * Explicitly: + * - Basic types: bool, byte, char + * - Float types: float, double + * - Int types: int8_t, int16_t, int32_t, int64_t + * - Unsigned int types: uint8_t, uint16_t, uint32_t, uint64_t + * - String types: std::string, std::u16string + */ + +DYNAMIC_TYPE_BUILDER_DEFINITIONS(bool, bool); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(std::byte, byte); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(char, char); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(float, float32); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(double, float64); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(int8_t, int8); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(int16_t, int16); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(int32_t, int32); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(int64_t, int64); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(uint8_t, uint8); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(uint16_t, uint16); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(uint32_t, uint32); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(uint64_t, uint64); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(std::string, string); +DYNAMIC_TYPE_BUILDER_DEFINITIONS(std::u16string, wstring); + + +// THROW FOR UNSUPPORTED TYPES ===================================================================== +template +void +DynamicTypeBuilder::add_member(rosidl_dynamic_typesupport_member_id_t id, const std::string & name) +{ + throw rclcpp::exceptions::UnimplementedError( + "add_member is not implemented for input type"); +} + + +template +void +DynamicTypeBuilder::add_array_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length) +{ + throw rclcpp::exceptions::UnimplementedError( + "add_array_member is not implemented for input type"); +} + + +template +void +DynamicTypeBuilder::add_unbounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name) +{ + throw rclcpp::exceptions::UnimplementedError( + "add_unbounded_sequence_member is not implemented for input type"); +} + + +template +void +DynamicTypeBuilder::add_bounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound) +{ + throw rclcpp::exceptions::UnimplementedError( + "add_bounded_sequence_member is not implemented for input type"); +} + + +} // namespace dynamic_typesupport +} // namespace rclcpp + +#undef __DYNAMIC_TYPE_BUILDER_ADD_MEMBER_FN +#undef __DYNAMIC_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN +#undef __DYNAMIC_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN +#undef __DYNAMIC_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN +#undef DYNAMIC_TYPE_BUILDER_DEFINITIONS + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_TYPE_BUILDER_IMPL_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp new file mode 100644 index 0000000000..9429cac90f --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp @@ -0,0 +1,373 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_ + + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/macros.hpp" +#include "rclcpp/visibility_control.hpp" + +#include + + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + + +class DynamicType; +class DynamicTypeBuilder; + +/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_data_t * +/** + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Exposes the underlying serialization support API + * + * Ownership: + * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed + * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. + * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer + * must point to the same location in memory as the stored raw pointer! + */ +class DynamicData : public std::enable_shared_from_this +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicData) + + // CONSTRUCTION ================================================================================== + // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the + // lifetime of the serialization support (if the constructor cannot otherwise get it from args). + // + // In cases where a dynamic data pointer is passed, the serialization support composed by + // the data should be the exact same object managed by the DynamicSerializationSupport, + // otherwise the lifetime management will not work properly. + + /// Construct a new DynamicData with the provided dynamic type builder + RCLCPP_PUBLIC + explicit DynamicData(std::shared_ptr dynamic_type_builder); + + /// Construct a new DynamicData with the provided dynamic type + RCLCPP_PUBLIC + explicit DynamicData(std::shared_ptr dynamic_type); + + /// Assume ownership of raw pointer + RCLCPP_PUBLIC + DynamicData( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data); + + /// Copy shared pointer + RCLCPP_PUBLIC + DynamicData( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_data); + + /// Loaning constructor + /// Must only be called with raw ptr obtained from loaning! + // NOTE(methylDragon): I'd put this in protected, but I need this exposed to + // enable_shared_from_this... + RCLCPP_PUBLIC + DynamicData( + DynamicData::SharedPtr parent_data, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data); + + // NOTE(methylDragon): Deliberately no constructor from description to nudge users towards using + // construction from dynamic type/builder, which is more efficient + + /// Copy constructor + RCLCPP_PUBLIC + DynamicData(const DynamicData & other); + + /// Move constructor + RCLCPP_PUBLIC + DynamicData(DynamicData && other) noexcept; + + /// Copy assignment + RCLCPP_PUBLIC + DynamicData & operator=(const DynamicData & other); + + /// Move assignment + RCLCPP_PUBLIC + DynamicData & operator=(DynamicData && other) noexcept; + + RCLCPP_PUBLIC + virtual ~DynamicData(); + + + // GETTERS ======================================================================================= + RCLCPP_PUBLIC + const std::string + get_library_identifier() const; + + RCLCPP_PUBLIC + const std::string + get_name() const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_dynamic_data_t * + get_rosidl_dynamic_data(); + + RCLCPP_PUBLIC + const rosidl_dynamic_typesupport_dynamic_data_t * + get_rosidl_dynamic_data() const; + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_data(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_data() const; + + RCLCPP_PUBLIC + DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_dynamic_serialization_support() const; + + RCLCPP_PUBLIC + size_t + get_item_count() const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + get_member_id(size_t index) const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + get_member_id(const std::string & name) const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + get_array_index(size_t index) const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + get_array_index(const std::string & name) const; + + + // METHODS ======================================================================================= + RCLCPP_PUBLIC + DynamicData + clone() const; + + RCLCPP_PUBLIC + DynamicData::SharedPtr + clone_shared() const; + + RCLCPP_PUBLIC + bool + equals(const DynamicData & other) const; + + RCLCPP_PUBLIC + DynamicData::SharedPtr + loan_value(rosidl_dynamic_typesupport_member_id_t id); + + RCLCPP_PUBLIC + DynamicData::SharedPtr + loan_value(const std::string & name); + + RCLCPP_PUBLIC + void + clear_all_values(); + + RCLCPP_PUBLIC + void + clear_nonkey_values(); + + RCLCPP_PUBLIC + void + clear_value(rosidl_dynamic_typesupport_member_id_t id); + + RCLCPP_PUBLIC + void + clear_value(const std::string & name); + + RCLCPP_PUBLIC + void + clear_sequence(); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_sequence_data(); + + RCLCPP_PUBLIC + void + remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index); + + RCLCPP_PUBLIC + void + print() const; + + RCLCPP_PUBLIC + bool + serialize(std::shared_ptr buffer); + + RCLCPP_PUBLIC + bool + deserialize(std::shared_ptr buffer); + + + // MEMBER ACCESS TEMPLATES ======================================================================= + /** + * Since we're in a ROS layer, these should support all ROS interface C++ types as found in: + * https://docs.ros.org/en/rolling/Concepts/About-ROS-Interfaces.html + * + * Explicitly: + * - Basic types: bool, byte, char + * - Float types: float, double + * - Int types: int8_t, int16_t, int32_t, int64_t + * - Unsigned int types: uint8_t, uint16_t, uint32_t, uint64_t + * - String types: std::string, std::u16string + */ + + template + ValueT + get_value(rosidl_dynamic_typesupport_member_id_t id); + + template + ValueT + get_value(const std::string & name); + + template + void + set_value(rosidl_dynamic_typesupport_member_id_t id, ValueT value); + + template + void + set_value(const std::string & name, ValueT value); + + template + rosidl_dynamic_typesupport_member_id_t + insert_value(ValueT value); + + + // BOUNDED STRING MEMBER ACCESS ================================================================== + RCLCPP_PUBLIC + const std::string + get_bounded_string_value(rosidl_dynamic_typesupport_member_id_t id, size_t string_bound); + + RCLCPP_PUBLIC + const std::string + get_bounded_string_value(const std::string & name, size_t string_bound); + + RCLCPP_PUBLIC + const std::u16string + get_bounded_wstring_value(rosidl_dynamic_typesupport_member_id_t id, size_t wstring_bound); + + RCLCPP_PUBLIC + const std::u16string + get_bounded_wstring_value(const std::string & name, size_t wstring_bound); + + RCLCPP_PUBLIC + void + set_bounded_string_value( + rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_bound); + + RCLCPP_PUBLIC + void + set_bounded_string_value(const std::string & name, const std::string value, size_t string_bound); + + RCLCPP_PUBLIC + void + set_bounded_wstring_value( + rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_bound); + + RCLCPP_PUBLIC + void + set_bounded_wstring_value( + const std::string & name, const std::u16string value, size_t wstring_bound); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_bounded_string_value(const std::string value, size_t string_bound); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_bounded_wstring_value(const std::u16string value, size_t wstring_bound); + + + // NESTED MEMBER ACCESS ========================================================================== + RCLCPP_PUBLIC + DynamicData + get_complex_value(rosidl_dynamic_typesupport_member_id_t id); + + RCLCPP_PUBLIC + DynamicData + get_complex_value(const std::string & name); + + RCLCPP_PUBLIC + DynamicData::SharedPtr + get_complex_value_shared(rosidl_dynamic_typesupport_member_id_t id); + + RCLCPP_PUBLIC + DynamicData::SharedPtr + get_complex_value_shared(const std::string & name); + + RCLCPP_PUBLIC + void + set_complex_value(rosidl_dynamic_typesupport_member_id_t id, DynamicData & value); + + RCLCPP_PUBLIC + void + set_complex_value(const std::string & name, DynamicData & value); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_complex_value_copy(const DynamicData & value); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_complex_value(DynamicData & value); + +protected: + // NOTE(methylDragon): + // This is just here to extend the lifetime of the serialization support + // It isn't actually used by the builder since the builder should compose its own support + // + // ... Though ideally it should be the exact same support as the one stored in the + // DynamicSerializationSupport + DynamicSerializationSupport::SharedPtr serialization_support_; + + std::shared_ptr rosidl_dynamic_data_; + + bool is_loaned_; + DynamicData::SharedPtr parent_data_; // Used for returning the loaned value, and lifetime management + +private: + RCLCPP_PUBLIC + DynamicData(); + + RCLCPP_PUBLIC + bool + match_serialization_support_( + const DynamicSerializationSupport & serialization_support, + const rosidl_dynamic_typesupport_dynamic_data_t & dynamic_data); +}; + + +} // namespace dynamic_typesupport +} // namespace rclcpp + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp new file mode 100644 index 0000000000..d39fae07e1 --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -0,0 +1,105 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_ + + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#include "rclcpp/macros.hpp" +#include "rclcpp/visibility_control.hpp" + +#include + + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + + +/// Thin wrapper around DynamicData object for message pubsub +/** + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Exposes the underlying serialization support API + * + * Ownership: + * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed + * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. + * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer + * must point to the same location in memory as the stored raw pointer! + */ +class DynamicMessage final : public DynamicData +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessage) + + // CONSTRUCTION ================================================================================== + // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the + // lifetime of the serialization support (if the constructor cannot otherwise get it from args). + // + // In cases where a dynamic data pointer is passed, the serialization support composed by + // the data should be the exact same object managed by the DynamicSerializationSupport, + // otherwise the lifetime management will not work properly. + + /// Construct a new DynamicMessage with the provided dynamic type builder + RCLCPP_PUBLIC + explicit DynamicMessage(std::shared_ptr dynamic_type_builder); + + /// Construct a new DynamicMessage with the provided dynamic type + RCLCPP_PUBLIC + explicit DynamicMessage(std::shared_ptr dynamic_type); + + /// Assume ownership of raw pointer + RCLCPP_PUBLIC + DynamicMessage( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data); + + /// Copy shared pointer + RCLCPP_PUBLIC + DynamicMessage( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_data); + + /// Loaning constructor + /// Must only be called with raw ptr obtained from loaning! + // NOTE(methylDragon): I'd put this in protected, but I need this exposed to + // enable_shared_from_this... + RCLCPP_PUBLIC + DynamicMessage( + DynamicData::SharedPtr parent_data, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data); + + // NOTE(methylDragon): Deliberately no constructor from description to nudge users towards using + // construction from dynamic type/builder, which is more efficient + +private: + RCLCPP_PUBLIC + DynamicMessage(); +}; + + +} // namespace dynamic_typesupport +} // namespace rclcpp + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp new file mode 100644 index 0000000000..fd33180675 --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -0,0 +1,93 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_HPP_ + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#include "rclcpp/macros.hpp" +#include "rclcpp/visibility_control.hpp" + +#include + + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + + +/// Thin wrapper around DynamicType object for message pubsub type representation +/** + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Exposes the underlying serialization support API + * + * Ownership: + * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed + * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. + * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer + * must point to the same location in memory as the stored raw pointer! + */ +class DynamicMessageType final : public DynamicType +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageType) + + // CONSTRUCTION ================================================================================== + // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the + // lifetime of the serialization support (if the constructor cannot otherwise get it from args). + // + // In cases where a dynamic type pointer is passed, the serialization support composed by + // the type should be the exact same object managed by the DynamicSerializationSupport, + // otherwise the lifetime management will not work properly. + + /// Construct a new DynamicType with the provided dynamic type builder + RCLCPP_PUBLIC + explicit DynamicMessageType(std::shared_ptr dynamic_type_builder); + + /// Assume ownership of raw pointer + RCLCPP_PUBLIC + DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type); + + /// Copy shared pointer + RCLCPP_PUBLIC + DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_type); + + /// From description + RCLCPP_PUBLIC + DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description); + +private: + RCLCPP_PUBLIC + DynamicMessageType(); +}; + + +} // namespace dynamic_typesupport +} // namespace rclcpp + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp new file mode 100644 index 0000000000..932e6a2d94 --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp @@ -0,0 +1,110 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_SERIALIZATION_SUPPORT_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_SERIALIZATION_SUPPORT_HPP_ + +#include +#include + +#include "rclcpp/macros.hpp" +#include "rclcpp/visibility_control.hpp" + +#include + + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + +/// Utility wrapper class for rosidl_dynamic_typesupport_serialization_support_t * +/** + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Exposes the underlying serialization support API + * + * Ownership: + * - This class, similarly to the rosidl_dynamic_typesupport_serialization_support_t, must outlive + * all downstream usages of the serialization support. + */ +class DynamicSerializationSupport : public std::enable_shared_from_this +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicSerializationSupport) + + // CONSTRUCTION ================================================================================== + /// Get the rmw middleware implementation specific serialization support (configured by name) + RCLCPP_PUBLIC + explicit DynamicSerializationSupport(const std::string & serialization_library_name = nullptr); + + /// Assume ownership of raw pointer + RCLCPP_PUBLIC + explicit DynamicSerializationSupport( + rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support); + + /// Copy shared pointer + RCLCPP_PUBLIC + DynamicSerializationSupport( // NOLINT(explicit) + std::shared_ptr serialization_support); + + /// Move constructor + RCLCPP_PUBLIC + DynamicSerializationSupport(DynamicSerializationSupport && other) noexcept; + + /// Move assignment + RCLCPP_PUBLIC + DynamicSerializationSupport & operator=(DynamicSerializationSupport && other) noexcept; + + RCLCPP_PUBLIC + virtual ~DynamicSerializationSupport(); + + + // GETTERS ======================================================================================= + RCLCPP_PUBLIC + const std::string + get_library_identifier() const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_serialization_support_t * + get_rosidl_serialization_support(); + + RCLCPP_PUBLIC + const rosidl_dynamic_typesupport_serialization_support_t * + get_rosidl_serialization_support() const; + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_serialization_support(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_serialization_support() const; + +protected: + RCLCPP_DISABLE_COPY(DynamicSerializationSupport) + + std::shared_ptr rosidl_serialization_support_; + +private: + RCLCPP_PUBLIC + DynamicSerializationSupport(); +}; + + +} // namespace dynamic_typesupport +} // namespace rclcpp + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_SERIALIZATION_SUPPORT_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp new file mode 100644 index 0000000000..e0d9660c22 --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp @@ -0,0 +1,196 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_HPP_ + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/macros.hpp" +#include "rclcpp/visibility_control.hpp" + +#include + + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + + +class DynamicData; +class DynamicTypeBuilder; + +/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_type_t * +/** + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Exposes the underlying serialization support API + * + * Ownership: + * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed + * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. + * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer + * must point to the same location in memory as the stored raw pointer! + */ +class DynamicType : public std::enable_shared_from_this +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicType) + + // CONSTRUCTION ================================================================================== + // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the + // lifetime of the serialization support (if the constructor cannot otherwise get it from args). + // + // In cases where a dynamic type pointer is passed, the serialization support composed by + // the type should be the exact same object managed by the DynamicSerializationSupport, + // otherwise the lifetime management will not work properly. + + /// Construct a new DynamicType with the provided dynamic type builder + RCLCPP_PUBLIC + explicit DynamicType(std::shared_ptr dynamic_type_builder); + + /// Assume ownership of raw pointer + RCLCPP_PUBLIC + DynamicType( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type); + + /// Copy shared pointer + RCLCPP_PUBLIC + DynamicType( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_type); + + /// From description + RCLCPP_PUBLIC + DynamicType( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description); + + /// Copy constructor + RCLCPP_PUBLIC + DynamicType(const DynamicType & other); + + /// Move constructor + RCLCPP_PUBLIC + DynamicType(DynamicType && other) noexcept; + + /// Copy assignment + RCLCPP_PUBLIC + DynamicType & operator=(const DynamicType & other); + + /// Move assignment + RCLCPP_PUBLIC + DynamicType & operator=(DynamicType && other) noexcept; + + RCLCPP_PUBLIC + virtual ~DynamicType(); + + /// Swaps the serialization support if serialization_support is populated + RCLCPP_PUBLIC + void + init_from_description( + const rosidl_runtime_c__type_description__TypeDescription * description, + DynamicSerializationSupport::SharedPtr serialization_support = nullptr); + + // GETTERS ======================================================================================= + RCLCPP_PUBLIC + const std::string + get_library_identifier() const; + + RCLCPP_PUBLIC + const std::string + get_name() const; + + RCLCPP_PUBLIC + size_t + get_member_count() const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_dynamic_type_t * + get_rosidl_dynamic_type(); + + RCLCPP_PUBLIC + const rosidl_dynamic_typesupport_dynamic_type_t * + get_rosidl_dynamic_type() const; + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_type(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_type() const; + + RCLCPP_PUBLIC + DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_dynamic_serialization_support() const; + + + // METHODS ======================================================================================= + RCLCPP_PUBLIC + DynamicType + clone() const; + + RCLCPP_PUBLIC + DynamicType::SharedPtr + clone_shared() const; + + RCLCPP_PUBLIC + bool + equals(const DynamicType & other) const; + + RCLCPP_PUBLIC + DynamicData + build_data(); + + RCLCPP_PUBLIC + std::shared_ptr + build_data_shared(); + +protected: + // NOTE(methylDragon): + // This is just here to extend the lifetime of the serialization support + // It isn't actually used by the builder since the builder should compose its own support + // + // ... Though ideally it should be the exact same support as the one stored in the + // DynamicSerializationSupport + DynamicSerializationSupport::SharedPtr serialization_support_; + + std::shared_ptr rosidl_dynamic_type_; + +private: + RCLCPP_PUBLIC + DynamicType(); + + RCLCPP_PUBLIC + bool + match_serialization_support_( + const DynamicSerializationSupport & serialization_support, + const rosidl_dynamic_typesupport_dynamic_type_t & rosidl_dynamic_type); +}; + + +} // namespace dynamic_typesupport +} // namespace rclcpp + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp new file mode 100644 index 0000000000..62199c838a --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp @@ -0,0 +1,318 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_ + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/macros.hpp" +#include "rclcpp/visibility_control.hpp" + +#include + + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + +class DynamicData; +class DynamicType; + +/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_type_builder_t * +/** + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Exposes the underlying serialization support API + * + * Ownership: + * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed + * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. + * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer + * must point to the same location in memory as the stored raw pointer! + */ +class DynamicTypeBuilder : public std::enable_shared_from_this +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicTypeBuilder) + + // CONSTRUCTION ================================================================================== + // All constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the + // lifetime of the serialization support. + // + // In cases where a dynamic type builder pointer is passed, the serialization support composed by + // the builder should be the exact same object managed by the DynamicSerializationSupport, + // otherwise the lifetime management will not work properly. + + /// Construct a new DynamicTypeBuilder with the provided serialization support + RCLCPP_PUBLIC + DynamicTypeBuilder( + DynamicSerializationSupport::SharedPtr serialization_support, + const std::string & name); + + /// Assume ownership of raw pointer + RCLCPP_PUBLIC + DynamicTypeBuilder( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_type_builder_t * dynamic_type_builder); + + /// Copy shared pointer + RCLCPP_PUBLIC + DynamicTypeBuilder( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr dynamic_type_builder); + + /// Copy constructor + RCLCPP_PUBLIC + DynamicTypeBuilder(const DynamicTypeBuilder & other); + + /// Move constructor + RCLCPP_PUBLIC + DynamicTypeBuilder(DynamicTypeBuilder && other) noexcept; + + /// Copy assignment + RCLCPP_PUBLIC + DynamicTypeBuilder & operator=(const DynamicTypeBuilder & other); + + /// Move assignment + RCLCPP_PUBLIC + DynamicTypeBuilder & operator=(DynamicTypeBuilder && other) noexcept; + + /// From description + RCLCPP_PUBLIC + DynamicTypeBuilder( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description); + + RCLCPP_PUBLIC + virtual ~DynamicTypeBuilder(); + + /// Swaps the serialization support if serialization_support is populated + RCLCPP_PUBLIC + void + init_from_description( + const rosidl_runtime_c__type_description__TypeDescription * description, + DynamicSerializationSupport::SharedPtr serialization_support = nullptr); + + + // GETTERS ======================================================================================= + RCLCPP_PUBLIC + const std::string + get_library_identifier() const; + + RCLCPP_PUBLIC + const std::string + get_name() const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_dynamic_type_builder_t * + get_rosidl_dynamic_type_builder(); + + RCLCPP_PUBLIC + const rosidl_dynamic_typesupport_dynamic_type_builder_t * + get_rosidl_dynamic_type_builder() const; + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_type_builder(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_type_builder() const; + + RCLCPP_PUBLIC + DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_dynamic_serialization_support() const; + + + // METHODS ======================================================================================= + RCLCPP_PUBLIC + void + set_name(const std::string & name); + + RCLCPP_PUBLIC + DynamicTypeBuilder + clone() const; + + RCLCPP_PUBLIC + DynamicTypeBuilder::SharedPtr + clone_shared() const; + + RCLCPP_PUBLIC + void + clear(); + + RCLCPP_PUBLIC + DynamicData + build_data(); + + RCLCPP_PUBLIC + std::shared_ptr + build_data_shared(); + + RCLCPP_PUBLIC + DynamicType + build_type(); + + RCLCPP_PUBLIC + std::shared_ptr + build_type_shared(); + + + // ADD MEMBERS TEMPLATES ========================================================================= + /** + * Since we're in a ROS layer, these should support all ROS interface C++ types as found in: + * https://docs.ros.org/en/rolling/Concepts/About-ROS-Interfaces.html + * + * Explicitly: + * - Basic types: bool, byte, char + * - Float types: float, double + * - Int types: int8_t, int16_t, int32_t, int64_t + * - Unsigned int types: uint8_t, uint16_t, uint32_t, uint64_t + * - String types: std::string, std::u16string + */ + + template + void + add_member(rosidl_dynamic_typesupport_member_id_t id, const std::string & name); + + template + void + add_array_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length); + + template + void + add_unbounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name); + + template + void + add_bounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound); + + + // ADD BOUNDED STRING MEMBERS ==================================================================== + RCLCPP_PUBLIC + void + add_bounded_string_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound); + + RCLCPP_PUBLIC + void + add_bounded_wstring_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound); + + RCLCPP_PUBLIC + void + add_bounded_string_array_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + size_t string_bound, size_t array_length); + + RCLCPP_PUBLIC + void + add_bounded_wstring_array_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + size_t wstring_bound, size_t array_length); + + RCLCPP_PUBLIC + void + add_bounded_string_unbounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound); + + RCLCPP_PUBLIC + void + add_bounded_wstring_unbounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound); + + RCLCPP_PUBLIC + void + add_bounded_string_bounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + size_t string_bound, size_t sequence_bound); + + RCLCPP_PUBLIC + void + add_bounded_wstring_bounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + size_t wstring_bound, size_t sequence_bound); + + + // ADD NESTED MEMBERS ============================================================================ + RCLCPP_PUBLIC + void + add_complex_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicType & nested_type); + + RCLCPP_PUBLIC + void + add_complex_array_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicType & nested_type, size_t array_length); + + RCLCPP_PUBLIC + void + add_complex_unbounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicType & nested_type); + + RCLCPP_PUBLIC + void + add_complex_bounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicType & nested_type, size_t sequence_bound); + +protected: + // NOTE(methylDragon): + // This is just here to extend the lifetime of the serialization support + // It isn't actually used by the builder since the builder should compose its own support + // + // ... Though ideally it should be the exact same support as the one stored in the + // DynamicSerializationSupport + DynamicSerializationSupport::SharedPtr serialization_support_; + + std::shared_ptr rosidl_dynamic_type_builder_; + +private: + RCLCPP_PUBLIC + DynamicTypeBuilder(); + + RCLCPP_PUBLIC + void + init_from_serialization_support_( + DynamicSerializationSupport::SharedPtr serialization_support, + const std::string & name); + + RCLCPP_PUBLIC + bool + match_serialization_support_( + const DynamicSerializationSupport & serialization_support, + const rosidl_dynamic_typesupport_dynamic_type_builder_t & dynamic_type_builder); +}; + + +} // namespace dynamic_typesupport +} // namespace rclcpp + + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_ diff --git a/rclcpp/include/rclcpp/rclcpp.hpp b/rclcpp/include/rclcpp/rclcpp.hpp index f1d751ff3f..ab4b54a0dd 100644 --- a/rclcpp/include/rclcpp/rclcpp.hpp +++ b/rclcpp/include/rclcpp/rclcpp.hpp @@ -117,6 +117,19 @@ * - Allocator related items: * - rclcpp/allocator/allocator_common.hpp * - rclcpp/allocator/allocator_deleter.hpp + * - Dynamic typesupport wrappers + * - rclcpp::dynamic_typesupport::DynamicData + * - rclcpp::dynamic_typesupport::DynamicMessage + * - rclcpp::dynamic_typesupport::DynamicMessageType + * - rclcpp::dynamic_typesupport::DynamicSerializationSupport + * - rclcpp::dynamic_typesupport::DynamicTypeBuilder + * - rclcpp::dynamic_typesupport::DynamicType + * - rclcpp/dynamic_typesupport/dynamic_data.hpp + * - rclcpp/dynamic_typesupport/dynamic_message.hpp + * - rclcpp/dynamic_typesupport/dynamic_message_type.hpp + * - rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp + * - rclcpp/dynamic_typesupport/dynamic_type_builder.hpp + * - rclcpp/dynamic_typesupport/dynamic_type.hpp * - Generic publisher * - rclcpp::Node::create_generic_publisher() * - rclcpp::GenericPublisher diff --git a/rclcpp/package.xml b/rclcpp/package.xml index 38773e2ec2..f7c89260bc 100644 --- a/rclcpp/package.xml +++ b/rclcpp/package.xml @@ -39,6 +39,7 @@ rcpputils rcutils rmw + rosidl_dynamic_typesupport statistics_msgs tracetools diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp new file mode 100644 index 0000000000..f953e44a80 --- /dev/null +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp @@ -0,0 +1,642 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#include "rclcpp/exceptions.hpp" +#include "rcutils/logging_macros.h" + +#include +#include +#include + +using rclcpp::dynamic_typesupport::DynamicData; +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; +using rclcpp::dynamic_typesupport::DynamicType; +using rclcpp::dynamic_typesupport::DynamicTypeBuilder; + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_ +// Template specialization implementations +#include "rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp" +#endif + + +// CONSTRUCTION ================================================================================== +DynamicData::DynamicData(const DynamicTypeBuilder::SharedPtr dynamic_type_builder) +: serialization_support_(dynamic_type_builder->get_shared_dynamic_serialization_support()), + rosidl_dynamic_data_(nullptr), + is_loaned_(false), + parent_data_(nullptr) +{ + if (!serialization_support_) { + throw std::runtime_error("dynamic type could not bind serialization support!"); + } + + rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = + dynamic_type_builder->get_rosidl_dynamic_type_builder(); + if (!rosidl_dynamic_type_builder) { + throw std::runtime_error("dynamic type builder cannot be nullptr!"); + } + + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; + rosidl_dynamic_data = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type_builder( + rosidl_dynamic_type_builder); + if (!rosidl_dynamic_data) { + throw std::runtime_error("could not create new dynamic data object"); + } + + rosidl_dynamic_data_.reset( + rosidl_dynamic_data, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { + rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); + free(rosidl_dynamic_data); + }); +} + + +DynamicData::DynamicData(const DynamicType::SharedPtr dynamic_type) +: serialization_support_(dynamic_type->get_shared_dynamic_serialization_support()), + rosidl_dynamic_data_(nullptr), + is_loaned_(false), + parent_data_(nullptr) +{ + if (!serialization_support_) { + throw std::runtime_error("dynamic type could not bind serialization support!"); + } + + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type = + dynamic_type->get_rosidl_dynamic_type(); + if (!rosidl_dynamic_type) { + throw std::runtime_error("dynamic type cannot be nullptr!"); + } + + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; + rosidl_dynamic_data = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type( + rosidl_dynamic_type); + if (!rosidl_dynamic_data) { + throw std::runtime_error("could not create new dynamic data object"); + } + + rosidl_dynamic_data_.reset( + rosidl_dynamic_data, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { + rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); + free(rosidl_dynamic_data); + }); +} + + +DynamicData::DynamicData( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data) +: serialization_support_(serialization_support), + rosidl_dynamic_data_(nullptr), + is_loaned_(false), + parent_data_(nullptr) +{ + if (!rosidl_dynamic_data) { + throw std::runtime_error("rosidl dynamic data cannot be nullptr!"); + } + if (serialization_support) { + if (!match_serialization_support_(*serialization_support, *rosidl_dynamic_data)) { + throw std::runtime_error( + "serialization support library identifier does not match dynamic data's!"); + } + } + + rosidl_dynamic_data_.reset( + rosidl_dynamic_data, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { + rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); + free(rosidl_dynamic_data); + }); +} + + +DynamicData::DynamicData( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_data) +: serialization_support_(serialization_support), + rosidl_dynamic_data_(rosidl_dynamic_data), + is_loaned_(false), + parent_data_(nullptr) +{ + if (!rosidl_dynamic_data) { + throw std::runtime_error("rosidl dynamic data cannot be nullptr!"); + } + if (serialization_support) { + if (!match_serialization_support_(*serialization_support, *rosidl_dynamic_data)) { + throw std::runtime_error( + "serialization support library identifier does not match dynamic data's!"); + } + } +} + + +DynamicData::DynamicData( + DynamicData::SharedPtr parent_data, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data) +: DynamicData(parent_data->get_shared_dynamic_serialization_support(), rosidl_loaned_data) +{ + if (!parent_data) { + throw std::runtime_error("parent dynamic data cannot be nullptr!"); + } + if (!rosidl_loaned_data) { + throw std::runtime_error("loaned rosidl dynamic data cannot be nullptr!"); + } + + parent_data_ = parent_data; + is_loaned_ = true; +} + + +DynamicData::DynamicData(const DynamicData & other) +: enable_shared_from_this(), + serialization_support_(nullptr), + rosidl_dynamic_data_(nullptr), + is_loaned_(false), + parent_data_(nullptr) +{ + DynamicData out = other.clone(); + // We don't copy is_loaned_ or parent_data_ because it's a fresh copy now + std::swap(serialization_support_, out.serialization_support_); + std::swap(rosidl_dynamic_data_, out.rosidl_dynamic_data_); +} + + +DynamicData::DynamicData(DynamicData && other) noexcept +: serialization_support_(std::exchange(other.serialization_support_, nullptr)), + rosidl_dynamic_data_(std::exchange(other.rosidl_dynamic_data_, nullptr)), + is_loaned_(other.is_loaned_), + parent_data_(std::exchange(other.parent_data_, nullptr)) +{} + + +DynamicData & +DynamicData::operator=(const DynamicData & other) +{ + return *this = DynamicData(other); +} + + +DynamicData & +DynamicData::operator=(DynamicData && other) noexcept +{ + std::swap(serialization_support_, other.serialization_support_); + std::swap(rosidl_dynamic_data_, other.rosidl_dynamic_data_); + is_loaned_ = other.is_loaned_; + std::swap(parent_data_, other.parent_data_); + return *this; +} + + +DynamicData::~DynamicData() +{ + if (is_loaned_) { + if (!parent_data_) { + RCUTILS_LOG_ERROR("dynamic data is loaned, but parent is missing!!"); + } else { + rosidl_dynamic_typesupport_dynamic_data_return_loaned_value( + parent_data_->get_rosidl_dynamic_data(), get_rosidl_dynamic_data()); + } + } +} + + +bool +DynamicData::match_serialization_support_( + const DynamicSerializationSupport & serialization_support, + const rosidl_dynamic_typesupport_dynamic_data_t & rosidl_dynamic_type_data) +{ + bool out = true; + + if (serialization_support.get_library_identifier() != std::string( + rosidl_dynamic_type_data.serialization_support->library_identifier)) + { + RCUTILS_LOG_ERROR("serialization support library identifier does not match dynamic data's"); + out = false; + } + + // TODO(methylDragon): Can I do this?? Is it portable? + if (serialization_support.get_rosidl_serialization_support() != + rosidl_dynamic_type_data.serialization_support) + { + RCUTILS_LOG_ERROR("serialization support pointer does not match dynamic data's"); + out = false; + } + + return out; +} + + +// GETTERS ======================================================================================= +const std::string +DynamicData::get_library_identifier() const +{ + return std::string(rosidl_dynamic_data_->serialization_support->library_identifier); +} + + +const std::string +DynamicData::get_name() const +{ + size_t buf_length; + const char * buf = rosidl_dynamic_typesupport_dynamic_data_get_name( + get_rosidl_dynamic_data(), &buf_length); + return std::string(buf, buf_length); +} + + +rosidl_dynamic_typesupport_dynamic_data_t * +DynamicData::get_rosidl_dynamic_data() +{ + return rosidl_dynamic_data_.get(); +} + + +const rosidl_dynamic_typesupport_dynamic_data_t * +DynamicData::get_rosidl_dynamic_data() const +{ + return rosidl_dynamic_data_.get(); +} + + +std::shared_ptr +DynamicData::get_shared_rosidl_dynamic_data() +{ + return std::shared_ptr( + shared_from_this(), rosidl_dynamic_data_.get()); +} + + +std::shared_ptr +DynamicData::get_shared_rosidl_dynamic_data() const +{ + return std::shared_ptr( + shared_from_this(), rosidl_dynamic_data_.get()); +} + + +DynamicSerializationSupport::SharedPtr +DynamicData::get_shared_dynamic_serialization_support() +{ + return serialization_support_; +} + + +std::shared_ptr +DynamicData::get_shared_dynamic_serialization_support() const +{ + return serialization_support_; +} + + +size_t +DynamicData::get_item_count() const +{ + return rosidl_dynamic_typesupport_dynamic_data_get_item_count(get_rosidl_dynamic_data()); +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::get_member_id(size_t index) const +{ + return rosidl_dynamic_typesupport_dynamic_data_get_member_id_at_index( + get_rosidl_dynamic_data(), index); +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::get_member_id(const std::string & name) const +{ + return rosidl_dynamic_typesupport_dynamic_data_get_member_id_by_name( + get_rosidl_dynamic_data(), name.c_str(), name.size()); +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::get_array_index(size_t index) const +{ + return rosidl_dynamic_typesupport_dynamic_data_get_array_index( + get_rosidl_dynamic_data(), index); +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::get_array_index(const std::string & name) const +{ + return get_array_index(get_member_id(name)); +} + + +// METHODS ======================================================================================= +DynamicData +DynamicData::clone() const +{ + return DynamicData( + serialization_support_, + rosidl_dynamic_typesupport_dynamic_data_clone(get_rosidl_dynamic_data())); +} + + +DynamicData::SharedPtr +DynamicData::clone_shared() const +{ + return DynamicData::make_shared( + serialization_support_, + rosidl_dynamic_typesupport_dynamic_data_clone(get_rosidl_dynamic_data())); +} + + +bool +DynamicData::equals(const DynamicData & other) const +{ + if (get_library_identifier() != other.get_library_identifier()) { + throw std::runtime_error("library identifiers don't match"); + } + return rosidl_dynamic_typesupport_dynamic_data_equals( + get_rosidl_dynamic_data(), other.get_rosidl_dynamic_data()); +} + + +DynamicData::SharedPtr +DynamicData::loan_value(rosidl_dynamic_typesupport_member_id_t id) +{ + return DynamicData::make_shared( + shared_from_this(), + rosidl_dynamic_typesupport_dynamic_data_loan_value( + get_rosidl_dynamic_data(), id)); +} + + +DynamicData::SharedPtr +DynamicData::loan_value(const std::string & name) +{ + return loan_value(get_member_id(name)); +} + + +void +DynamicData::clear_all_values() +{ + rosidl_dynamic_typesupport_dynamic_data_clear_all_values(get_rosidl_dynamic_data()); +} + + +void +DynamicData::clear_nonkey_values() +{ + rosidl_dynamic_typesupport_dynamic_data_clear_nonkey_values(get_rosidl_dynamic_data()); +} + + +void +DynamicData::clear_value(rosidl_dynamic_typesupport_member_id_t id) +{ + rosidl_dynamic_typesupport_dynamic_data_clear_value(get_rosidl_dynamic_data(), id); +} + + +void +DynamicData::clear_value(const std::string & name) +{ + clear_value(get_member_id(name)); +} + + +void +DynamicData::clear_sequence() +{ + rosidl_dynamic_typesupport_dynamic_data_clear_sequence_data(get_rosidl_dynamic_data()); +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_sequence_data() +{ + rosidl_dynamic_typesupport_member_id_t out; + rosidl_dynamic_typesupport_dynamic_data_insert_sequence_data(get_rosidl_dynamic_data(), &out); + return out; +} + + +void +DynamicData::remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index) +{ + rosidl_dynamic_typesupport_dynamic_data_remove_sequence_data( + get_rosidl_dynamic_data(), index); +} + + +void +DynamicData::print() const +{ + rosidl_dynamic_typesupport_dynamic_data_print(get_rosidl_dynamic_data()); +} + + +bool +DynamicData::serialize(std::shared_ptr buffer) +{ + return rosidl_dynamic_typesupport_dynamic_data_serialize( + get_rosidl_dynamic_data(), buffer.get()); +} + + +bool +DynamicData::deserialize(std::shared_ptr buffer) +{ + return rosidl_dynamic_typesupport_dynamic_data_deserialize( + get_rosidl_dynamic_data(), buffer.get()); +} + + +// MEMBER ACCESS =================================================================================== +// Defined in "detail/dynamic_data_impl.hpp" + + +// BOUNDED STRING MEMBER ACCESS ==================================================================== +const std::string +DynamicData::get_bounded_string_value( + rosidl_dynamic_typesupport_member_id_t id, size_t string_bound) +{ + size_t buf_length; + char * buf = nullptr; + rosidl_dynamic_typesupport_dynamic_data_get_bounded_string_value( + get_rosidl_dynamic_data(), id, &buf, &buf_length, string_bound); + auto out = std::string(buf, buf_length); + free(buf); + return out; +} + + +const std::string +DynamicData::get_bounded_string_value(const std::string & name, size_t string_bound) +{ + return get_bounded_string_value(get_member_id(name), string_bound); +} + + +const std::u16string +DynamicData::get_bounded_wstring_value( + rosidl_dynamic_typesupport_member_id_t id, size_t wstring_bound) +{ + size_t buf_length; + char16_t * buf = nullptr; + rosidl_dynamic_typesupport_dynamic_data_get_bounded_wstring_value( + get_rosidl_dynamic_data(), id, &buf, &buf_length, wstring_bound); + auto out = std::u16string(buf, buf_length); + free(buf); + return out; +} + + +const std::u16string +DynamicData::get_bounded_wstring_value(const std::string & name, size_t wstring_bound) +{ + return get_bounded_wstring_value(get_member_id(name), wstring_bound); +} + + +void +DynamicData::set_bounded_string_value( + rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_bound) +{ + rosidl_dynamic_typesupport_dynamic_data_set_bounded_string_value( + get_rosidl_dynamic_data(), id, value.c_str(), value.size(), string_bound); +} + + +void +DynamicData::set_bounded_string_value( + const std::string & name, const std::string value, size_t string_bound) +{ + set_bounded_string_value(get_member_id(name), value, string_bound); +} + + +void +DynamicData::set_bounded_wstring_value( + rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_bound) +{ + rosidl_dynamic_typesupport_dynamic_data_set_bounded_wstring_value( + get_rosidl_dynamic_data(), id, value.c_str(), value.size(), wstring_bound); +} + + +void +DynamicData::set_bounded_wstring_value( + const std::string & name, const std::u16string value, size_t wstring_bound) +{ + set_bounded_wstring_value(get_member_id(name), value, wstring_bound); +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_bounded_string_value(const std::string value, size_t string_bound) +{ + rosidl_dynamic_typesupport_member_id_t out; + rosidl_dynamic_typesupport_dynamic_data_insert_bounded_string_value( + get_rosidl_dynamic_data(), value.c_str(), value.size(), string_bound, &out); + return out; +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_bounded_wstring_value(const std::u16string value, size_t wstring_bound) +{ + rosidl_dynamic_typesupport_member_id_t out; + rosidl_dynamic_typesupport_dynamic_data_insert_bounded_wstring_value( + get_rosidl_dynamic_data(), value.c_str(), value.size(), wstring_bound, &out); + return out; +} + + +// NESTED MEMBER ACCESS ============================================================================ +DynamicData +DynamicData::get_complex_value(rosidl_dynamic_typesupport_member_id_t id) +{ + rosidl_dynamic_typesupport_dynamic_data_t * out_ptr = nullptr; + rosidl_dynamic_typesupport_dynamic_data_get_complex_value( + get_rosidl_dynamic_data(), id, &out_ptr); + return DynamicData(get_shared_dynamic_serialization_support(), out_ptr); +} + + +DynamicData +DynamicData::get_complex_value(const std::string & name) +{ + return get_complex_value(get_member_id(name)); +} + + +DynamicData::SharedPtr +DynamicData::get_complex_value_shared(rosidl_dynamic_typesupport_member_id_t id) +{ + rosidl_dynamic_typesupport_dynamic_data_t * out_ptr = nullptr; + rosidl_dynamic_typesupport_dynamic_data_get_complex_value( + get_rosidl_dynamic_data(), id, &out_ptr); + return DynamicData::make_shared(get_shared_dynamic_serialization_support(), out_ptr); +} + + +DynamicData::SharedPtr +DynamicData::get_complex_value_shared(const std::string & name) +{ + return get_complex_value_shared(get_member_id(name)); +} + + +void +DynamicData::set_complex_value( + rosidl_dynamic_typesupport_member_id_t id, DynamicData & value) +{ + rosidl_dynamic_typesupport_dynamic_data_set_complex_value( + get_rosidl_dynamic_data(), id, value.get_rosidl_dynamic_data()); +} + + +void +DynamicData::set_complex_value(const std::string & name, DynamicData & value) +{ + set_complex_value(get_member_id(name), value); +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_complex_value_copy(const DynamicData & value) +{ + rosidl_dynamic_typesupport_member_id_t out; + rosidl_dynamic_typesupport_dynamic_data_insert_complex_value_copy( + get_rosidl_dynamic_data(), value.get_rosidl_dynamic_data(), &out); + return out; +} + + +rosidl_dynamic_typesupport_member_id_t +DynamicData::insert_complex_value(DynamicData & value) +{ + rosidl_dynamic_typesupport_member_id_t out; + rosidl_dynamic_typesupport_dynamic_data_insert_complex_value( + get_rosidl_dynamic_data(), value.get_rosidl_dynamic_data(), &out); + return out; +} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp new file mode 100644 index 0000000000..550517a852 --- /dev/null +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp @@ -0,0 +1,61 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" + +#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#include "rclcpp/exceptions.hpp" +#include "rcutils/logging_macros.h" + +#include +#include +#include + +using rclcpp::dynamic_typesupport::DynamicMessage; +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; +using rclcpp::dynamic_typesupport::DynamicType; +using rclcpp::dynamic_typesupport::DynamicTypeBuilder; + + +// CONSTRUCTION ================================================================================== +DynamicMessage::DynamicMessage(const DynamicTypeBuilder::SharedPtr dynamic_type_builder) +: DynamicData(dynamic_type_builder) {} + + +DynamicMessage::DynamicMessage(const DynamicType::SharedPtr dynamic_type) +: DynamicData(dynamic_type) {} + + +DynamicMessage::DynamicMessage( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data) +: DynamicData(serialization_support, rosidl_dynamic_data) {} + + +DynamicMessage::DynamicMessage( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_data) +: DynamicData(serialization_support, rosidl_dynamic_data) {} + + +DynamicMessage::DynamicMessage( + DynamicData::SharedPtr parent_data, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data) +: DynamicData(parent_data, rosidl_loaned_data) {} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp new file mode 100644 index 0000000000..3f6858fea5 --- /dev/null +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp @@ -0,0 +1,57 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" + +#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#include "rclcpp/exceptions.hpp" +#include "rcutils/logging_macros.h" + +#include +#include +#include + +using rclcpp::dynamic_typesupport::DynamicMessageType; +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; +using rclcpp::dynamic_typesupport::DynamicType; +using rclcpp::dynamic_typesupport::DynamicTypeBuilder; + + +// CONSTRUCTION ==================================================================================== +DynamicMessageType::DynamicMessageType(DynamicTypeBuilder::SharedPtr dynamic_type_builder) +: DynamicType(dynamic_type_builder) {} + + +DynamicMessageType::DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type) +: DynamicType(serialization_support, rosidl_dynamic_type) {} + + +DynamicMessageType::DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_type) +: DynamicType(serialization_support, rosidl_dynamic_type) {} + + +DynamicMessageType::DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description) +: DynamicType(serialization_support, description) {} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp new file mode 100644 index 0000000000..4c7d90ebde --- /dev/null +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp @@ -0,0 +1,131 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/exceptions.hpp" +#include "rcutils/logging_macros.h" +#include "rmw/dynamic_typesupport.h" + +#include + +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; + +// CONSTRUCTION ==================================================================================== +DynamicSerializationSupport::DynamicSerializationSupport( + const std::string & serialization_library_name) +: rosidl_serialization_support_(nullptr) +{ + rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support = nullptr; + + if (serialization_library_name.empty()) { + rosidl_serialization_support = rmw_get_serialization_support(NULL); + } else { + rosidl_serialization_support = + rmw_get_serialization_support(serialization_library_name.c_str()); + } + + if (!rosidl_serialization_support) { + throw std::runtime_error("could not create new serialization support object"); + } + + rosidl_serialization_support_.reset( + rosidl_serialization_support, + // Custom deleter + [](rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support) -> void { + rosidl_dynamic_typesupport_serialization_support_fini(rosidl_serialization_support); + free(rosidl_serialization_support); + }); +} + + +DynamicSerializationSupport::DynamicSerializationSupport( + rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support) +: rosidl_serialization_support_(nullptr) +{ + if (!rosidl_serialization_support) { + throw std::runtime_error("serialization support cannot be nullptr!"); + } + + // Custom deleter + rosidl_serialization_support_.reset( + rosidl_serialization_support, + [](rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support) -> void { + rosidl_dynamic_typesupport_serialization_support_fini(rosidl_serialization_support); + free(rosidl_serialization_support); + }); +} + + +DynamicSerializationSupport::DynamicSerializationSupport( + std::shared_ptr rosidl_serialization_support) +: rosidl_serialization_support_(rosidl_serialization_support) {} + + +DynamicSerializationSupport::DynamicSerializationSupport( + DynamicSerializationSupport && other) noexcept +: rosidl_serialization_support_(std::exchange(other.rosidl_serialization_support_, nullptr)) {} + + +DynamicSerializationSupport & +DynamicSerializationSupport::operator=(DynamicSerializationSupport && other) noexcept +{ + std::swap(rosidl_serialization_support_, other.rosidl_serialization_support_); + return *this; +} + + +DynamicSerializationSupport::~DynamicSerializationSupport() {} + + +// GETTERS ========================================================================================= +const std::string +DynamicSerializationSupport::get_library_identifier() const +{ + return std::string( + rosidl_dynamic_typesupport_serialization_support_get_library_identifier( + rosidl_serialization_support_.get())); +} + + +rosidl_dynamic_typesupport_serialization_support_t * +DynamicSerializationSupport::get_rosidl_serialization_support() +{ + return rosidl_serialization_support_.get(); +} + + +const rosidl_dynamic_typesupport_serialization_support_t * +DynamicSerializationSupport::get_rosidl_serialization_support() const +{ + return rosidl_serialization_support_.get(); +} + + +std::shared_ptr +DynamicSerializationSupport::get_shared_rosidl_serialization_support() +{ + return std::shared_ptr( + shared_from_this(), rosidl_serialization_support_.get()); +} + + +std::shared_ptr +DynamicSerializationSupport::get_shared_rosidl_serialization_support() const +{ + return std::shared_ptr( + shared_from_this(), rosidl_serialization_support_.get()); +} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp new file mode 100644 index 0000000000..8590722edc --- /dev/null +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp @@ -0,0 +1,320 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#include "rclcpp/exceptions.hpp" +#include "rcutils/logging_macros.h" + +#include +#include +#include + +using rclcpp::dynamic_typesupport::DynamicData; +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; +using rclcpp::dynamic_typesupport::DynamicType; +using rclcpp::dynamic_typesupport::DynamicTypeBuilder; + + +// CONSTRUCTION ==================================================================================== +DynamicType::DynamicType(DynamicTypeBuilder::SharedPtr dynamic_type_builder) +: serialization_support_(dynamic_type_builder->get_shared_dynamic_serialization_support()), + rosidl_dynamic_type_(nullptr) +{ + if (!serialization_support_) { + throw std::runtime_error("dynamic type could not bind serialization support!"); + } + + rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = + dynamic_type_builder->get_rosidl_dynamic_type_builder(); + if (!rosidl_dynamic_type_builder) { + throw std::runtime_error("dynamic type builder cannot be nullptr!"); + } + + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type = nullptr; + rosidl_dynamic_type = rosidl_dynamic_typesupport_dynamic_type_init_from_dynamic_type_builder( + rosidl_dynamic_type_builder); + if (!rosidl_dynamic_type) { + throw std::runtime_error("could not create new dynamic type object"); + } + + rosidl_dynamic_type_.reset( + rosidl_dynamic_type, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { + rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); + free(rosidl_dynamic_type); + }); +} + + +DynamicType::DynamicType( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type) +: serialization_support_(serialization_support), rosidl_dynamic_type_(nullptr) +{ + if (!rosidl_dynamic_type) { + throw std::runtime_error("rosidl dynamic type cannot be nullptr!"); + } + if (serialization_support) { + if (!match_serialization_support_(*serialization_support, *rosidl_dynamic_type)) { + throw std::runtime_error( + "serialization support library identifier does not match dynamic type's!"); + } + } + + rosidl_dynamic_type_.reset( + rosidl_dynamic_type, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { + rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); + free(rosidl_dynamic_type); + }); +} + + +DynamicType::DynamicType( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_type) +: serialization_support_(serialization_support), rosidl_dynamic_type_(rosidl_dynamic_type) +{ + if (!rosidl_dynamic_type) { + throw std::runtime_error("rosidl dynamic type cannot be nullptr!"); + } + if (serialization_support) { + if (!match_serialization_support_(*serialization_support, *rosidl_dynamic_type)) { + throw std::runtime_error( + "serialization support library identifier does not match dynamic type's!"); + } + } +} + + +DynamicType::DynamicType( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description) +: serialization_support_(serialization_support), rosidl_dynamic_type_(nullptr) +{ + init_from_description(description, serialization_support); +} + + +DynamicType::DynamicType(const DynamicType & other) +: enable_shared_from_this(), serialization_support_(nullptr), rosidl_dynamic_type_(nullptr) +{ + DynamicType out = other.clone(); + std::swap(serialization_support_, out.serialization_support_); + std::swap(rosidl_dynamic_type_, out.rosidl_dynamic_type_); +} + + +DynamicType::DynamicType(DynamicType && other) noexcept +: serialization_support_(std::exchange(other.serialization_support_, nullptr)), + rosidl_dynamic_type_(std::exchange(other.rosidl_dynamic_type_, nullptr)) {} + + +DynamicType & +DynamicType::operator=(const DynamicType & other) +{ + return *this = DynamicType(other); +} + + +DynamicType & +DynamicType::operator=(DynamicType && other) noexcept +{ + std::swap(serialization_support_, other.serialization_support_); + std::swap(rosidl_dynamic_type_, other.rosidl_dynamic_type_); + return *this; +} + + +DynamicType::~DynamicType() {} + + +void +DynamicType::init_from_description( + const rosidl_runtime_c__type_description__TypeDescription * description, + DynamicSerializationSupport::SharedPtr serialization_support) +{ + if (!description) { + throw std::runtime_error("description cannot be nullptr!"); + } + if (serialization_support) { + // Swap serialization support if serialization support is given + serialization_support_ = serialization_support; + } + + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type = nullptr; + rosidl_dynamic_type = + rosidl_dynamic_typesupport_dynamic_type_init_from_description( + serialization_support_->get_rosidl_serialization_support(), description); + if (!rosidl_dynamic_type) { + throw std::runtime_error("could not create new dynamic type object"); + } + + rosidl_dynamic_type_.reset( + rosidl_dynamic_type, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { + rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); + free(rosidl_dynamic_type); + }); +} + + +bool +DynamicType::match_serialization_support_( + const DynamicSerializationSupport & serialization_support, + const rosidl_dynamic_typesupport_dynamic_type_t & rosidl_dynamic_type) +{ + bool out = true; + + if (serialization_support.get_library_identifier() != std::string( + rosidl_dynamic_type.serialization_support->library_identifier)) + { + RCUTILS_LOG_ERROR( + "serialization support library identifier does not match dynamic type's"); + out = false; + } + + // TODO(methylDragon): Can I do this?? Is it portable? + if (serialization_support.get_rosidl_serialization_support() != + rosidl_dynamic_type.serialization_support) + { + RCUTILS_LOG_ERROR( + "serialization support pointer does not match dynamic type's"); + out = false; + } + + return out; +} + + +// GETTERS ========================================================================================= +const std::string +DynamicType::get_library_identifier() const +{ + return std::string(rosidl_dynamic_type_->serialization_support->library_identifier); +} + + +const std::string +DynamicType::get_name() const +{ + size_t buf_length; + const char * buf = rosidl_dynamic_typesupport_dynamic_type_get_name( + get_rosidl_dynamic_type(), &buf_length); + return std::string(buf, buf_length); +} + + +size_t +DynamicType::get_member_count() const +{ + return rosidl_dynamic_typesupport_dynamic_type_get_member_count(rosidl_dynamic_type_.get()); +} + + +rosidl_dynamic_typesupport_dynamic_type_t * +DynamicType::get_rosidl_dynamic_type() +{ + return rosidl_dynamic_type_.get(); +} + + +const rosidl_dynamic_typesupport_dynamic_type_t * +DynamicType::get_rosidl_dynamic_type() const +{ + return rosidl_dynamic_type_.get(); +} + + +std::shared_ptr +DynamicType::get_shared_rosidl_dynamic_type() +{ + return std::shared_ptr( + shared_from_this(), rosidl_dynamic_type_.get()); +} + + +std::shared_ptr +DynamicType::get_shared_rosidl_dynamic_type() const +{ + return std::shared_ptr( + shared_from_this(), rosidl_dynamic_type_.get()); +} + + +DynamicSerializationSupport::SharedPtr +DynamicType::get_shared_dynamic_serialization_support() +{ + return serialization_support_; +} + + +std::shared_ptr +DynamicType::get_shared_dynamic_serialization_support() const +{ + return serialization_support_; +} + + +// METHODS ========================================================================================= +DynamicType +DynamicType::clone() const +{ + return DynamicType( + serialization_support_, + rosidl_dynamic_typesupport_dynamic_type_clone(get_rosidl_dynamic_type())); +} + + +DynamicType::SharedPtr +DynamicType::clone_shared() const +{ + return DynamicType::make_shared( + serialization_support_, + rosidl_dynamic_typesupport_dynamic_type_clone(get_rosidl_dynamic_type())); +} + + +bool +DynamicType::equals(const DynamicType & other) const +{ + if (get_library_identifier() != other.get_library_identifier()) { + throw std::runtime_error("library identifiers don't match"); + } + return rosidl_dynamic_typesupport_dynamic_type_equals( + get_rosidl_dynamic_type(), other.get_rosidl_dynamic_type()); +} + + +DynamicData +DynamicType::build_data() +{ + return DynamicData(shared_from_this()); +} + + +DynamicData::SharedPtr +DynamicType::build_data_shared() +{ + return DynamicData::make_shared(shared_from_this()); +} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp new file mode 100644 index 0000000000..18d23625a1 --- /dev/null +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp @@ -0,0 +1,492 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#include "rclcpp/exceptions.hpp" +#include "rcutils/logging_macros.h" + +#include +#include +#include + +using rclcpp::dynamic_typesupport::DynamicData; +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; +using rclcpp::dynamic_typesupport::DynamicType; +using rclcpp::dynamic_typesupport::DynamicTypeBuilder; + + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_TYPE_BUILDER_IMPL_HPP_ +// Template specialization implementations +#include "rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp" +#endif + + +// CONSTRUCTION ================================================================================== +DynamicTypeBuilder::DynamicTypeBuilder( + DynamicSerializationSupport::SharedPtr serialization_support, const std::string & name) +: serialization_support_(serialization_support), rosidl_dynamic_type_builder_(nullptr) +{ + init_from_serialization_support_(serialization_support, name); + if (!rosidl_dynamic_type_builder_) { + throw std::runtime_error("could not create new dynamic type builder object"); + } +} + + +DynamicTypeBuilder::DynamicTypeBuilder( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder) +: serialization_support_(serialization_support), rosidl_dynamic_type_builder_(nullptr) +{ + if (!serialization_support) { + throw std::runtime_error("serialization support cannot be nullptr!"); + } + if (!rosidl_dynamic_type_builder) { + throw std::runtime_error("rosidl dynamic type builder cannot be nullptr!"); + } + if (!match_serialization_support_(*serialization_support, *rosidl_dynamic_type_builder)) { + throw std::runtime_error( + "serialization support library does not match dynamic type builder's!"); + } + + rosidl_dynamic_type_builder_.reset( + rosidl_dynamic_type_builder, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { + rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); + free(rosidl_dynamic_type_builder); + }); +} + + +DynamicTypeBuilder::DynamicTypeBuilder( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_type_builder) +: serialization_support_(serialization_support), + rosidl_dynamic_type_builder_(rosidl_dynamic_type_builder) +{ + if (!serialization_support) { + throw std::runtime_error("serialization support cannot be nullptr!"); + } + if (!rosidl_dynamic_type_builder) { + throw std::runtime_error("rosidl dynamic type builder cannot be nullptr!"); + } + if (!match_serialization_support_(*serialization_support, *rosidl_dynamic_type_builder.get())) { + throw std::runtime_error( + "serialization support library does not match dynamic type builder's!"); + } +} + + +DynamicTypeBuilder::DynamicTypeBuilder( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description) +: serialization_support_(serialization_support), + rosidl_dynamic_type_builder_(nullptr) +{ + if (!serialization_support) { + throw std::runtime_error("serialization support cannot be nullptr!"); + } + init_from_description(description, serialization_support); +} + + +DynamicTypeBuilder::DynamicTypeBuilder(const DynamicTypeBuilder & other) +: enable_shared_from_this(), serialization_support_(nullptr), rosidl_dynamic_type_builder_(nullptr) +{ + DynamicTypeBuilder out = other.clone(); + std::swap(serialization_support_, out.serialization_support_); + std::swap(rosidl_dynamic_type_builder_, out.rosidl_dynamic_type_builder_); +} + + +DynamicTypeBuilder::DynamicTypeBuilder(DynamicTypeBuilder && other) noexcept +: serialization_support_(std::exchange(other.serialization_support_, nullptr)), + rosidl_dynamic_type_builder_(std::exchange(other.rosidl_dynamic_type_builder_, nullptr)) {} + + +DynamicTypeBuilder & +DynamicTypeBuilder::operator=(const DynamicTypeBuilder & other) +{ + return *this = DynamicTypeBuilder(other); +} + + +DynamicTypeBuilder & +DynamicTypeBuilder::operator=(DynamicTypeBuilder && other) noexcept +{ + std::swap(serialization_support_, other.serialization_support_); + std::swap(rosidl_dynamic_type_builder_, other.rosidl_dynamic_type_builder_); + return *this; +} + + +DynamicTypeBuilder::~DynamicTypeBuilder() {} + + +void +DynamicTypeBuilder::init_from_description( + const rosidl_runtime_c__type_description__TypeDescription * description, + DynamicSerializationSupport::SharedPtr serialization_support) +{ + if (!description) { + throw std::runtime_error("description cannot be nullptr!"); + } + if (serialization_support) { + // Swap serialization support if serialization support is given + serialization_support_ = serialization_support; + } + + rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; + rosidl_dynamic_type_builder = + rosidl_dynamic_typesupport_dynamic_type_builder_init_from_description( + serialization_support_->get_rosidl_serialization_support(), description); + if (!rosidl_dynamic_type_builder) { + throw std::runtime_error("could not create new dynamic type builder object"); + } + + rosidl_dynamic_type_builder_.reset( + rosidl_dynamic_type_builder, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { + rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); + free(rosidl_dynamic_type_builder); + }); +} + + +void +DynamicTypeBuilder::init_from_serialization_support_( + DynamicSerializationSupport::SharedPtr serialization_support, + const std::string & name) +{ + if (!serialization_support) { + throw std::runtime_error("serialization support cannot be nullptr!"); + } + if (!serialization_support->get_rosidl_serialization_support()) { + throw std::runtime_error("serialization support raw pointer cannot be nullptr!"); + } + + + rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; + rosidl_dynamic_type_builder = rosidl_dynamic_typesupport_dynamic_type_builder_init( + serialization_support->get_rosidl_serialization_support(), name.c_str(), name.size()); + + if (!rosidl_dynamic_type_builder) { + throw std::runtime_error("could not create new dynamic type builder object"); + } + + rosidl_dynamic_type_builder_.reset( + rosidl_dynamic_type_builder, + // Custom deleter + [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { + rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); + free(rosidl_dynamic_type_builder); + }); +} + + +bool +DynamicTypeBuilder::match_serialization_support_( + const DynamicSerializationSupport & serialization_support, + const rosidl_dynamic_typesupport_dynamic_type_builder_t & rosidl_dynamic_type_builder) +{ + bool out = true; + + if (serialization_support.get_library_identifier() != std::string( + rosidl_dynamic_type_builder.serialization_support->library_identifier)) + { + RCUTILS_LOG_ERROR( + "serialization support library identifier does not match dynamic type builder's"); + out = false; + } + + // TODO(methylDragon): Can I do this?? Is it portable? + if (serialization_support.get_rosidl_serialization_support() != + rosidl_dynamic_type_builder.serialization_support) + { + RCUTILS_LOG_ERROR( + "serialization support pointer does not match dynamic type builder's"); + out = false; + } + + return out; +} + + +// GETTERS ======================================================================================= +const std::string +DynamicTypeBuilder::get_library_identifier() const +{ + return std::string(rosidl_dynamic_type_builder_->serialization_support->library_identifier); +} + + +const std::string +DynamicTypeBuilder::get_name() const +{ + size_t buf_length; + const char * buf = rosidl_dynamic_typesupport_dynamic_type_builder_get_name( + get_rosidl_dynamic_type_builder(), &buf_length); + return std::string(buf, buf_length); +} + + +rosidl_dynamic_typesupport_dynamic_type_builder_t * +DynamicTypeBuilder::get_rosidl_dynamic_type_builder() +{ + return rosidl_dynamic_type_builder_.get(); +} + + +const rosidl_dynamic_typesupport_dynamic_type_builder_t * +DynamicTypeBuilder::get_rosidl_dynamic_type_builder() const +{ + return rosidl_dynamic_type_builder_.get(); +} + + +std::shared_ptr +DynamicTypeBuilder::get_shared_rosidl_dynamic_type_builder() +{ + return std::shared_ptr( + shared_from_this(), rosidl_dynamic_type_builder_.get()); +} + + +std::shared_ptr +DynamicTypeBuilder::get_shared_rosidl_dynamic_type_builder() const +{ + return std::shared_ptr( + shared_from_this(), rosidl_dynamic_type_builder_.get()); +} + + +DynamicSerializationSupport::SharedPtr +DynamicTypeBuilder::get_shared_dynamic_serialization_support() +{ + return serialization_support_; +} + + +std::shared_ptr +DynamicTypeBuilder::get_shared_dynamic_serialization_support() const +{ + return serialization_support_; +} + + +// METHODS ======================================================================================= +void +DynamicTypeBuilder::set_name(const std::string & name) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_set_name( + get_rosidl_dynamic_type_builder(), name.c_str(), name.size()); +} + + +DynamicTypeBuilder +DynamicTypeBuilder::clone() const +{ + return DynamicTypeBuilder( + serialization_support_, + rosidl_dynamic_typesupport_dynamic_type_builder_clone(get_rosidl_dynamic_type_builder())); +} + + +DynamicTypeBuilder::SharedPtr +DynamicTypeBuilder::clone_shared() const +{ + return DynamicTypeBuilder::make_shared( + serialization_support_, + rosidl_dynamic_typesupport_dynamic_type_builder_clone(get_rosidl_dynamic_type_builder())); +} + + +void +DynamicTypeBuilder::clear() +{ + if (!serialization_support_) { + throw std::runtime_error( + "cannot call clear() on a dynamic type builder with uninitialized serialization support"); + } + + const std::string & name = get_name(); + init_from_serialization_support_(serialization_support_, name); + if (!rosidl_dynamic_type_builder_) { + throw std::runtime_error("could not create new dynamic type builder object"); + } +} + + +DynamicData +DynamicTypeBuilder::build_data() +{ + return DynamicData(shared_from_this()); +} + + +DynamicData::SharedPtr +DynamicTypeBuilder::build_data_shared() +{ + return DynamicData::make_shared(shared_from_this()); +} + + +DynamicType +DynamicTypeBuilder::build_type() +{ + return DynamicType(shared_from_this()); +} + + +DynamicType::SharedPtr +DynamicTypeBuilder::build_type_shared() +{ + return DynamicType::make_shared(shared_from_this()); +} + + +// ADD MEMBERS ===================================================================================== +// Defined in "detail/dynamic_type_builder_impl.hpp" + + +// ADD BOUNDED STRING MEMBERS ====================================================================== +void +DynamicTypeBuilder::add_bounded_string_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_string_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), string_bound); +} + + +void +DynamicTypeBuilder::add_bounded_wstring_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_wstring_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), wstring_bound); +} + + +void +DynamicTypeBuilder::add_bounded_string_array_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + size_t string_bound, size_t array_length) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_string_array_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), string_bound, array_length); +} + + +void +DynamicTypeBuilder::add_bounded_wstring_array_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + size_t wstring_bound, size_t array_length) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_wstring_array_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), wstring_bound, array_length); +} + + +void +DynamicTypeBuilder::add_bounded_string_unbounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_string_unbounded_sequence_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), string_bound); +} + + +void +DynamicTypeBuilder::add_bounded_wstring_unbounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_wstring_unbounded_sequence_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), wstring_bound); +} + + +void +DynamicTypeBuilder::add_bounded_string_bounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + size_t string_bound, size_t sequence_bound) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_string_bounded_sequence_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + string_bound, sequence_bound); +} + + +void +DynamicTypeBuilder::add_bounded_wstring_bounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + size_t wstring_bound, size_t sequence_bound) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_wstring_bounded_sequence_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + wstring_bound, sequence_bound); +} + + +// ADD NESTED MEMBERS ============================================================================== +void +DynamicTypeBuilder::add_complex_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicType & nested_type) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + nested_type.get_rosidl_dynamic_type()); +} + + +void +DynamicTypeBuilder::add_complex_array_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicType & nested_type, size_t array_length) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_array_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + nested_type.get_rosidl_dynamic_type(), array_length); +} + + +void +DynamicTypeBuilder::add_complex_unbounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicType & nested_type) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_unbounded_sequence_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + nested_type.get_rosidl_dynamic_type()); +} + + +void +DynamicTypeBuilder::add_complex_bounded_sequence_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicType & nested_type, size_t sequence_bound) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_bounded_sequence_member( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + nested_type.get_rosidl_dynamic_type(), sequence_bound); +} From a3e5d0a91a9933a38ac1da04043bcc31b30fb308 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Mon, 20 Mar 2023 18:09:46 -0700 Subject: [PATCH 02/27] Implement dynamic message type support wrapper Signed-off-by: methylDragon --- rclcpp/CMakeLists.txt | 1 + .../dynamic_typesupport/dynamic_data.hpp | 2 +- .../dynamic_typesupport/dynamic_message.hpp | 4 +- .../dynamic_message_type.hpp | 2 +- .../dynamic_message_type_support.hpp | 189 +++++++++ .../dynamic_typesupport/dynamic_type.hpp | 2 +- .../dynamic_type_builder.hpp | 2 +- rclcpp/include/rclcpp/rclcpp.hpp | 3 + .../dynamic_typesupport/dynamic_data.cpp | 2 +- .../dynamic_message_type_support.cpp | 399 ++++++++++++++++++ .../dynamic_typesupport/dynamic_type.cpp | 2 +- .../dynamic_type_builder.cpp | 2 +- 12 files changed, 601 insertions(+), 9 deletions(-) create mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp create mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index 583aeece44..cbeb0a17a0 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -52,6 +52,7 @@ set(${PROJECT_NAME}_SRCS src/rclcpp/dynamic_typesupport/dynamic_data.cpp src/rclcpp/dynamic_typesupport/dynamic_message.cpp src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp + src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp src/rclcpp/dynamic_typesupport/dynamic_type.cpp src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp index 9429cac90f..452cdbc17a 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp @@ -143,7 +143,7 @@ class DynamicData : public std::enable_shared_from_this get_shared_dynamic_serialization_support(); RCLCPP_PUBLIC - std::shared_ptr + DynamicSerializationSupport::ConstSharedPtr get_shared_dynamic_serialization_support() const; RCLCPP_PUBLIC diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index d39fae07e1..0970bd7dc8 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -63,11 +63,11 @@ class DynamicMessage final : public DynamicData /// Construct a new DynamicMessage with the provided dynamic type builder RCLCPP_PUBLIC - explicit DynamicMessage(std::shared_ptr dynamic_type_builder); + explicit DynamicMessage(DynamicTypeBuilder::SharedPtr dynamic_type_builder); /// Construct a new DynamicMessage with the provided dynamic type RCLCPP_PUBLIC - explicit DynamicMessage(std::shared_ptr dynamic_type); + explicit DynamicMessage(DynamicType::SharedPtr dynamic_type); /// Assume ownership of raw pointer RCLCPP_PUBLIC diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index fd33180675..2379baa686 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -61,7 +61,7 @@ class DynamicMessageType final : public DynamicType /// Construct a new DynamicType with the provided dynamic type builder RCLCPP_PUBLIC - explicit DynamicMessageType(std::shared_ptr dynamic_type_builder); + explicit DynamicMessageType(DynamicTypeBuilder::SharedPtr dynamic_type_builder); /// Assume ownership of raw pointer RCLCPP_PUBLIC diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp new file mode 100644 index 0000000000..149ad81bb7 --- /dev/null +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -0,0 +1,189 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_ + +#include +#include + +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" + +#include "rclcpp/macros.hpp" +#include "rclcpp/visibility_control.hpp" + +#include +#include +#include + +namespace rclcpp +{ +namespace dynamic_typesupport +{ + +/// Utility wrapper class for rosidl_message_type_support_t * containing managed +/// instances of the typesupport handle impl. +/** + * + * NOTE: This class is the recommended way to obtain the dynamic message type + * support struct, instead of rcl_get_dynamic_message_typesupport_handle, + * because this class will manage the lifetimes for you. + * + * Do NOT call rcl_dynamic_message_typesupport_handle_fini!! + * + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Stores shared pointers to wrapper classes that expose the underlying + * serialization support API + * + * Ownership: + * - This class, similarly to the rosidl_dynamic_typesupport_serialization_support_t, must outlive + * all downstream usages of the serialization support. + */ +class DynamicMessageTypeSupport : public std::enable_shared_from_this +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageTypeSupport) + + // CONSTRUCTION ================================================================================== + /// From description + RCLCPP_PUBLIC + DynamicMessageTypeSupport( + rosidl_runtime_c__type_description__TypeDescription * description, + const std::string & serialization_library_name = nullptr); + + /// From description, for provided serialization support + RCLCPP_PUBLIC + DynamicMessageTypeSupport( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_runtime_c__type_description__TypeDescription * description); + + /// Assume ownership of managed types + RCLCPP_PUBLIC + DynamicMessageTypeSupport( + DynamicSerializationSupport::SharedPtr serialization_support, + DynamicMessageType::SharedPtr dynamic_message_type, + DynamicMessage::SharedPtr dynamic_message, + rosidl_runtime_c__type_description__TypeDescription * description = nullptr); + + RCLCPP_PUBLIC + virtual ~DynamicMessageTypeSupport(); + + + // GETTERS ======================================================================================= + RCLCPP_PUBLIC + const std::string + get_library_identifier() const; + + RCLCPP_PUBLIC + rosidl_message_type_support_t * + get_rosidl_message_type_support(); + + RCLCPP_PUBLIC + const rosidl_message_type_support_t * + get_rosidl_message_type_support() const; + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_message_type_support(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_message_type_support() const; + + RCLCPP_PUBLIC + rosidl_runtime_c__type_description__TypeDescription * + get_rosidl_runtime_c_type_description(); + + RCLCPP_PUBLIC + const rosidl_runtime_c__type_description__TypeDescription * + get_rosidl_runtime_c_type_description() const; + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_runtime_c_type_description(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_runtime_c_type_description() const; + + RCLCPP_PUBLIC + DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support(); + + RCLCPP_PUBLIC + DynamicSerializationSupport::ConstSharedPtr + get_shared_dynamic_serialization_support() const; + + RCLCPP_PUBLIC + DynamicMessageType::SharedPtr + get_shared_dynamic_message_type(); + + RCLCPP_PUBLIC + DynamicMessageType::ConstSharedPtr + get_shared_dynamic_message_type() const; + + RCLCPP_PUBLIC + DynamicMessage::SharedPtr + get_shared_dynamic_message(); + + RCLCPP_PUBLIC + DynamicMessage::ConstSharedPtr + get_shared_dynamic_message() const; + +protected: + RCLCPP_DISABLE_COPY(DynamicMessageTypeSupport) + + DynamicSerializationSupport::SharedPtr serialization_support_; + DynamicMessageType::SharedPtr dynamic_message_type_; + DynamicMessage::SharedPtr dynamic_message_; + std::shared_ptr description_; + + std::shared_ptr rosidl_message_type_support_; + +private: + RCLCPP_PUBLIC + DynamicMessageTypeSupport(); + + RCLCPP_PUBLIC + void + init_serialization_support_(const std::string & serialization_library_name); + + RCLCPP_PUBLIC + void + init_dynamic_message_type_( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description); + + RCLCPP_PUBLIC + void + init_dynamic_message_(DynamicType::SharedPtr dynamic_type); + + RCLCPP_PUBLIC + void + init_rosidl_message_type_support_( + DynamicSerializationSupport::SharedPtr serialization_support, + DynamicMessageType::SharedPtr dynamic_message_type, + DynamicMessage::SharedPtr dynamic_message, + const rosidl_runtime_c__type_description__TypeDescription * description); +}; + + +} // namespace dynamic_typesupport +} // namespace rclcpp + +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp index e0d9660c22..d61cdf8196 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp @@ -142,7 +142,7 @@ class DynamicType : public std::enable_shared_from_this get_shared_dynamic_serialization_support(); RCLCPP_PUBLIC - std::shared_ptr + DynamicSerializationSupport::ConstSharedPtr get_shared_dynamic_serialization_support() const; diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp index 62199c838a..5e3dbaeb0f 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp @@ -140,7 +140,7 @@ class DynamicTypeBuilder : public std::enable_shared_from_this + DynamicSerializationSupport::ConstSharedPtr get_shared_dynamic_serialization_support() const; diff --git a/rclcpp/include/rclcpp/rclcpp.hpp b/rclcpp/include/rclcpp/rclcpp.hpp index ab4b54a0dd..d84610d159 100644 --- a/rclcpp/include/rclcpp/rclcpp.hpp +++ b/rclcpp/include/rclcpp/rclcpp.hpp @@ -130,6 +130,9 @@ * - rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp * - rclcpp/dynamic_typesupport/dynamic_type_builder.hpp * - rclcpp/dynamic_typesupport/dynamic_type.hpp + * - Dynamic typesupport + * - rclcpp::dynamic_typesupport::DynamicMessageTypeSupport + * - rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp * - Generic publisher * - rclcpp::Node::create_generic_publisher() * - rclcpp::GenericPublisher diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp index f953e44a80..d1715b8087 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp @@ -303,7 +303,7 @@ DynamicData::get_shared_dynamic_serialization_support() } -std::shared_ptr +DynamicSerializationSupport::ConstSharedPtr DynamicData::get_shared_dynamic_serialization_support() const { return serialization_support_; diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp new file mode 100644 index 0000000000..ada02b90d3 --- /dev/null +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -0,0 +1,399 @@ +// Copyright 2023 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "rmw/dynamic_typesupport.h" + +#include "rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp" + +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/exceptions.hpp" +#include "rclcpp/macros.hpp" +#include "rclcpp/visibility_control.hpp" +#include "rcutils/logging_macros.h" + +#include +#include +#include +#include + +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; +using rclcpp::dynamic_typesupport::DynamicMessage; +using rclcpp::dynamic_typesupport::DynamicMessageType; +using rclcpp::dynamic_typesupport::DynamicMessageTypeSupport; + + +// CONSTRUCTION ==================================================================================== +DynamicMessageTypeSupport::DynamicMessageTypeSupport( + rosidl_runtime_c__type_description__TypeDescription * description, + const std::string & serialization_library_name) +: serialization_support_(nullptr), + dynamic_message_type_(nullptr), + dynamic_message_(nullptr), + description_(nullptr), + rosidl_message_type_support_(nullptr) +{ + if (!description) { + throw std::runtime_error("description cannot be nullptr!"); + } + description_.reset( + description, + [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { + rosidl_runtime_c__type_description__TypeDescription__destroy(description); + }); + + init_serialization_support_(serialization_library_name); + if (!serialization_support_) { + throw std::runtime_error("could not init dynamic serialization support!"); + } + + init_dynamic_message_type_(serialization_support_, description); + if (!dynamic_message_type_) { + throw std::runtime_error("could not init dynamic message type!"); + } + + init_dynamic_message_(dynamic_message_type_); + if (!dynamic_message_) { + throw std::runtime_error("could not init dynamic message!"); + } + + init_rosidl_message_type_support_( + serialization_support_, dynamic_message_type_, dynamic_message_, description_.get()); + if (!rosidl_message_type_support_) { + throw std::runtime_error("could not init rosidl message type support!"); + } +} + + +DynamicMessageTypeSupport::DynamicMessageTypeSupport( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_runtime_c__type_description__TypeDescription * description) +: serialization_support_(serialization_support), + dynamic_message_type_(nullptr), + dynamic_message_(nullptr), + description_(nullptr), + rosidl_message_type_support_(nullptr) +{ + // Check null + if (!serialization_support) { + throw std::runtime_error("serialization_support cannot be nullptr!"); + } + if (!description) { + throw std::runtime_error("description cannot be nullptr!"); + } + description_.reset( + description, + [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { + rosidl_runtime_c__type_description__TypeDescription__destroy(description); + }); + + // Init + init_dynamic_message_type_(serialization_support_, description); + if (!dynamic_message_type_) { + throw std::runtime_error("could not init dynamic message type!"); + } + + init_dynamic_message_(dynamic_message_type_); + if (!dynamic_message_) { + throw std::runtime_error("could not init dynamic message!"); + } + + init_rosidl_message_type_support_( + serialization_support_, dynamic_message_type_, dynamic_message_, description_.get()); + if (!rosidl_message_type_support_) { + throw std::runtime_error("could not init rosidl message type support!"); + } +} + + +DynamicMessageTypeSupport::DynamicMessageTypeSupport( + DynamicSerializationSupport::SharedPtr serialization_support, + DynamicMessageType::SharedPtr dynamic_message_type, + DynamicMessage::SharedPtr dynamic_message, + rosidl_runtime_c__type_description__TypeDescription * description) +: serialization_support_(serialization_support), + dynamic_message_type_(dynamic_message_type), + dynamic_message_(dynamic_message), + description_(nullptr), + rosidl_message_type_support_(nullptr) +{ + // Check null + if (!serialization_support) { + throw std::runtime_error("serialization_support cannot be nullptr!"); + } + if (!dynamic_message_type) { + throw std::runtime_error("dynamic_message_type cannot be nullptr!"); + } + if (!dynamic_message) { + throw std::runtime_error("dynamic_message cannot be nullptr!"); + } + + if (description) { + description_.reset( + description, + [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { + rosidl_runtime_c__type_description__TypeDescription__destroy(description); + }); + } + + // Check identifiers + if (serialization_support->get_library_identifier() != + dynamic_message_type->get_library_identifier()) + { + throw std::runtime_error( + "serialization support library identifier does not match " + "dynamic message type library identifier!"); + } + if (dynamic_message_type->get_library_identifier() != dynamic_message->get_library_identifier()) { + throw std::runtime_error( + "dynamic message type library identifier does not match " + "dynamic message library identifier!"); + } + + // Check pointers + /* *INDENT-OFF* */ + if (serialization_support->get_rosidl_serialization_support() != + dynamic_message_type + ->get_shared_dynamic_serialization_support() + ->get_rosidl_serialization_support()) + { + throw std::runtime_error("serialization support pointer dynamic message type's"); + } + if (dynamic_message_type + ->get_shared_dynamic_serialization_support() + ->get_rosidl_serialization_support() != + dynamic_message_type + ->get_shared_dynamic_serialization_support() + ->get_rosidl_serialization_support()) + { + throw std::runtime_error("serialization support pointer dynamic message type's"); + } + /* *INDENT-ON* */ + + init_rosidl_message_type_support_( + serialization_support_, dynamic_message_type_, dynamic_message_, description_.get()); + if (!rosidl_message_type_support_) { + throw std::runtime_error("could not init rosidl message type support!"); + } +} + + +DynamicMessageTypeSupport::~DynamicMessageTypeSupport() {} + + +void +DynamicMessageTypeSupport::init_serialization_support_( + const std::string & serialization_library_name) +{ + serialization_support_ = DynamicSerializationSupport::make_shared(serialization_library_name); +} + + +void +DynamicMessageTypeSupport::init_dynamic_message_type_( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription * description) +{ + dynamic_message_type_ = DynamicMessageType::make_shared(serialization_support, description); +} + + +void +DynamicMessageTypeSupport::init_dynamic_message_(DynamicType::SharedPtr dynamic_type) +{ + dynamic_message_ = DynamicMessage::make_shared(dynamic_type); +} + + +void +DynamicMessageTypeSupport::init_rosidl_message_type_support_( + DynamicSerializationSupport::SharedPtr serialization_support, + DynamicMessageType::SharedPtr dynamic_message_type, + DynamicMessage::SharedPtr dynamic_message, + const rosidl_runtime_c__type_description__TypeDescription * description) +{ + bool middleware_supports_type_discovery = + rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY); + bool middleware_can_take_dynamic_data = + rmw_feature_supported(RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_DATA); + + if (!middleware_supports_type_discovery && !description) { + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "Middleware does not support type discovery! Deferred dynamic type" + "message type support will never be populated! You must provide a type " + "description!"); + return; + } + + // NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members + // are they're managed by the passed in SharedPtr wrapper classes + rosidl_message_type_support_ = std::make_shared(); + + if (!rosidl_message_type_support_) { + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "Could not allocate rosidl_message_type_support_t struct"); + return; + } + + rosidl_message_type_support_->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; + + // NOTE(methylDragon): To populate dynamic_type and description if deferred, OUTSIDE + rosidl_message_type_support_->data = calloc(1, sizeof(rmw_dynamic_typesupport_impl_t)); + if (!rosidl_message_type_support_->data) { + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "Could not allocate rmw_dynamic_typesupport_impl_t struct"); + rosidl_message_type_support_.reset(); + } + + rmw_dynamic_typesupport_impl_t * ts_impl = + (rmw_dynamic_typesupport_impl_t *)rosidl_message_type_support_->data; + + ts_impl->take_dynamic_data = middleware_can_take_dynamic_data; + ts_impl->serialization_support = serialization_support->get_rosidl_serialization_support(); + ts_impl->dynamic_type = dynamic_message_type->get_rosidl_dynamic_type(); + ts_impl->dynamic_data = dynamic_message->get_rosidl_dynamic_data(); + rosidl_message_type_support_->func = get_message_typesupport_handle_function; + + if (description) { + ts_impl->description = rosidl_runtime_c__type_description__TypeDescription__create(); + if (ts_impl->description == NULL) { + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "Could not create type description to assign into"); + rosidl_message_type_support_.reset(); + } + + if (!rosidl_runtime_c__type_description__TypeDescription__copy( + description, ts_impl->description)) + { + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "Could not copy type description"); + rosidl_message_type_support_.reset(); + } + } +} + + +// GETTERS ========================================================================================= +const std::string +DynamicMessageTypeSupport::get_library_identifier() const +{ + return serialization_support_->get_library_identifier(); +} + + +rosidl_message_type_support_t * +DynamicMessageTypeSupport::get_rosidl_message_type_support() +{ + return rosidl_message_type_support_.get(); +} + + +const rosidl_message_type_support_t * +DynamicMessageTypeSupport::get_rosidl_message_type_support() const +{ + return rosidl_message_type_support_.get(); +} + + +std::shared_ptr +DynamicMessageTypeSupport::get_shared_rosidl_message_type_support() +{ + return rosidl_message_type_support_; +} + + +std::shared_ptr +DynamicMessageTypeSupport::get_shared_rosidl_message_type_support() const +{ + return rosidl_message_type_support_; +} + + +rosidl_runtime_c__type_description__TypeDescription * +DynamicMessageTypeSupport::get_rosidl_runtime_c_type_description() +{ + return description_.get(); +} + + +const rosidl_runtime_c__type_description__TypeDescription * +DynamicMessageTypeSupport::get_rosidl_runtime_c_type_description() const +{ + return description_.get(); +} + + +std::shared_ptr +DynamicMessageTypeSupport::get_shared_rosidl_runtime_c_type_description() +{ + return description_; +} + + +std::shared_ptr +DynamicMessageTypeSupport::get_shared_rosidl_runtime_c_type_description() const +{ + return description_; +} + + +DynamicSerializationSupport::SharedPtr +DynamicMessageTypeSupport::get_shared_dynamic_serialization_support() +{ + return serialization_support_; +} + + +DynamicSerializationSupport::ConstSharedPtr +DynamicMessageTypeSupport::get_shared_dynamic_serialization_support() const +{ + return serialization_support_; +} + + +DynamicMessageType::SharedPtr +DynamicMessageTypeSupport::get_shared_dynamic_message_type() +{ + return dynamic_message_type_; +} + + +DynamicMessageType::ConstSharedPtr +DynamicMessageTypeSupport::get_shared_dynamic_message_type() const +{ + return dynamic_message_type_; +} + + +DynamicMessage::SharedPtr +DynamicMessageTypeSupport::get_shared_dynamic_message() +{ + return dynamic_message_; +} + + +DynamicMessage::ConstSharedPtr +DynamicMessageTypeSupport::get_shared_dynamic_message() const +{ + return dynamic_message_; +} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp index 8590722edc..a189d88d53 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp @@ -269,7 +269,7 @@ DynamicType::get_shared_dynamic_serialization_support() } -std::shared_ptr +DynamicSerializationSupport::ConstSharedPtr DynamicType::get_shared_dynamic_serialization_support() const { return serialization_support_; diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp index 18d23625a1..5cec3d7904 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp @@ -286,7 +286,7 @@ DynamicTypeBuilder::get_shared_dynamic_serialization_support() } -std::shared_ptr +DynamicSerializationSupport::ConstSharedPtr DynamicTypeBuilder::get_shared_dynamic_serialization_support() const { return serialization_support_; From 554ad022a62ccfcb78e220fd3c6ce98b9c2fa407 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 21 Mar 2023 11:13:53 -0700 Subject: [PATCH 03/27] Refine wrappers Signed-off-by: methylDragon --- rclcpp/CMakeLists.txt | 2 - .../dynamic_typesupport/dynamic_data.hpp | 5 +- .../dynamic_typesupport/dynamic_message.hpp | 99 ++++++++++--------- .../dynamic_message_type.hpp | 79 +++++++-------- .../dynamic_message_type_support.hpp | 2 +- .../dynamic_serialization_support.hpp | 2 +- .../dynamic_typesupport/dynamic_data.cpp | 11 +-- .../dynamic_typesupport/dynamic_message.cpp | 61 ------------ .../dynamic_message_type.cpp | 57 ----------- .../dynamic_serialization_support.cpp | 6 +- 10 files changed, 102 insertions(+), 222 deletions(-) delete mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp delete mode 100644 rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index cbeb0a17a0..848fbec174 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -50,8 +50,6 @@ set(${PROJECT_NAME}_SRCS src/rclcpp/detail/utilities.cpp src/rclcpp/duration.cpp src/rclcpp/dynamic_typesupport/dynamic_data.cpp - src/rclcpp/dynamic_typesupport/dynamic_message.cpp - src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp src/rclcpp/dynamic_typesupport/dynamic_type.cpp diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp index 452cdbc17a..36a6de270a 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp @@ -23,6 +23,7 @@ #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" +#include #include @@ -222,11 +223,11 @@ class DynamicData : public std::enable_shared_from_this RCLCPP_PUBLIC bool - serialize(std::shared_ptr buffer); + serialize(rcl_serialized_message_t * buffer); RCLCPP_PUBLIC bool - deserialize(std::shared_ptr buffer); + deserialize(rcl_serialized_message_t * buffer); // MEMBER ACCESS TEMPLATES ======================================================================= diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index 0970bd7dc8..215a303ccb 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -34,7 +34,7 @@ namespace rclcpp namespace dynamic_typesupport { - +using DynamicMessageType = DynamicType; /// Thin wrapper around DynamicData object for message pubsub /** * This class: @@ -48,55 +48,56 @@ namespace dynamic_typesupport * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer * must point to the same location in memory as the stored raw pointer! */ -class DynamicMessage final : public DynamicData -{ -public: - RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessage) - - // CONSTRUCTION ================================================================================== - // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the - // lifetime of the serialization support (if the constructor cannot otherwise get it from args). - // - // In cases where a dynamic data pointer is passed, the serialization support composed by - // the data should be the exact same object managed by the DynamicSerializationSupport, - // otherwise the lifetime management will not work properly. - - /// Construct a new DynamicMessage with the provided dynamic type builder - RCLCPP_PUBLIC - explicit DynamicMessage(DynamicTypeBuilder::SharedPtr dynamic_type_builder); - - /// Construct a new DynamicMessage with the provided dynamic type - RCLCPP_PUBLIC - explicit DynamicMessage(DynamicType::SharedPtr dynamic_type); - - /// Assume ownership of raw pointer - RCLCPP_PUBLIC - DynamicMessage( - DynamicSerializationSupport::SharedPtr serialization_support, - rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data); - - /// Copy shared pointer - RCLCPP_PUBLIC - DynamicMessage( - DynamicSerializationSupport::SharedPtr serialization_support, - std::shared_ptr rosidl_dynamic_data); - - /// Loaning constructor - /// Must only be called with raw ptr obtained from loaning! - // NOTE(methylDragon): I'd put this in protected, but I need this exposed to - // enable_shared_from_this... - RCLCPP_PUBLIC - DynamicMessage( - DynamicData::SharedPtr parent_data, - rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data); - - // NOTE(methylDragon): Deliberately no constructor from description to nudge users towards using - // construction from dynamic type/builder, which is more efficient -private: - RCLCPP_PUBLIC - DynamicMessage(); -}; +// class DynamicMessage final : public DynamicData +// { +// public: +// RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessage) +// +// // CONSTRUCTION ================================================================================== +// // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the +// // lifetime of the serialization support (if the constructor cannot otherwise get it from args). +// // +// // In cases where a dynamic data pointer is passed, the serialization support composed by +// // the data should be the exact same object managed by the DynamicSerializationSupport, +// // otherwise the lifetime management will not work properly. +// +// /// Construct a new DynamicMessage with the provided dynamic type builder +// RCLCPP_PUBLIC +// explicit DynamicMessage(DynamicTypeBuilder::SharedPtr dynamic_type_builder); +// +// /// Construct a new DynamicMessage with the provided dynamic type +// RCLCPP_PUBLIC +// explicit DynamicMessage(DynamicType::SharedPtr dynamic_type); +// +// /// Assume ownership of raw pointer +// RCLCPP_PUBLIC +// DynamicMessage( +// DynamicSerializationSupport::SharedPtr serialization_support, +// rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data); +// +// /// Copy shared pointer +// RCLCPP_PUBLIC +// DynamicMessage( +// DynamicSerializationSupport::SharedPtr serialization_support, +// std::shared_ptr rosidl_dynamic_data); +// +// /// Loaning constructor +// /// Must only be called with raw ptr obtained from loaning! +// // NOTE(methylDragon): I'd put this in protected, but I need this exposed to +// // enable_shared_from_this... +// RCLCPP_PUBLIC +// DynamicMessage( +// DynamicData::SharedPtr parent_data, +// rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data); +// +// // NOTE(methylDragon): Deliberately no constructor from description to nudge users towards using +// // construction from dynamic type/builder, which is more efficient +// +// private: +// RCLCPP_PUBLIC +// DynamicMessage(); +// }; } // namespace dynamic_typesupport diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index 2379baa686..886a406864 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -33,6 +33,7 @@ namespace dynamic_typesupport { +using DynamicMessage = DynamicData; /// Thin wrapper around DynamicType object for message pubsub type representation /** * This class: @@ -46,45 +47,45 @@ namespace dynamic_typesupport * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer * must point to the same location in memory as the stored raw pointer! */ -class DynamicMessageType final : public DynamicType -{ -public: - RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageType) - - // CONSTRUCTION ================================================================================== - // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the - // lifetime of the serialization support (if the constructor cannot otherwise get it from args). - // - // In cases where a dynamic type pointer is passed, the serialization support composed by - // the type should be the exact same object managed by the DynamicSerializationSupport, - // otherwise the lifetime management will not work properly. - - /// Construct a new DynamicType with the provided dynamic type builder - RCLCPP_PUBLIC - explicit DynamicMessageType(DynamicTypeBuilder::SharedPtr dynamic_type_builder); - - /// Assume ownership of raw pointer - RCLCPP_PUBLIC - DynamicMessageType( - DynamicSerializationSupport::SharedPtr serialization_support, - rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type); - - /// Copy shared pointer - RCLCPP_PUBLIC - DynamicMessageType( - DynamicSerializationSupport::SharedPtr serialization_support, - std::shared_ptr rosidl_dynamic_type); - - /// From description - RCLCPP_PUBLIC - DynamicMessageType( - DynamicSerializationSupport::SharedPtr serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description); - -private: - RCLCPP_PUBLIC - DynamicMessageType(); -}; +// class DynamicMessageType final : public DynamicType +// { +// public: +// RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageType) +// +// // CONSTRUCTION ================================================================================== +// // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the +// // lifetime of the serialization support (if the constructor cannot otherwise get it from args). +// // +// // In cases where a dynamic type pointer is passed, the serialization support composed by +// // the type should be the exact same object managed by the DynamicSerializationSupport, +// // otherwise the lifetime management will not work properly. +// +// /// Construct a new DynamicType with the provided dynamic type builder +// RCLCPP_PUBLIC +// explicit DynamicMessageType(DynamicTypeBuilder::SharedPtr dynamic_type_builder); +// +// /// Assume ownership of raw pointer +// RCLCPP_PUBLIC +// DynamicMessageType( +// DynamicSerializationSupport::SharedPtr serialization_support, +// rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type); +// +// /// Copy shared pointer +// RCLCPP_PUBLIC +// DynamicMessageType( +// DynamicSerializationSupport::SharedPtr serialization_support, +// std::shared_ptr rosidl_dynamic_type); +// +// /// From description +// RCLCPP_PUBLIC +// DynamicMessageType( +// DynamicSerializationSupport::SharedPtr serialization_support, +// const rosidl_runtime_c__type_description__TypeDescription * description); +// +// private: +// RCLCPP_PUBLIC +// DynamicMessageType(); +// }; } // namespace dynamic_typesupport diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp index 149ad81bb7..8fc96744b7 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -64,7 +64,7 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this @@ -455,18 +456,16 @@ DynamicData::print() const bool -DynamicData::serialize(std::shared_ptr buffer) +DynamicData::serialize(rcl_serialized_message_t * buffer) { - return rosidl_dynamic_typesupport_dynamic_data_serialize( - get_rosidl_dynamic_data(), buffer.get()); + return rosidl_dynamic_typesupport_dynamic_data_serialize(get_rosidl_dynamic_data(), buffer); } bool -DynamicData::deserialize(std::shared_ptr buffer) +DynamicData::deserialize(rcl_serialized_message_t * buffer) { - return rosidl_dynamic_typesupport_dynamic_data_deserialize( - get_rosidl_dynamic_data(), buffer.get()); + return rosidl_dynamic_typesupport_dynamic_data_deserialize(get_rosidl_dynamic_data(), buffer); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp deleted file mode 100644 index 550517a852..0000000000 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2023 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. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" - -#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" -#include "rclcpp/exceptions.hpp" -#include "rcutils/logging_macros.h" - -#include -#include -#include - -using rclcpp::dynamic_typesupport::DynamicMessage; -using rclcpp::dynamic_typesupport::DynamicSerializationSupport; -using rclcpp::dynamic_typesupport::DynamicType; -using rclcpp::dynamic_typesupport::DynamicTypeBuilder; - - -// CONSTRUCTION ================================================================================== -DynamicMessage::DynamicMessage(const DynamicTypeBuilder::SharedPtr dynamic_type_builder) -: DynamicData(dynamic_type_builder) {} - - -DynamicMessage::DynamicMessage(const DynamicType::SharedPtr dynamic_type) -: DynamicData(dynamic_type) {} - - -DynamicMessage::DynamicMessage( - DynamicSerializationSupport::SharedPtr serialization_support, - rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data) -: DynamicData(serialization_support, rosidl_dynamic_data) {} - - -DynamicMessage::DynamicMessage( - DynamicSerializationSupport::SharedPtr serialization_support, - std::shared_ptr rosidl_dynamic_data) -: DynamicData(serialization_support, rosidl_dynamic_data) {} - - -DynamicMessage::DynamicMessage( - DynamicData::SharedPtr parent_data, - rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data) -: DynamicData(parent_data, rosidl_loaned_data) {} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp deleted file mode 100644 index 3f6858fea5..0000000000 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2023 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. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" - -#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" -#include "rclcpp/exceptions.hpp" -#include "rcutils/logging_macros.h" - -#include -#include -#include - -using rclcpp::dynamic_typesupport::DynamicMessageType; -using rclcpp::dynamic_typesupport::DynamicSerializationSupport; -using rclcpp::dynamic_typesupport::DynamicType; -using rclcpp::dynamic_typesupport::DynamicTypeBuilder; - - -// CONSTRUCTION ==================================================================================== -DynamicMessageType::DynamicMessageType(DynamicTypeBuilder::SharedPtr dynamic_type_builder) -: DynamicType(dynamic_type_builder) {} - - -DynamicMessageType::DynamicMessageType( - DynamicSerializationSupport::SharedPtr serialization_support, - rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type) -: DynamicType(serialization_support, rosidl_dynamic_type) {} - - -DynamicMessageType::DynamicMessageType( - DynamicSerializationSupport::SharedPtr serialization_support, - std::shared_ptr rosidl_dynamic_type) -: DynamicType(serialization_support, rosidl_dynamic_type) {} - - -DynamicMessageType::DynamicMessageType( - DynamicSerializationSupport::SharedPtr serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description) -: DynamicType(serialization_support, description) {} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp index 4c7d90ebde..f5d61960f1 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp @@ -46,8 +46,7 @@ DynamicSerializationSupport::DynamicSerializationSupport( rosidl_serialization_support, // Custom deleter [](rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support) -> void { - rosidl_dynamic_typesupport_serialization_support_fini(rosidl_serialization_support); - free(rosidl_serialization_support); + rosidl_dynamic_typesupport_serialization_support_destroy(rosidl_serialization_support); }); } @@ -64,8 +63,7 @@ DynamicSerializationSupport::DynamicSerializationSupport( rosidl_serialization_support_.reset( rosidl_serialization_support, [](rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support) -> void { - rosidl_dynamic_typesupport_serialization_support_fini(rosidl_serialization_support); - free(rosidl_serialization_support); + rosidl_dynamic_typesupport_serialization_support_destroy(rosidl_serialization_support); }); } From 833efe0e2d47c9a8bc96c0fe4a7e4c2d0495f009 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 21 Mar 2023 16:04:30 -0700 Subject: [PATCH 04/27] Delete redundant wrapper class definitions Signed-off-by: methylDragon --- .../dynamic_typesupport/dynamic_message.hpp | 67 ++----------------- .../dynamic_message_type.hpp | 55 +-------------- 2 files changed, 7 insertions(+), 115 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index 215a303ccb..26b6068413 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -34,70 +34,11 @@ namespace rclcpp namespace dynamic_typesupport { -using DynamicMessageType = DynamicType; -/// Thin wrapper around DynamicData object for message pubsub -/** - * This class: - * - Manages the lifetime of the raw pointer. - * - Exposes getter methods to get the raw pointer and shared pointers - * - Exposes the underlying serialization support API - * - * Ownership: - * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed - * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. - * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer - * must point to the same location in memory as the stored raw pointer! - */ -// class DynamicMessage final : public DynamicData -// { -// public: -// RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessage) -// -// // CONSTRUCTION ================================================================================== -// // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the -// // lifetime of the serialization support (if the constructor cannot otherwise get it from args). -// // -// // In cases where a dynamic data pointer is passed, the serialization support composed by -// // the data should be the exact same object managed by the DynamicSerializationSupport, -// // otherwise the lifetime management will not work properly. -// -// /// Construct a new DynamicMessage with the provided dynamic type builder -// RCLCPP_PUBLIC -// explicit DynamicMessage(DynamicTypeBuilder::SharedPtr dynamic_type_builder); -// -// /// Construct a new DynamicMessage with the provided dynamic type -// RCLCPP_PUBLIC -// explicit DynamicMessage(DynamicType::SharedPtr dynamic_type); -// -// /// Assume ownership of raw pointer -// RCLCPP_PUBLIC -// DynamicMessage( -// DynamicSerializationSupport::SharedPtr serialization_support, -// rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data); -// -// /// Copy shared pointer -// RCLCPP_PUBLIC -// DynamicMessage( -// DynamicSerializationSupport::SharedPtr serialization_support, -// std::shared_ptr rosidl_dynamic_data); -// -// /// Loaning constructor -// /// Must only be called with raw ptr obtained from loaning! -// // NOTE(methylDragon): I'd put this in protected, but I need this exposed to -// // enable_shared_from_this... -// RCLCPP_PUBLIC -// DynamicMessage( -// DynamicData::SharedPtr parent_data, -// rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data); -// -// // NOTE(methylDragon): Deliberately no constructor from description to nudge users towards using -// // construction from dynamic type/builder, which is more efficient -// -// private: -// RCLCPP_PUBLIC -// DynamicMessage(); -// }; +// NOTE(methylDragon): We just alias the type in this case... +// I'd have made a wrapper class but then I'd need to redirect every single +// method (or dynamic cast everywhere else), so.. no thanks. +using DynamicMessageType = DynamicType; } // namespace dynamic_typesupport diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index 886a406864..59115f7e45 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -33,59 +33,10 @@ namespace dynamic_typesupport { +// NOTE(methylDragon): We just alias the type in this case... +// I'd have made a wrapper class but then I'd need to redirect every single +// method (or dynamic cast everywhere else), so.. no thanks. using DynamicMessage = DynamicData; -/// Thin wrapper around DynamicType object for message pubsub type representation -/** - * This class: - * - Manages the lifetime of the raw pointer. - * - Exposes getter methods to get the raw pointer and shared pointers - * - Exposes the underlying serialization support API - * - * Ownership: - * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed - * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. - * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer - * must point to the same location in memory as the stored raw pointer! - */ -// class DynamicMessageType final : public DynamicType -// { -// public: -// RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageType) -// -// // CONSTRUCTION ================================================================================== -// // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the -// // lifetime of the serialization support (if the constructor cannot otherwise get it from args). -// // -// // In cases where a dynamic type pointer is passed, the serialization support composed by -// // the type should be the exact same object managed by the DynamicSerializationSupport, -// // otherwise the lifetime management will not work properly. -// -// /// Construct a new DynamicType with the provided dynamic type builder -// RCLCPP_PUBLIC -// explicit DynamicMessageType(DynamicTypeBuilder::SharedPtr dynamic_type_builder); -// -// /// Assume ownership of raw pointer -// RCLCPP_PUBLIC -// DynamicMessageType( -// DynamicSerializationSupport::SharedPtr serialization_support, -// rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type); -// -// /// Copy shared pointer -// RCLCPP_PUBLIC -// DynamicMessageType( -// DynamicSerializationSupport::SharedPtr serialization_support, -// std::shared_ptr rosidl_dynamic_type); -// -// /// From description -// RCLCPP_PUBLIC -// DynamicMessageType( -// DynamicSerializationSupport::SharedPtr serialization_support, -// const rosidl_runtime_c__type_description__TypeDescription * description); -// -// private: -// RCLCPP_PUBLIC -// DynamicMessageType(); -// }; } // namespace dynamic_typesupport From a2484be7c3d633433bc63c8a0da302c1d6a5174c Mon Sep 17 00:00:00 2001 From: methylDragon Date: Wed, 22 Mar 2023 16:43:52 -0700 Subject: [PATCH 05/27] Take ownership of description, add print, and update ser support API Signed-off-by: methylDragon --- .../dynamic_typesupport/dynamic_message.hpp | 3 +- .../dynamic_message_type.hpp | 2 +- .../dynamic_message_type_support.hpp | 8 +++- .../dynamic_serialization_support.hpp | 2 +- .../dynamic_type_builder.hpp | 24 ++++++++++ .../dynamic_message_type_support.cpp | 41 ++++++++--------- .../dynamic_type_builder.cpp | 44 +++++++++++++++++++ 7 files changed, 97 insertions(+), 27 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index 26b6068413..9fe612141e 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -38,8 +38,7 @@ namespace dynamic_typesupport // NOTE(methylDragon): We just alias the type in this case... // I'd have made a wrapper class but then I'd need to redirect every single // method (or dynamic cast everywhere else), so.. no thanks. -using DynamicMessageType = DynamicType; - +using DynamicMessage = DynamicData; } // namespace dynamic_typesupport } // namespace rclcpp diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index 59115f7e45..3520179a56 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -36,7 +36,7 @@ namespace dynamic_typesupport // NOTE(methylDragon): We just alias the type in this case... // I'd have made a wrapper class but then I'd need to redirect every single // method (or dynamic cast everywhere else), so.. no thanks. -using DynamicMessage = DynamicData; +using DynamicMessageType = DynamicType; } // namespace dynamic_typesupport diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp index 8fc96744b7..596dead05f 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -145,6 +145,12 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this serialization_support); /// Move constructor diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp index 5e3dbaeb0f..60cd03968f 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp @@ -282,6 +282,30 @@ class DynamicTypeBuilder : public std::enable_shared_from_this #include +#include "rosidl_runtime_c/type_description_utils.h" #include #include @@ -225,7 +226,7 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( DynamicSerializationSupport::SharedPtr serialization_support, DynamicMessageType::SharedPtr dynamic_message_type, DynamicMessage::SharedPtr dynamic_message, - const rosidl_runtime_c__type_description__TypeDescription * description) + rosidl_runtime_c__type_description__TypeDescription * description) { bool middleware_supports_type_discovery = rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY); @@ -242,8 +243,11 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( } // NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members - // are they're managed by the passed in SharedPtr wrapper classes - rosidl_message_type_support_ = std::make_shared(); + // are managed by the passed in SharedPtr wrapper classes + rosidl_message_type_support_.reset( + new rosidl_message_type_support_t(), + [](rosidl_message_type_support_t * ts) -> void {free(const_cast(ts->data));} + ); if (!rosidl_message_type_support_) { RCUTILS_LOG_ERROR_NAMED( @@ -270,26 +274,8 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( ts_impl->serialization_support = serialization_support->get_rosidl_serialization_support(); ts_impl->dynamic_type = dynamic_message_type->get_rosidl_dynamic_type(); ts_impl->dynamic_data = dynamic_message->get_rosidl_dynamic_data(); + ts_impl->description = description; rosidl_message_type_support_->func = get_message_typesupport_handle_function; - - if (description) { - ts_impl->description = rosidl_runtime_c__type_description__TypeDescription__create(); - if (ts_impl->description == NULL) { - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, - "Could not create type description to assign into"); - rosidl_message_type_support_.reset(); - } - - if (!rosidl_runtime_c__type_description__TypeDescription__copy( - description, ts_impl->description)) - { - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, - "Could not copy type description"); - rosidl_message_type_support_.reset(); - } - } } @@ -397,3 +383,14 @@ DynamicMessageTypeSupport::get_shared_dynamic_message() const { return dynamic_message_; } + + +// METHODS ========================================================================================= +void +DynamicMessageTypeSupport::print_description() const +{ + if (!description_) { + RCUTILS_LOG_ERROR("Can't print description, no bound description!"); + } + rosidl_runtime_c_type_description_utils_print_type_description(description_.get()); +} diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp index 5cec3d7904..6f205ffe2b 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp @@ -490,3 +490,47 @@ DynamicTypeBuilder::add_complex_bounded_sequence_member( get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), nested_type.get_rosidl_dynamic_type(), sequence_bound); } + + +void +DynamicTypeBuilder::add_complex_member_builder( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicTypeBuilder & nested_type_builder) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_member_builder( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + nested_type_builder.get_rosidl_dynamic_type_builder()); +} + + +void +DynamicTypeBuilder::add_complex_array_member_builder( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicTypeBuilder & nested_type_builder, size_t array_length) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_array_member_builder( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + nested_type_builder.get_rosidl_dynamic_type_builder(), array_length); +} + + +void +DynamicTypeBuilder::add_complex_unbounded_sequence_member_builder( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicTypeBuilder & nested_type_builder) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_unbounded_sequence_member_builder( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + nested_type_builder.get_rosidl_dynamic_type_builder()); +} + + +void +DynamicTypeBuilder::add_complex_bounded_sequence_member_builder( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + DynamicTypeBuilder & nested_type_builder, size_t sequence_bound) +{ + rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_bounded_sequence_member_builder( + get_rosidl_dynamic_type_builder(), id, name.c_str(), name.size(), + nested_type_builder.get_rosidl_dynamic_type_builder(), sequence_bound); +} From 0ce81c4feddba7154e13b1676d00a1b036aabdad Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 6 Dec 2022 14:54:32 -0800 Subject: [PATCH 06/27] Implement first cut Signed-off-by: methylDragon --- rclcpp/CMakeLists.txt | 1 + .../include/rclcpp/generic_subscription.hpp | 18 ++ rclcpp/include/rclcpp/rclcpp.hpp | 2 + .../rclcpp/runtime_type_subscription.hpp | 182 ++++++++++++++++++ rclcpp/include/rclcpp/subscription.hpp | 37 ++++ rclcpp/include/rclcpp/subscription_base.hpp | 63 +++++- rclcpp/src/rclcpp/executor.cpp | 46 +++++ rclcpp/src/rclcpp/generic_subscription.cpp | 40 +++- .../src/rclcpp/runtime_type_subscription.cpp | 117 +++++++++++ rclcpp/src/rclcpp/subscription_base.cpp | 23 ++- .../node_interfaces/test_node_topics.cpp | 7 + 11 files changed, 531 insertions(+), 5 deletions(-) create mode 100644 rclcpp/include/rclcpp/runtime_type_subscription.hpp create mode 100644 rclcpp/src/rclcpp/runtime_type_subscription.cpp diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index 848fbec174..faca3daa0b 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -100,6 +100,7 @@ set(${PROJECT_NAME}_SRCS src/rclcpp/qos.cpp src/rclcpp/event_handler.cpp src/rclcpp/qos_overriding_options.cpp + src/rclcpp/runtime_type_subscription.cpp src/rclcpp/serialization.cpp src/rclcpp/serialized_message.cpp src/rclcpp/service.cpp diff --git a/rclcpp/include/rclcpp/generic_subscription.hpp b/rclcpp/include/rclcpp/generic_subscription.hpp index 12a1c79f8f..6ab7d083eb 100644 --- a/rclcpp/include/rclcpp/generic_subscription.hpp +++ b/rclcpp/include/rclcpp/generic_subscription.hpp @@ -123,6 +123,24 @@ class GenericSubscription : public rclcpp::SubscriptionBase RCLCPP_PUBLIC void return_serialized_message(std::shared_ptr & message) override; + + // RUNTIME TYPE ================================================================================== + // TODO(methylDragon): Reorder later + RCLCPP_PUBLIC + std::shared_ptr get_dynamic_type() override; + + RCLCPP_PUBLIC + std::shared_ptr get_dynamic_data() override; + + RCLCPP_PUBLIC + std::shared_ptr get_serialization_support() override; + + RCLCPP_PUBLIC + void handle_runtime_type_message( + const std::shared_ptr & ser, + const std::shared_ptr & dyn_data, + const rclcpp::MessageInfo & message_info) override; + private: RCLCPP_DISABLE_COPY(GenericSubscription) diff --git a/rclcpp/include/rclcpp/rclcpp.hpp b/rclcpp/include/rclcpp/rclcpp.hpp index d84610d159..e2793dced8 100644 --- a/rclcpp/include/rclcpp/rclcpp.hpp +++ b/rclcpp/include/rclcpp/rclcpp.hpp @@ -183,4 +183,6 @@ #include "rclcpp/waitable.hpp" #include "rclcpp/wait_set.hpp" +#include "rclcpp/runtime_type_subscription.hpp" + #endif // RCLCPP__RCLCPP_HPP_ diff --git a/rclcpp/include/rclcpp/runtime_type_subscription.hpp b/rclcpp/include/rclcpp/runtime_type_subscription.hpp new file mode 100644 index 0000000000..a9ee646e88 --- /dev/null +++ b/rclcpp/include/rclcpp/runtime_type_subscription.hpp @@ -0,0 +1,182 @@ +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RCLCPP__RUNTIME_TYPE_SUBSCRIPTION_HPP_ +#define RCLCPP__RUNTIME_TYPE_SUBSCRIPTION_HPP_ + +#include +#include +#include + +#include "rcpputils/shared_library.hpp" + +#include "rclcpp/callback_group.hpp" +#include "rclcpp/macros.hpp" +#include "rclcpp/node_interfaces/node_base_interface.hpp" +#include "rclcpp/node_interfaces/node_topics_interface.hpp" +#include "rclcpp/qos.hpp" +#include "rclcpp/serialized_message.hpp" +#include "rclcpp/subscription_base.hpp" +#include "rclcpp/typesupport_helpers.hpp" +#include "rclcpp/visibility_control.hpp" + +namespace rclcpp +{ + +/// %Subscription for messages whose type descriptions are obtained at runtime. +/** + * Since the type is not known at compile time, this is not a template, and the dynamic library + * containing type support information has to be identified and loaded based on the type name. + * + * NOTE(methylDragon): No considerations for intra-process handling are made. + */ +class RuntimeTypeSubscription : public rclcpp::SubscriptionBase +{ +public: + // cppcheck-suppress unknownMacro + RCLCPP_SMART_PTR_DEFINITIONS(RuntimeTypeSubscription) + + template> + RuntimeTypeSubscription( + rclcpp::node_interfaces::NodeBaseInterface * node_base, + rosidl_message_type_support_t & type_support_handle, + const std::string & topic_name, + const rclcpp::QoS & qos, + // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the ser + // support and DynamicData, and pass that to the callback + std::function, std::shared_ptr + )> callback, + const rclcpp::SubscriptionOptionsWithAllocator & options, + bool use_take_runtime_type_message = false) + : SubscriptionBase( + node_base, + type_support_handle, + topic_name, + options.to_rcl_subscription_options(qos), + options.event_callbacks, + options.use_default_callbacks, + false, + true, + use_take_runtime_type_message), + ts_(type_support_handle), + callback_(callback) + { + if(type_support_handle.typesupport_identifier + != rmw_typesupport_runtime_type_introspection_c__identifier) + { + throw std::runtime_error( + "RuntimeTypeSubscription must use runtime type introspection type support!"); + } + } + + // TODO(methylDragon): + /// Deferred type description constructor, only usable if the middleware implementation supports + /// type discovery + // template> + // RuntimeTypeSubscription( + // rclcpp::node_interfaces::NodeBaseInterface * node_base, + // const std::string & topic_name, + // const rclcpp::QoS & qos, + // // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the ser + // // support and DynamicData, and pass that to the callback + // std::function, std::shared_ptr + // )> callback, + // const rclcpp::SubscriptionOptionsWithAllocator & options, + // const char * serialization_lib_name = nullptr) + // : SubscriptionBase( + // node_base, + // // NOTE(methylDragon): Since the typesupport is deferred, it needs to be modified post-hoc + // // which means it technically isn't const correct... + // *rmw_get_runtime_type_message_typesupport_handle(serialization_lib_name), + // topic_name, + // options.to_rcl_subscription_options(qos), + // options.event_callbacks, + // options.use_default_callbacks, + // false, + // true), + // callback_(callback) + // {} + + RCLCPP_PUBLIC + virtual ~RuntimeTypeSubscription() = default; + + // Same as create_serialized_message() as the subscription is to serialized_messages only + RCLCPP_PUBLIC + std::shared_ptr create_message() override; + + RCLCPP_PUBLIC + std::shared_ptr create_serialized_message() override; + + /// Cast the message to a rclcpp::SerializedMessage and call the callback. + RCLCPP_PUBLIC + void handle_message( + std::shared_ptr & message, const rclcpp::MessageInfo & message_info) override; + + /// Handle dispatching rclcpp::SerializedMessage to user callback. + RCLCPP_PUBLIC + void + handle_serialized_message( + const std::shared_ptr & serialized_message, + const rclcpp::MessageInfo & message_info) override; + + /// This function is currently not implemented. + RCLCPP_PUBLIC + void handle_loaned_message( + void * loaned_message, const rclcpp::MessageInfo & message_info) override; + + // Same as return_serialized_message() as the subscription is to serialized_messages only + RCLCPP_PUBLIC + void return_message(std::shared_ptr & message) override; + + RCLCPP_PUBLIC + void return_serialized_message(std::shared_ptr & message) override; + + + // RUNTIME TYPE ================================================================================== + // TODO(methylDragon): Reorder later + RCLCPP_PUBLIC + std::shared_ptr + get_dynamic_type() override; + + RCLCPP_PUBLIC + std::shared_ptr + get_dynamic_data() override; + + RCLCPP_PUBLIC + std::shared_ptr + get_serialization_support() override; + + RCLCPP_PUBLIC + void handle_runtime_type_message( + const std::shared_ptr & ser, + const std::shared_ptr & dyn_data, + const rclcpp::MessageInfo & message_info + ) override; + + +private: + RCLCPP_DISABLE_COPY(RuntimeTypeSubscription) + + rosidl_message_type_support_t & ts_; + + std::function, std::shared_ptr + )> callback_; +}; + +} // namespace rclcpp + +#endif // RCLCPP__RUNTIME_TYPE_SUBSCRIPTION_HPP_ diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index d9e84b29f8..09f637e462 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -388,6 +388,43 @@ class Subscription : public SubscriptionBase return any_callback_.use_take_shared_method(); } + // RUNTIME TYPE ================================================================================== + // TODO(methylDragon): Reorder later + // TODO(methylDragon): Implement later... + std::shared_ptr + get_dynamic_type() override + { + throw rclcpp::exceptions::UnimplementedError( + "get_dynamic_type is not implemented for Subscription"); + } + + std::shared_ptr + get_dynamic_data() override + { + throw rclcpp::exceptions::UnimplementedError( + "get_dynamic_data is not implemented for Subscription"); + } + + std::shared_ptr + get_serialization_support() override + { + throw rclcpp::exceptions::UnimplementedError( + "get_serialization_support is not implemented for Subscription"); + } + + void + handle_runtime_type_message( + const std::shared_ptr & ser, + const std::shared_ptr & dyn_data, + const rclcpp::MessageInfo & message_info) override + { + (void) ser; + (void) dyn_data; + (void) message_info; + throw rclcpp::exceptions::UnimplementedError( + "handle_runtime_type_message is not implemented for Subscription"); + } + private: RCLCPP_DISABLE_COPY(Subscription) diff --git a/rclcpp/include/rclcpp/subscription_base.hpp b/rclcpp/include/rclcpp/subscription_base.hpp index 52057a39d2..28ac87578b 100644 --- a/rclcpp/include/rclcpp/subscription_base.hpp +++ b/rclcpp/include/rclcpp/subscription_base.hpp @@ -77,6 +77,8 @@ class SubscriptionBase : public std::enable_shared_from_this * \param[in] topic_name Name of the topic to subscribe to. * \param[in] subscription_options Options for the subscription. * \param[in] is_serialized is true if the message will be delivered still serialized + * \param[in] use_runtime_type_cb is true if the message will be taken serialized and then handled + * using dynamic type and dynamic data (type constructed at runtime) */ RCLCPP_PUBLIC SubscriptionBase( @@ -86,7 +88,12 @@ class SubscriptionBase : public std::enable_shared_from_this const rcl_subscription_options_t & subscription_options, const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks, - bool is_serialized = false); + bool is_serialized = false, + bool use_runtime_type_cb = false, + bool use_take_runtime_type_message = false); + // TODO(methylDragon): If we don't need this, remove it, + // rclcpp::node_interfaces::NodeGraphInterface * node_graph = 0, + // rclcpp::node_interfaces::NodeServicesInterface * node_services = 0); /// Destructor. RCLCPP_PUBLIC @@ -535,6 +542,54 @@ class SubscriptionBase : public std::enable_shared_from_this rclcpp::ContentFilterOptions get_content_filter() const; + // RUNTIME TYPE ================================================================================== + // TODO(methylDragon): Reorder later + RCLCPP_PUBLIC + virtual + std::shared_ptr + get_dynamic_type() = 0; + + RCLCPP_PUBLIC + virtual + std::shared_ptr + get_dynamic_data() = 0; + + RCLCPP_PUBLIC + virtual + std::shared_ptr + get_serialization_support() = 0; + + RCLCPP_PUBLIC + virtual + void + handle_runtime_type_message( + const std::shared_ptr & ser, + const std::shared_ptr & dyn_data, + const rclcpp::MessageInfo & message_info + ) = 0; + + // TODO(methylDragon): + // RCLCPP_PUBLIC + // bool + // take_runtime_type_message(ser_dynamic_data_t * message_out, rclcpp::MessageInfo & message_info_out); + + /// Return if the subscription should use runtime type + /** + * This will cause the subscription to use the handle_runtime_type_message methods, which must be + * used with take_serialized or take_runtime_type. + * + * \return `true` if the subscription should use a runtime type callback, `false` otherwise + */ + RCLCPP_PUBLIC + bool + use_runtime_type_cb() const; + + RCLCPP_PUBLIC + bool + use_take_runtime_type_message() const; + // =============================================================================================== + + protected: template void @@ -568,6 +623,10 @@ class SubscriptionBase : public std::enable_shared_from_this rclcpp::node_interfaces::NodeBaseInterface * const node_base_; + // TODO(methylDragon): Remove if we don't need this + // rclcpp::node_interfaces::NodeGraphInterface * const node_graph_; + // rclcpp::node_interfaces::NodeServicesInterface * const node_services_; + std::shared_ptr node_handle_; std::shared_ptr subscription_handle_; std::shared_ptr intra_process_subscription_handle_; @@ -588,6 +647,8 @@ class SubscriptionBase : public std::enable_shared_from_this rosidl_message_type_support_t type_support_; bool is_serialized_; + bool use_runtime_type_cb_; + bool use_take_runtime_type_message_; std::atomic subscription_in_use_by_wait_set_{false}; std::atomic intra_process_subscription_waitable_in_use_by_wait_set_{false}; diff --git a/rclcpp/src/rclcpp/executor.cpp b/rclcpp/src/rclcpp/executor.cpp index 9bafbe3106..d9c0641662 100644 --- a/rclcpp/src/rclcpp/executor.cpp +++ b/rclcpp/src/rclcpp/executor.cpp @@ -601,6 +601,52 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) rclcpp::MessageInfo message_info; message_info.get_rmw_message_info().from_intra_process = false; + // PROPOSED ====================================================================================== + // If a subscription is meant to use_runtime_type_cb, then it will use its serialization-specific + // dynamic data. + // + // Two cases: + // - Runtime type subscription using dynamic type stored in its own internal type support struct + // - Non-runtime type subscription with no stored dynamic type + // - Subscriptions of this type must be able to lookup the local message description to + // generate a dynamic type at runtime! + // - TODO(methylDragon): I won't be handling this case yet + // + // TODO(methylDragon): + // - use_runtime_type_cb (can use take_serialized or take_runtime_type) + // - take_runtime_type (MUST have use_runtime_type_cb true) + if (subscription->use_runtime_type_cb()) { + if (subscription->use_take_runtime_type_message()) { + // TODO(methylDragon) + throw rclcpp::exceptions::UnimplementedError("take_runtime_type_message is not implemented"); + } else { + std::shared_ptr serialized_msg = subscription->create_serialized_message(); + take_and_do_error_handling( + "taking a serialized message from topic", + subscription->get_topic_name(), + [&]() {return subscription->take_serialized(*serialized_msg.get(), message_info);}, + [&]() + { + std::shared_ptr ser = subscription->get_serialization_support(); + std::shared_ptr dyn_data = subscription->get_dynamic_data(); + + // NOTE(methylDragon): We might want to consider cloning the dynamic data here + + rcl_ret_t ret = rmw_serialized_to_dynamic_data( + &serialized_msg->get_rcl_serialized_message(), dyn_data.get()); + + if (ret != RMW_RET_OK) { + throw_from_rcl_error(ret, "Couldn't convert serialized message to dynamic data!"); + } + subscription->handle_runtime_type_message(ser, dyn_data, message_info); + } + ); + subscription->return_serialized_message(serialized_msg); + } + return; + } + // =============================================================================================== + if (subscription->is_serialized()) { // This is the case where a copy of the serialized message is taken from // the middleware via inter-process communication. diff --git a/rclcpp/src/rclcpp/generic_subscription.cpp b/rclcpp/src/rclcpp/generic_subscription.cpp index cc50955773..0209511951 100644 --- a/rclcpp/src/rclcpp/generic_subscription.cpp +++ b/rclcpp/src/rclcpp/generic_subscription.cpp @@ -43,8 +43,7 @@ void GenericSubscription::handle_message( "handle_message is not implemented for GenericSubscription"); } -void -GenericSubscription::handle_serialized_message( +void GenericSubscription::handle_serialized_message( const std::shared_ptr & message, const rclcpp::MessageInfo &) { @@ -72,4 +71,41 @@ void GenericSubscription::return_serialized_message( message.reset(); } + +// RUNTIME TYPE ================================================================================== +// TODO(methylDragon): Reorder later +std::shared_ptr +GenericSubscription::get_dynamic_type() +{ + throw rclcpp::exceptions::UnimplementedError( + "get_dynamic_type is not implemented for GenericSubscription"); +} + +std::shared_ptr +GenericSubscription::get_dynamic_data() +{ + throw rclcpp::exceptions::UnimplementedError( + "get_dynamic_data is not implemented for GenericSubscription"); +} + +std::shared_ptr +GenericSubscription::get_serialization_support() +{ + throw rclcpp::exceptions::UnimplementedError( + "get_serialization_support is not implemented for GenericSubscription"); +} + +void +GenericSubscription::handle_runtime_type_message( + const std::shared_ptr & ser, + const std::shared_ptr & dyn_data, + const rclcpp::MessageInfo & message_info) +{ + (void) ser; + (void) dyn_data; + (void) message_info; + throw rclcpp::exceptions::UnimplementedError( + "handle_runtime_type_message is not implemented for GenericSubscription"); +} + } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/runtime_type_subscription.cpp b/rclcpp/src/rclcpp/runtime_type_subscription.cpp new file mode 100644 index 0000000000..9edfa5a0f1 --- /dev/null +++ b/rclcpp/src/rclcpp/runtime_type_subscription.cpp @@ -0,0 +1,117 @@ +// Copyright 2022 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "rclcpp/runtime_type_subscription.hpp" + +#include +#include + +#include "rcl/subscription.h" + +#include "rclcpp/exceptions.hpp" + +namespace rclcpp +{ + +std::shared_ptr RuntimeTypeSubscription::create_message() +{ + return create_serialized_message(); +} + +std::shared_ptr RuntimeTypeSubscription::create_serialized_message() +{ + return std::make_shared(0); +} + +void RuntimeTypeSubscription::handle_message( + std::shared_ptr &, const rclcpp::MessageInfo &) +{ + throw rclcpp::exceptions::UnimplementedError( + "handle_message is not implemented for RuntimeTypeSubscription"); +} + +void RuntimeTypeSubscription::handle_serialized_message( + const std::shared_ptr &, const rclcpp::MessageInfo &) +{ + throw rclcpp::exceptions::UnimplementedError( + "handle_serialized_message is not implemented for RuntimeTypeSubscription"); +} + +void RuntimeTypeSubscription::handle_loaned_message( + void *, const rclcpp::MessageInfo &) +{ + throw rclcpp::exceptions::UnimplementedError( + "handle_loaned_message is not implemented for RuntimeTypeSubscription"); +} + +void RuntimeTypeSubscription::return_message(std::shared_ptr & message) +{ + auto typed_message = std::static_pointer_cast(message); + return_serialized_message(typed_message); +} + +void RuntimeTypeSubscription::return_serialized_message( + std::shared_ptr & message) +{ + message.reset(); +} + + +// RUNTIME TYPE ==================================================================================== +// TODO(methylDragon): Re-order later +std::shared_ptr +RuntimeTypeSubscription::get_dynamic_type() +{ + auto ts_impl = (runtime_type_ts_impl_t *)(ts_.data); + + // no-op deleter because the lifetime is managed by the typesupport outside + return std::shared_ptr( + ts_impl->dynamic_type, [](ser_dynamic_type_t *){} + ); +}; + +// NOTE(methylDragon): Should we store a separate copy of dynamic data in the sub so it isn't tied +// to the typesupport instead? +// If that's the case, will there ever be a lifetime contention between a sub +// that manages the data and the callback/user usage of the data? +std::shared_ptr +RuntimeTypeSubscription::get_dynamic_data() +{ + auto ts_impl = (runtime_type_ts_impl_t *)(ts_.data); + + // no-op deleter because the lifetime is managed by the typesupport outside + return std::shared_ptr( + ts_impl->dynamic_data, [](ser_dynamic_data_t *){} + ); +}; + +std::shared_ptr RuntimeTypeSubscription::get_serialization_support() +{ + auto ts_impl = (runtime_type_ts_impl_t *)(ts_.data); + + // no-op deleter because the lifetime is managed by the typesupport outside + return std::shared_ptr( + ts_impl->ser, [](serialization_support_t *){} + ); +}; + +void RuntimeTypeSubscription::handle_runtime_type_message( + const std::shared_ptr & ser, + const std::shared_ptr & dyn_data, + const rclcpp::MessageInfo &) +{ + callback_(ser, dyn_data); +} + +} // namespace rclcpp diff --git a/rclcpp/src/rclcpp/subscription_base.cpp b/rclcpp/src/rclcpp/subscription_base.cpp index e95cb4ac49..241dbc0124 100644 --- a/rclcpp/src/rclcpp/subscription_base.cpp +++ b/rclcpp/src/rclcpp/subscription_base.cpp @@ -41,7 +41,9 @@ SubscriptionBase::SubscriptionBase( const rcl_subscription_options_t & subscription_options, const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks, - bool is_serialized) + bool is_serialized, + bool use_runtime_type_cb, + bool use_take_runtime_type_message) : node_base_(node_base), node_handle_(node_base_->get_shared_rcl_node_handle()), node_logger_(rclcpp::get_node_logger(node_handle_.get())), @@ -49,7 +51,9 @@ SubscriptionBase::SubscriptionBase( intra_process_subscription_id_(0), event_callbacks_(event_callbacks), type_support_(type_support_handle), - is_serialized_(is_serialized) + is_serialized_(is_serialized), + use_runtime_type_cb_(use_runtime_type_cb), + use_take_runtime_type_message_(use_take_runtime_type_message) { auto custom_deletor = [node_handle = this->node_handle_](rcl_subscription_t * rcl_subs) { @@ -515,3 +519,18 @@ SubscriptionBase::get_content_filter() const return ret_options; } + + +// RUNTIME TYPE ================================================================================== +// TODO(methylDragon): Reorder later +bool +SubscriptionBase::use_runtime_type_cb() const +{ + return use_runtime_type_cb_; +} + +bool +SubscriptionBase::use_take_runtime_type_message() const +{ + return use_take_runtime_type_message_; +} diff --git a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp index ecfc89a6aa..b0664aff9b 100644 --- a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp +++ b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp @@ -77,6 +77,13 @@ class TestSubscription : public rclcpp::SubscriptionBase const std::shared_ptr &, const rclcpp::MessageInfo &) override {} void return_message(std::shared_ptr &) override {} void return_serialized_message(std::shared_ptr &) override {} + + std::shared_ptr get_dynamic_type() override {return nullptr;} + std::shared_ptr get_dynamic_data() override {return nullptr;} + std::shared_ptr get_serialization_support() override {return nullptr;} + void handle_runtime_type_message( + const std::shared_ptr &, const std::shared_ptr &, + const rclcpp::MessageInfo &) override {} }; class TestNodeTopics : public ::testing::Test From 5af57f8010b3a02200e1a500aa206285838078eb Mon Sep 17 00:00:00 2001 From: methylDragon Date: Mon, 27 Feb 2023 14:08:56 -0800 Subject: [PATCH 07/27] Migrate to rosidl_dynamic_typesupport and update field IDs Signed-off-by: methylDragon --- rclcpp/CMakeLists.txt | 2 +- ...scription.hpp => dynamic_subscription.hpp} | 50 ++++++++-------- .../include/rclcpp/generic_subscription.hpp | 12 ++-- rclcpp/include/rclcpp/rclcpp.hpp | 2 +- rclcpp/include/rclcpp/subscription.hpp | 16 ++--- rclcpp/include/rclcpp/subscription_base.hpp | 32 +++++----- ...scription.cpp => dynamic_subscription.cpp} | 58 +++++++++---------- rclcpp/src/rclcpp/executor.cpp | 18 +++--- rclcpp/src/rclcpp/generic_subscription.cpp | 16 ++--- rclcpp/src/rclcpp/subscription_base.cpp | 16 ++--- .../node_interfaces/test_node_topics.cpp | 10 ++-- rclcpp/test/rclcpp/test_generic_pubsub.cpp | 4 +- 12 files changed, 118 insertions(+), 118 deletions(-) rename rclcpp/include/rclcpp/{runtime_type_subscription.hpp => dynamic_subscription.hpp} (76%) rename rclcpp/src/rclcpp/{runtime_type_subscription.cpp => dynamic_subscription.cpp} (53%) diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index faca3daa0b..2a36c5fc07 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -100,7 +100,7 @@ set(${PROJECT_NAME}_SRCS src/rclcpp/qos.cpp src/rclcpp/event_handler.cpp src/rclcpp/qos_overriding_options.cpp - src/rclcpp/runtime_type_subscription.cpp + src/rclcpp/dynamic_subscription.cpp src/rclcpp/serialization.cpp src/rclcpp/serialized_message.cpp src/rclcpp/service.cpp diff --git a/rclcpp/include/rclcpp/runtime_type_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp similarity index 76% rename from rclcpp/include/rclcpp/runtime_type_subscription.hpp rename to rclcpp/include/rclcpp/dynamic_subscription.hpp index a9ee646e88..018abc80bf 100644 --- a/rclcpp/include/rclcpp/runtime_type_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RCLCPP__RUNTIME_TYPE_SUBSCRIPTION_HPP_ -#define RCLCPP__RUNTIME_TYPE_SUBSCRIPTION_HPP_ +#ifndef RCLCPP__DYNAMIC_SUBSCRIPTION_HPP_ +#define RCLCPP__DYNAMIC_SUBSCRIPTION_HPP_ #include #include @@ -41,25 +41,25 @@ namespace rclcpp * * NOTE(methylDragon): No considerations for intra-process handling are made. */ -class RuntimeTypeSubscription : public rclcpp::SubscriptionBase +class DynamicSubscription : public rclcpp::SubscriptionBase { public: // cppcheck-suppress unknownMacro - RCLCPP_SMART_PTR_DEFINITIONS(RuntimeTypeSubscription) + RCLCPP_SMART_PTR_DEFINITIONS(DynamicSubscription) template> - RuntimeTypeSubscription( + DynamicSubscription( rclcpp::node_interfaces::NodeBaseInterface * node_base, rosidl_message_type_support_t & type_support_handle, const std::string & topic_name, const rclcpp::QoS & qos, - // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the ser + // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the serialization_support // support and DynamicData, and pass that to the callback std::function, std::shared_ptr + std::shared_ptr, std::shared_ptr )> callback, const rclcpp::SubscriptionOptionsWithAllocator & options, - bool use_take_runtime_type_message = false) + bool use_take_dynamic_message = false) : SubscriptionBase( node_base, type_support_handle, @@ -69,15 +69,15 @@ class RuntimeTypeSubscription : public rclcpp::SubscriptionBase options.use_default_callbacks, false, true, - use_take_runtime_type_message), + use_take_dynamic_message), ts_(type_support_handle), callback_(callback) { if(type_support_handle.typesupport_identifier - != rmw_typesupport_runtime_type_introspection_c__identifier) + != rmw_dynamic_typesupport_c__identifier) { throw std::runtime_error( - "RuntimeTypeSubscription must use runtime type introspection type support!"); + "DynamicSubscription must use runtime type introspection type support!"); } } @@ -85,14 +85,14 @@ class RuntimeTypeSubscription : public rclcpp::SubscriptionBase /// Deferred type description constructor, only usable if the middleware implementation supports /// type discovery // template> - // RuntimeTypeSubscription( + // DynamicSubscription( // rclcpp::node_interfaces::NodeBaseInterface * node_base, // const std::string & topic_name, // const rclcpp::QoS & qos, - // // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the ser + // // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the serialization_support // // support and DynamicData, and pass that to the callback // std::function, std::shared_ptr + // std::shared_ptr, std::shared_ptr // )> callback, // const rclcpp::SubscriptionOptionsWithAllocator & options, // const char * serialization_lib_name = nullptr) @@ -100,7 +100,7 @@ class RuntimeTypeSubscription : public rclcpp::SubscriptionBase // node_base, // // NOTE(methylDragon): Since the typesupport is deferred, it needs to be modified post-hoc // // which means it technically isn't const correct... - // *rmw_get_runtime_type_message_typesupport_handle(serialization_lib_name), + // *rmw_get_dynamic_message_typesupport_handle(serialization_lib_name), // topic_name, // options.to_rcl_subscription_options(qos), // options.event_callbacks, @@ -111,7 +111,7 @@ class RuntimeTypeSubscription : public rclcpp::SubscriptionBase // {} RCLCPP_PUBLIC - virtual ~RuntimeTypeSubscription() = default; + virtual ~DynamicSubscription() = default; // Same as create_serialized_message() as the subscription is to serialized_messages only RCLCPP_PUBLIC @@ -148,35 +148,35 @@ class RuntimeTypeSubscription : public rclcpp::SubscriptionBase // RUNTIME TYPE ================================================================================== // TODO(methylDragon): Reorder later RCLCPP_PUBLIC - std::shared_ptr + std::shared_ptr get_dynamic_type() override; RCLCPP_PUBLIC - std::shared_ptr + std::shared_ptr get_dynamic_data() override; RCLCPP_PUBLIC - std::shared_ptr + std::shared_ptr get_serialization_support() override; RCLCPP_PUBLIC - void handle_runtime_type_message( - const std::shared_ptr & ser, - const std::shared_ptr & dyn_data, + void handle_dynamic_message( + const std::shared_ptr & serialization_support, + const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info ) override; private: - RCLCPP_DISABLE_COPY(RuntimeTypeSubscription) + RCLCPP_DISABLE_COPY(DynamicSubscription) rosidl_message_type_support_t & ts_; std::function, std::shared_ptr + std::shared_ptr, std::shared_ptr )> callback_; }; } // namespace rclcpp -#endif // RCLCPP__RUNTIME_TYPE_SUBSCRIPTION_HPP_ +#endif // RCLCPP__DYNAMIC_SUBSCRIPTION_HPP_ diff --git a/rclcpp/include/rclcpp/generic_subscription.hpp b/rclcpp/include/rclcpp/generic_subscription.hpp index 6ab7d083eb..232a8a93bf 100644 --- a/rclcpp/include/rclcpp/generic_subscription.hpp +++ b/rclcpp/include/rclcpp/generic_subscription.hpp @@ -127,18 +127,18 @@ class GenericSubscription : public rclcpp::SubscriptionBase // RUNTIME TYPE ================================================================================== // TODO(methylDragon): Reorder later RCLCPP_PUBLIC - std::shared_ptr get_dynamic_type() override; + std::shared_ptr get_dynamic_type() override; RCLCPP_PUBLIC - std::shared_ptr get_dynamic_data() override; + std::shared_ptr get_dynamic_data() override; RCLCPP_PUBLIC - std::shared_ptr get_serialization_support() override; + std::shared_ptr get_serialization_support() override; RCLCPP_PUBLIC - void handle_runtime_type_message( - const std::shared_ptr & ser, - const std::shared_ptr & dyn_data, + void handle_dynamic_message( + const std::shared_ptr & serialization_support, + const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info) override; private: diff --git a/rclcpp/include/rclcpp/rclcpp.hpp b/rclcpp/include/rclcpp/rclcpp.hpp index e2793dced8..c68d0b8f0d 100644 --- a/rclcpp/include/rclcpp/rclcpp.hpp +++ b/rclcpp/include/rclcpp/rclcpp.hpp @@ -183,6 +183,6 @@ #include "rclcpp/waitable.hpp" #include "rclcpp/wait_set.hpp" -#include "rclcpp/runtime_type_subscription.hpp" +#include "rclcpp/dynamic_subscription.hpp" #endif // RCLCPP__RCLCPP_HPP_ diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index 09f637e462..512babc3ed 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -391,21 +391,21 @@ class Subscription : public SubscriptionBase // RUNTIME TYPE ================================================================================== // TODO(methylDragon): Reorder later // TODO(methylDragon): Implement later... - std::shared_ptr + std::shared_ptr get_dynamic_type() override { throw rclcpp::exceptions::UnimplementedError( "get_dynamic_type is not implemented for Subscription"); } - std::shared_ptr + std::shared_ptr get_dynamic_data() override { throw rclcpp::exceptions::UnimplementedError( "get_dynamic_data is not implemented for Subscription"); } - std::shared_ptr + std::shared_ptr get_serialization_support() override { throw rclcpp::exceptions::UnimplementedError( @@ -413,16 +413,16 @@ class Subscription : public SubscriptionBase } void - handle_runtime_type_message( - const std::shared_ptr & ser, - const std::shared_ptr & dyn_data, + handle_dynamic_message( + const std::shared_ptr & serialization_support, + const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info) override { - (void) ser; + (void) serialization_support; (void) dyn_data; (void) message_info; throw rclcpp::exceptions::UnimplementedError( - "handle_runtime_type_message is not implemented for Subscription"); + "handle_dynamic_message is not implemented for Subscription"); } private: diff --git a/rclcpp/include/rclcpp/subscription_base.hpp b/rclcpp/include/rclcpp/subscription_base.hpp index 28ac87578b..53c2339be8 100644 --- a/rclcpp/include/rclcpp/subscription_base.hpp +++ b/rclcpp/include/rclcpp/subscription_base.hpp @@ -77,7 +77,7 @@ class SubscriptionBase : public std::enable_shared_from_this * \param[in] topic_name Name of the topic to subscribe to. * \param[in] subscription_options Options for the subscription. * \param[in] is_serialized is true if the message will be delivered still serialized - * \param[in] use_runtime_type_cb is true if the message will be taken serialized and then handled + * \param[in] use_dynamic_message_cb is true if the message will be taken serialized and then handled * using dynamic type and dynamic data (type constructed at runtime) */ RCLCPP_PUBLIC @@ -89,8 +89,8 @@ class SubscriptionBase : public std::enable_shared_from_this const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks, bool is_serialized = false, - bool use_runtime_type_cb = false, - bool use_take_runtime_type_message = false); + bool use_dynamic_message_cb = false, + bool use_take_dynamic_message = false); // TODO(methylDragon): If we don't need this, remove it, // rclcpp::node_interfaces::NodeGraphInterface * node_graph = 0, // rclcpp::node_interfaces::NodeServicesInterface * node_services = 0); @@ -546,47 +546,47 @@ class SubscriptionBase : public std::enable_shared_from_this // TODO(methylDragon): Reorder later RCLCPP_PUBLIC virtual - std::shared_ptr + std::shared_ptr get_dynamic_type() = 0; RCLCPP_PUBLIC virtual - std::shared_ptr + std::shared_ptr get_dynamic_data() = 0; RCLCPP_PUBLIC virtual - std::shared_ptr + std::shared_ptr get_serialization_support() = 0; RCLCPP_PUBLIC virtual void - handle_runtime_type_message( - const std::shared_ptr & ser, - const std::shared_ptr & dyn_data, + handle_dynamic_message( + const std::shared_ptr & serialization_support, + const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info ) = 0; // TODO(methylDragon): // RCLCPP_PUBLIC // bool - // take_runtime_type_message(ser_dynamic_data_t * message_out, rclcpp::MessageInfo & message_info_out); + // take_dynamic_message(rosidl_dynamic_typesupport_dynamic_data_t * message_out, rclcpp::MessageInfo & message_info_out); /// Return if the subscription should use runtime type /** - * This will cause the subscription to use the handle_runtime_type_message methods, which must be - * used with take_serialized or take_runtime_type. + * This will cause the subscription to use the handle_dynamic_message methods, which must be + * used with take_serialized or take_dynamic_message. * * \return `true` if the subscription should use a runtime type callback, `false` otherwise */ RCLCPP_PUBLIC bool - use_runtime_type_cb() const; + use_dynamic_message_cb() const; RCLCPP_PUBLIC bool - use_take_runtime_type_message() const; + use_take_dynamic_message() const; // =============================================================================================== @@ -647,8 +647,8 @@ class SubscriptionBase : public std::enable_shared_from_this rosidl_message_type_support_t type_support_; bool is_serialized_; - bool use_runtime_type_cb_; - bool use_take_runtime_type_message_; + bool use_dynamic_message_cb_; + bool use_take_dynamic_message_; std::atomic subscription_in_use_by_wait_set_{false}; std::atomic intra_process_subscription_waitable_in_use_by_wait_set_{false}; diff --git a/rclcpp/src/rclcpp/runtime_type_subscription.cpp b/rclcpp/src/rclcpp/dynamic_subscription.cpp similarity index 53% rename from rclcpp/src/rclcpp/runtime_type_subscription.cpp rename to rclcpp/src/rclcpp/dynamic_subscription.cpp index 9edfa5a0f1..777038659e 100644 --- a/rclcpp/src/rclcpp/runtime_type_subscription.cpp +++ b/rclcpp/src/rclcpp/dynamic_subscription.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "rclcpp/runtime_type_subscription.hpp" +#include "rclcpp/dynamic_subscription.hpp" #include #include @@ -24,44 +24,44 @@ namespace rclcpp { -std::shared_ptr RuntimeTypeSubscription::create_message() +std::shared_ptr DynamicSubscription::create_message() { return create_serialized_message(); } -std::shared_ptr RuntimeTypeSubscription::create_serialized_message() +std::shared_ptr DynamicSubscription::create_serialized_message() { return std::make_shared(0); } -void RuntimeTypeSubscription::handle_message( +void DynamicSubscription::handle_message( std::shared_ptr &, const rclcpp::MessageInfo &) { throw rclcpp::exceptions::UnimplementedError( - "handle_message is not implemented for RuntimeTypeSubscription"); + "handle_message is not implemented for DynamicSubscription"); } -void RuntimeTypeSubscription::handle_serialized_message( +void DynamicSubscription::handle_serialized_message( const std::shared_ptr &, const rclcpp::MessageInfo &) { throw rclcpp::exceptions::UnimplementedError( - "handle_serialized_message is not implemented for RuntimeTypeSubscription"); + "handle_serialized_message is not implemented for DynamicSubscription"); } -void RuntimeTypeSubscription::handle_loaned_message( +void DynamicSubscription::handle_loaned_message( void *, const rclcpp::MessageInfo &) { throw rclcpp::exceptions::UnimplementedError( - "handle_loaned_message is not implemented for RuntimeTypeSubscription"); + "handle_loaned_message is not implemented for DynamicSubscription"); } -void RuntimeTypeSubscription::return_message(std::shared_ptr & message) +void DynamicSubscription::return_message(std::shared_ptr & message) { auto typed_message = std::static_pointer_cast(message); return_serialized_message(typed_message); } -void RuntimeTypeSubscription::return_serialized_message( +void DynamicSubscription::return_serialized_message( std::shared_ptr & message) { message.reset(); @@ -70,14 +70,14 @@ void RuntimeTypeSubscription::return_serialized_message( // RUNTIME TYPE ==================================================================================== // TODO(methylDragon): Re-order later -std::shared_ptr -RuntimeTypeSubscription::get_dynamic_type() +std::shared_ptr +DynamicSubscription::get_dynamic_type() { - auto ts_impl = (runtime_type_ts_impl_t *)(ts_.data); + auto ts_impl = (rmw_dynamic_typesupport_impl_t *)(ts_.data); // no-op deleter because the lifetime is managed by the typesupport outside - return std::shared_ptr( - ts_impl->dynamic_type, [](ser_dynamic_type_t *){} + return std::shared_ptr( + ts_impl->dynamic_type, [](rosidl_dynamic_typesupport_dynamic_type_t *){} ); }; @@ -85,33 +85,33 @@ RuntimeTypeSubscription::get_dynamic_type() // to the typesupport instead? // If that's the case, will there ever be a lifetime contention between a sub // that manages the data and the callback/user usage of the data? -std::shared_ptr -RuntimeTypeSubscription::get_dynamic_data() +std::shared_ptr +DynamicSubscription::get_dynamic_data() { - auto ts_impl = (runtime_type_ts_impl_t *)(ts_.data); + auto ts_impl = (rmw_dynamic_typesupport_impl_t *)(ts_.data); // no-op deleter because the lifetime is managed by the typesupport outside - return std::shared_ptr( - ts_impl->dynamic_data, [](ser_dynamic_data_t *){} + return std::shared_ptr( + ts_impl->dynamic_data, [](rosidl_dynamic_typesupport_dynamic_data_t *){} ); }; -std::shared_ptr RuntimeTypeSubscription::get_serialization_support() +std::shared_ptr DynamicSubscription::get_serialization_support() { - auto ts_impl = (runtime_type_ts_impl_t *)(ts_.data); + auto ts_impl = (rmw_dynamic_typesupport_impl_t *)(ts_.data); // no-op deleter because the lifetime is managed by the typesupport outside - return std::shared_ptr( - ts_impl->ser, [](serialization_support_t *){} + return std::shared_ptr( + ts_impl->serialization_support, [](rosidl_dynamic_typesupport_serialization_support_t *){} ); }; -void RuntimeTypeSubscription::handle_runtime_type_message( - const std::shared_ptr & ser, - const std::shared_ptr & dyn_data, +void DynamicSubscription::handle_dynamic_message( + const std::shared_ptr & serialization_support, + const std::shared_ptr & dyn_data, const rclcpp::MessageInfo &) { - callback_(ser, dyn_data); + callback_(serialization_support, dyn_data); } } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/executor.cpp b/rclcpp/src/rclcpp/executor.cpp index d9c0641662..84f7f1d7a0 100644 --- a/rclcpp/src/rclcpp/executor.cpp +++ b/rclcpp/src/rclcpp/executor.cpp @@ -602,7 +602,7 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) message_info.get_rmw_message_info().from_intra_process = false; // PROPOSED ====================================================================================== - // If a subscription is meant to use_runtime_type_cb, then it will use its serialization-specific + // If a subscription is meant to use_dynamic_message_cb, then it will use its serialization-specific // dynamic data. // // Two cases: @@ -613,12 +613,12 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) // - TODO(methylDragon): I won't be handling this case yet // // TODO(methylDragon): - // - use_runtime_type_cb (can use take_serialized or take_runtime_type) - // - take_runtime_type (MUST have use_runtime_type_cb true) - if (subscription->use_runtime_type_cb()) { - if (subscription->use_take_runtime_type_message()) { + // - use_dynamic_message_cb (can use take_serialized or take_dynamic_message) + // - take_dynamic_message (MUST have use_dynamic_message_cb true) + if (subscription->use_dynamic_message_cb()) { + if (subscription->use_take_dynamic_message()) { // TODO(methylDragon) - throw rclcpp::exceptions::UnimplementedError("take_runtime_type_message is not implemented"); + throw rclcpp::exceptions::UnimplementedError("take_dynamic_message is not implemented"); } else { std::shared_ptr serialized_msg = subscription->create_serialized_message(); take_and_do_error_handling( @@ -627,8 +627,8 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) [&]() {return subscription->take_serialized(*serialized_msg.get(), message_info);}, [&]() { - std::shared_ptr ser = subscription->get_serialization_support(); - std::shared_ptr dyn_data = subscription->get_dynamic_data(); + std::shared_ptr serialization_support = subscription->get_serialization_support(); + std::shared_ptr dyn_data = subscription->get_dynamic_data(); // NOTE(methylDragon): We might want to consider cloning the dynamic data here @@ -638,7 +638,7 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) if (ret != RMW_RET_OK) { throw_from_rcl_error(ret, "Couldn't convert serialized message to dynamic data!"); } - subscription->handle_runtime_type_message(ser, dyn_data, message_info); + subscription->handle_dynamic_message(serialization_support, dyn_data, message_info); } ); subscription->return_serialized_message(serialized_msg); diff --git a/rclcpp/src/rclcpp/generic_subscription.cpp b/rclcpp/src/rclcpp/generic_subscription.cpp index 0209511951..3be4a67040 100644 --- a/rclcpp/src/rclcpp/generic_subscription.cpp +++ b/rclcpp/src/rclcpp/generic_subscription.cpp @@ -74,21 +74,21 @@ void GenericSubscription::return_serialized_message( // RUNTIME TYPE ================================================================================== // TODO(methylDragon): Reorder later -std::shared_ptr +std::shared_ptr GenericSubscription::get_dynamic_type() { throw rclcpp::exceptions::UnimplementedError( "get_dynamic_type is not implemented for GenericSubscription"); } -std::shared_ptr +std::shared_ptr GenericSubscription::get_dynamic_data() { throw rclcpp::exceptions::UnimplementedError( "get_dynamic_data is not implemented for GenericSubscription"); } -std::shared_ptr +std::shared_ptr GenericSubscription::get_serialization_support() { throw rclcpp::exceptions::UnimplementedError( @@ -96,16 +96,16 @@ GenericSubscription::get_serialization_support() } void -GenericSubscription::handle_runtime_type_message( - const std::shared_ptr & ser, - const std::shared_ptr & dyn_data, +GenericSubscription::handle_dynamic_message( + const std::shared_ptr & serialization_support, + const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info) { - (void) ser; + (void) serialization_support; (void) dyn_data; (void) message_info; throw rclcpp::exceptions::UnimplementedError( - "handle_runtime_type_message is not implemented for GenericSubscription"); + "handle_dynamic_message is not implemented for GenericSubscription"); } } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/subscription_base.cpp b/rclcpp/src/rclcpp/subscription_base.cpp index 241dbc0124..c006d6a545 100644 --- a/rclcpp/src/rclcpp/subscription_base.cpp +++ b/rclcpp/src/rclcpp/subscription_base.cpp @@ -42,8 +42,8 @@ SubscriptionBase::SubscriptionBase( const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks, bool is_serialized, - bool use_runtime_type_cb, - bool use_take_runtime_type_message) + bool use_dynamic_message_cb, + bool use_take_dynamic_message) : node_base_(node_base), node_handle_(node_base_->get_shared_rcl_node_handle()), node_logger_(rclcpp::get_node_logger(node_handle_.get())), @@ -52,8 +52,8 @@ SubscriptionBase::SubscriptionBase( event_callbacks_(event_callbacks), type_support_(type_support_handle), is_serialized_(is_serialized), - use_runtime_type_cb_(use_runtime_type_cb), - use_take_runtime_type_message_(use_take_runtime_type_message) + use_dynamic_message_cb_(use_dynamic_message_cb), + use_take_dynamic_message_(use_take_dynamic_message) { auto custom_deletor = [node_handle = this->node_handle_](rcl_subscription_t * rcl_subs) { @@ -524,13 +524,13 @@ SubscriptionBase::get_content_filter() const // RUNTIME TYPE ================================================================================== // TODO(methylDragon): Reorder later bool -SubscriptionBase::use_runtime_type_cb() const +SubscriptionBase::use_dynamic_message_cb() const { - return use_runtime_type_cb_; + return use_dynamic_message_cb_; } bool -SubscriptionBase::use_take_runtime_type_message() const +SubscriptionBase::use_take_dynamic_message() const { - return use_take_runtime_type_message_; + return use_take_dynamic_message_; } diff --git a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp index b0664aff9b..d29b51a1c8 100644 --- a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp +++ b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp @@ -78,11 +78,11 @@ class TestSubscription : public rclcpp::SubscriptionBase void return_message(std::shared_ptr &) override {} void return_serialized_message(std::shared_ptr &) override {} - std::shared_ptr get_dynamic_type() override {return nullptr;} - std::shared_ptr get_dynamic_data() override {return nullptr;} - std::shared_ptr get_serialization_support() override {return nullptr;} - void handle_runtime_type_message( - const std::shared_ptr &, const std::shared_ptr &, + std::shared_ptr get_dynamic_type() override {return nullptr;} + std::shared_ptr get_dynamic_data() override {return nullptr;} + std::shared_ptr get_serialization_support() override {return nullptr;} + void handle_dynamic_message( + const std::shared_ptr &, const std::shared_ptr &, const rclcpp::MessageInfo &) override {} }; diff --git a/rclcpp/test/rclcpp/test_generic_pubsub.cpp b/rclcpp/test/rclcpp/test_generic_pubsub.cpp index f4cef0b757..de50be4fe2 100644 --- a/rclcpp/test/rclcpp/test_generic_pubsub.cpp +++ b/rclcpp/test/rclcpp/test_generic_pubsub.cpp @@ -89,9 +89,9 @@ class RclcppGenericNodeFixture : public Test T2 message; write_message(data, message); - rclcpp::Serialization ser; + rclcpp::Serialization serialization_support; SerializedMessage result; - ser.serialize_message(&message, &result); + serialization_support.serialize_message(&message, &result); return result; } From 927b9de2a5bba9cbf7bedfafc2294f7ada6ea154 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 28 Feb 2023 13:37:52 -0800 Subject: [PATCH 08/27] Refactor dynamic typesupport to couple serialization support to objects Signed-off-by: methylDragon --- .../include/rclcpp/dynamic_subscription.hpp | 19 +++++++------------ .../include/rclcpp/generic_subscription.hpp | 3 +-- rclcpp/include/rclcpp/subscription.hpp | 4 +--- rclcpp/include/rclcpp/subscription_base.hpp | 7 +++---- rclcpp/src/rclcpp/dynamic_subscription.cpp | 7 +++---- rclcpp/src/rclcpp/executor.cpp | 10 +++++----- rclcpp/src/rclcpp/generic_subscription.cpp | 4 +--- rclcpp/src/rclcpp/subscription_base.cpp | 2 +- .../node_interfaces/test_node_topics.cpp | 2 +- 9 files changed, 23 insertions(+), 35 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp index 018abc80bf..b8c4e20e2b 100644 --- a/rclcpp/include/rclcpp/dynamic_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -53,11 +53,10 @@ class DynamicSubscription : public rclcpp::SubscriptionBase rosidl_message_type_support_t & type_support_handle, const std::string & topic_name, const rclcpp::QoS & qos, - // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the serialization_support - // support and DynamicData, and pass that to the callback - std::function, std::shared_ptr - )> callback, + // TODO(methylDragons): Eventually roll out an rclcpp::DynamicMessage that encompasses the + // serialization_support support and DynamicData, and pass that to the + // callback + std::function)> callback, const rclcpp::SubscriptionOptionsWithAllocator & options, bool use_take_dynamic_message = false) : SubscriptionBase( @@ -77,7 +76,7 @@ class DynamicSubscription : public rclcpp::SubscriptionBase != rmw_dynamic_typesupport_c__identifier) { throw std::runtime_error( - "DynamicSubscription must use runtime type introspection type support!"); + "DynamicSubscription must use dynamic type introspection type support!"); } } @@ -145,7 +144,7 @@ class DynamicSubscription : public rclcpp::SubscriptionBase void return_serialized_message(std::shared_ptr & message) override; - // RUNTIME TYPE ================================================================================== + // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later RCLCPP_PUBLIC std::shared_ptr @@ -161,7 +160,6 @@ class DynamicSubscription : public rclcpp::SubscriptionBase RCLCPP_PUBLIC void handle_dynamic_message( - const std::shared_ptr & serialization_support, const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info ) override; @@ -171,10 +169,7 @@ class DynamicSubscription : public rclcpp::SubscriptionBase RCLCPP_DISABLE_COPY(DynamicSubscription) rosidl_message_type_support_t & ts_; - - std::function, std::shared_ptr - )> callback_; + std::function)> callback_; }; } // namespace rclcpp diff --git a/rclcpp/include/rclcpp/generic_subscription.hpp b/rclcpp/include/rclcpp/generic_subscription.hpp index 232a8a93bf..b226f7e035 100644 --- a/rclcpp/include/rclcpp/generic_subscription.hpp +++ b/rclcpp/include/rclcpp/generic_subscription.hpp @@ -124,7 +124,7 @@ class GenericSubscription : public rclcpp::SubscriptionBase void return_serialized_message(std::shared_ptr & message) override; - // RUNTIME TYPE ================================================================================== + // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later RCLCPP_PUBLIC std::shared_ptr get_dynamic_type() override; @@ -137,7 +137,6 @@ class GenericSubscription : public rclcpp::SubscriptionBase RCLCPP_PUBLIC void handle_dynamic_message( - const std::shared_ptr & serialization_support, const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info) override; diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index 512babc3ed..bfe50d174d 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -388,7 +388,7 @@ class Subscription : public SubscriptionBase return any_callback_.use_take_shared_method(); } - // RUNTIME TYPE ================================================================================== + // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later // TODO(methylDragon): Implement later... std::shared_ptr @@ -414,11 +414,9 @@ class Subscription : public SubscriptionBase void handle_dynamic_message( - const std::shared_ptr & serialization_support, const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info) override { - (void) serialization_support; (void) dyn_data; (void) message_info; throw rclcpp::exceptions::UnimplementedError( diff --git a/rclcpp/include/rclcpp/subscription_base.hpp b/rclcpp/include/rclcpp/subscription_base.hpp index 53c2339be8..bfdcce330e 100644 --- a/rclcpp/include/rclcpp/subscription_base.hpp +++ b/rclcpp/include/rclcpp/subscription_base.hpp @@ -542,7 +542,7 @@ class SubscriptionBase : public std::enable_shared_from_this rclcpp::ContentFilterOptions get_content_filter() const; - // RUNTIME TYPE ================================================================================== + // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later RCLCPP_PUBLIC virtual @@ -563,7 +563,6 @@ class SubscriptionBase : public std::enable_shared_from_this virtual void handle_dynamic_message( - const std::shared_ptr & serialization_support, const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info ) = 0; @@ -573,12 +572,12 @@ class SubscriptionBase : public std::enable_shared_from_this // bool // take_dynamic_message(rosidl_dynamic_typesupport_dynamic_data_t * message_out, rclcpp::MessageInfo & message_info_out); - /// Return if the subscription should use runtime type + /// Return if the subscription should use dynamic type /** * This will cause the subscription to use the handle_dynamic_message methods, which must be * used with take_serialized or take_dynamic_message. * - * \return `true` if the subscription should use a runtime type callback, `false` otherwise + * \return `true` if the subscription should use a dynamic type callback, `false` otherwise */ RCLCPP_PUBLIC bool diff --git a/rclcpp/src/rclcpp/dynamic_subscription.cpp b/rclcpp/src/rclcpp/dynamic_subscription.cpp index 777038659e..d0a3b538c4 100644 --- a/rclcpp/src/rclcpp/dynamic_subscription.cpp +++ b/rclcpp/src/rclcpp/dynamic_subscription.cpp @@ -68,7 +68,7 @@ void DynamicSubscription::return_serialized_message( } -// RUNTIME TYPE ==================================================================================== +// DYNAMIC TYPE ==================================================================================== // TODO(methylDragon): Re-order later std::shared_ptr DynamicSubscription::get_dynamic_type() @@ -84,7 +84,7 @@ DynamicSubscription::get_dynamic_type() // NOTE(methylDragon): Should we store a separate copy of dynamic data in the sub so it isn't tied // to the typesupport instead? // If that's the case, will there ever be a lifetime contention between a sub -// that manages the data and the callback/user usage of the data? +// that manages the data and the callback/user usage of the data? std::shared_ptr DynamicSubscription::get_dynamic_data() { @@ -107,11 +107,10 @@ std::shared_ptr DynamicSubsc }; void DynamicSubscription::handle_dynamic_message( - const std::shared_ptr & serialization_support, const std::shared_ptr & dyn_data, const rclcpp::MessageInfo &) { - callback_(serialization_support, dyn_data); + callback_(dyn_data); } } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/executor.cpp b/rclcpp/src/rclcpp/executor.cpp index 84f7f1d7a0..dc9c96108a 100644 --- a/rclcpp/src/rclcpp/executor.cpp +++ b/rclcpp/src/rclcpp/executor.cpp @@ -602,12 +602,12 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) message_info.get_rmw_message_info().from_intra_process = false; // PROPOSED ====================================================================================== - // If a subscription is meant to use_dynamic_message_cb, then it will use its serialization-specific - // dynamic data. + // If a subscription is meant to use_dynamic_message_cb, then it will use its + // serialization-specific dynamic data. // // Two cases: - // - Runtime type subscription using dynamic type stored in its own internal type support struct - // - Non-runtime type subscription with no stored dynamic type + // - Dynamic type subscription using dynamic type stored in its own internal type support struct + // - Non-dynamic type subscription with no stored dynamic type // - Subscriptions of this type must be able to lookup the local message description to // generate a dynamic type at runtime! // - TODO(methylDragon): I won't be handling this case yet @@ -638,7 +638,7 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) if (ret != RMW_RET_OK) { throw_from_rcl_error(ret, "Couldn't convert serialized message to dynamic data!"); } - subscription->handle_dynamic_message(serialization_support, dyn_data, message_info); + subscription->handle_dynamic_message(dyn_data, message_info); } ); subscription->return_serialized_message(serialized_msg); diff --git a/rclcpp/src/rclcpp/generic_subscription.cpp b/rclcpp/src/rclcpp/generic_subscription.cpp index 3be4a67040..41b342748b 100644 --- a/rclcpp/src/rclcpp/generic_subscription.cpp +++ b/rclcpp/src/rclcpp/generic_subscription.cpp @@ -72,7 +72,7 @@ void GenericSubscription::return_serialized_message( } -// RUNTIME TYPE ================================================================================== +// DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later std::shared_ptr GenericSubscription::get_dynamic_type() @@ -97,11 +97,9 @@ GenericSubscription::get_serialization_support() void GenericSubscription::handle_dynamic_message( - const std::shared_ptr & serialization_support, const std::shared_ptr & dyn_data, const rclcpp::MessageInfo & message_info) { - (void) serialization_support; (void) dyn_data; (void) message_info; throw rclcpp::exceptions::UnimplementedError( diff --git a/rclcpp/src/rclcpp/subscription_base.cpp b/rclcpp/src/rclcpp/subscription_base.cpp index c006d6a545..0a37e0575d 100644 --- a/rclcpp/src/rclcpp/subscription_base.cpp +++ b/rclcpp/src/rclcpp/subscription_base.cpp @@ -521,7 +521,7 @@ SubscriptionBase::get_content_filter() const } -// RUNTIME TYPE ================================================================================== +// DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later bool SubscriptionBase::use_dynamic_message_cb() const diff --git a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp index d29b51a1c8..aeecba5683 100644 --- a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp +++ b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp @@ -82,7 +82,7 @@ class TestSubscription : public rclcpp::SubscriptionBase std::shared_ptr get_dynamic_data() override {return nullptr;} std::shared_ptr get_serialization_support() override {return nullptr;} void handle_dynamic_message( - const std::shared_ptr &, const std::shared_ptr &, + const std::shared_ptr &, const rclcpp::MessageInfo &) override {} }; From bfcc29e64b56202890d7e1e5b4c8489ef9c60785 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Wed, 22 Mar 2023 16:44:51 -0700 Subject: [PATCH 09/27] Use dynamic message type support wrappers Signed-off-by: methylDragon --- .../include/rclcpp/dynamic_subscription.hpp | 60 +++++++++++-------- .../include/rclcpp/generic_subscription.hpp | 10 ++-- rclcpp/include/rclcpp/rclcpp.hpp | 3 + rclcpp/include/rclcpp/subscription.hpp | 20 +++---- rclcpp/include/rclcpp/subscription_base.hpp | 20 ++++--- rclcpp/src/rclcpp/dynamic_subscription.cpp | 44 ++++---------- .../dynamic_typesupport/dynamic_data.cpp | 23 +++++-- rclcpp/src/rclcpp/executor.cpp | 13 ++-- rclcpp/src/rclcpp/generic_subscription.cpp | 22 +++---- .../node_interfaces/test_node_topics.cpp | 13 ++-- 10 files changed, 122 insertions(+), 106 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp index b8c4e20e2b..6822f9e210 100644 --- a/rclcpp/include/rclcpp/dynamic_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -22,6 +22,7 @@ #include "rcpputils/shared_library.hpp" #include "rclcpp/callback_group.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp" #include "rclcpp/macros.hpp" #include "rclcpp/node_interfaces/node_base_interface.hpp" #include "rclcpp/node_interfaces/node_topics_interface.hpp" @@ -50,18 +51,15 @@ class DynamicSubscription : public rclcpp::SubscriptionBase template> DynamicSubscription( rclcpp::node_interfaces::NodeBaseInterface * node_base, - rosidl_message_type_support_t & type_support_handle, + rclcpp::dynamic_typesupport::DynamicMessageTypeSupport::SharedPtr type_support, const std::string & topic_name, const rclcpp::QoS & qos, - // TODO(methylDragons): Eventually roll out an rclcpp::DynamicMessage that encompasses the - // serialization_support support and DynamicData, and pass that to the - // callback - std::function)> callback, + std::function callback, const rclcpp::SubscriptionOptionsWithAllocator & options, bool use_take_dynamic_message = false) : SubscriptionBase( node_base, - type_support_handle, + *(type_support->get_rosidl_message_type_support()), topic_name, options.to_rcl_subscription_options(qos), options.event_callbacks, @@ -69,15 +67,26 @@ class DynamicSubscription : public rclcpp::SubscriptionBase false, true, use_take_dynamic_message), - ts_(type_support_handle), - callback_(callback) + ts_(type_support), + callback_(callback), + serialization_support_(nullptr), + dynamic_message_(nullptr), + dynamic_message_type_(nullptr) { - if(type_support_handle.typesupport_identifier - != rmw_dynamic_typesupport_c__identifier) + if (!type_support) { + throw std::runtime_error("DynamicMessageTypeSupport cannot be nullptr!"); + } + + if (type_support->get_rosidl_message_type_support()->typesupport_identifier != + rmw_dynamic_typesupport_c__identifier) { throw std::runtime_error( - "DynamicSubscription must use dynamic type introspection type support!"); + "DynamicSubscription must use dynamic type introspection type support!"); } + + serialization_support_ = type_support->get_shared_dynamic_serialization_support(); + dynamic_message_type_ = type_support->get_shared_dynamic_message_type()->clone_shared(); + dynamic_message_ = type_support->get_shared_dynamic_message()->clone_shared(); } // TODO(methylDragon): @@ -91,7 +100,8 @@ class DynamicSubscription : public rclcpp::SubscriptionBase // // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the serialization_support // // support and DynamicData, and pass that to the callback // std::function, std::shared_ptr + // rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr, + // rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr // )> callback, // const rclcpp::SubscriptionOptionsWithAllocator & options, // const char * serialization_lib_name = nullptr) @@ -147,29 +157,31 @@ class DynamicSubscription : public rclcpp::SubscriptionBase // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later RCLCPP_PUBLIC - std::shared_ptr - get_dynamic_type() override; + rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr + get_shared_dynamic_message_type() override; RCLCPP_PUBLIC - std::shared_ptr - get_dynamic_data() override; + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr + get_shared_dynamic_message() override; RCLCPP_PUBLIC - std::shared_ptr - get_serialization_support() override; + rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support() override; RCLCPP_PUBLIC void handle_dynamic_message( - const std::shared_ptr & dyn_data, - const rclcpp::MessageInfo & message_info - ) override; - + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, + const rclcpp::MessageInfo & message_info) override; private: RCLCPP_DISABLE_COPY(DynamicSubscription) - rosidl_message_type_support_t & ts_; - std::function)> callback_; + rclcpp::dynamic_typesupport::DynamicMessageTypeSupport::SharedPtr ts_; + std::function callback_; + + rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr serialization_support_; + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr dynamic_message_; + rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr dynamic_message_type_; }; } // namespace rclcpp diff --git a/rclcpp/include/rclcpp/generic_subscription.hpp b/rclcpp/include/rclcpp/generic_subscription.hpp index b226f7e035..27fc363b3e 100644 --- a/rclcpp/include/rclcpp/generic_subscription.hpp +++ b/rclcpp/include/rclcpp/generic_subscription.hpp @@ -127,17 +127,19 @@ class GenericSubscription : public rclcpp::SubscriptionBase // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later RCLCPP_PUBLIC - std::shared_ptr get_dynamic_type() override; + rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr get_shared_dynamic_message_type() + override; RCLCPP_PUBLIC - std::shared_ptr get_dynamic_data() override; + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr get_shared_dynamic_message() override; RCLCPP_PUBLIC - std::shared_ptr get_serialization_support() override; + rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support() override; RCLCPP_PUBLIC void handle_dynamic_message( - const std::shared_ptr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, const rclcpp::MessageInfo & message_info) override; private: diff --git a/rclcpp/include/rclcpp/rclcpp.hpp b/rclcpp/include/rclcpp/rclcpp.hpp index c68d0b8f0d..0acbfb82b2 100644 --- a/rclcpp/include/rclcpp/rclcpp.hpp +++ b/rclcpp/include/rclcpp/rclcpp.hpp @@ -133,6 +133,9 @@ * - Dynamic typesupport * - rclcpp::dynamic_typesupport::DynamicMessageTypeSupport * - rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp + * - Dynamic subscription + * - rclcpp::DynamicSubscription + * - rclcpp/dynamic_subscription.hpp * - Generic publisher * - rclcpp::Node::create_generic_publisher() * - rclcpp::GenericPublisher diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index bfe50d174d..8888bb01e4 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -391,30 +391,30 @@ class Subscription : public SubscriptionBase // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later // TODO(methylDragon): Implement later... - std::shared_ptr - get_dynamic_type() override + rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr + get_shared_dynamic_message_type() override { throw rclcpp::exceptions::UnimplementedError( - "get_dynamic_type is not implemented for Subscription"); + "get_shared_dynamic_message_type is not implemented for Subscription"); } - std::shared_ptr - get_dynamic_data() override + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr + get_shared_dynamic_message() override { throw rclcpp::exceptions::UnimplementedError( - "get_dynamic_data is not implemented for Subscription"); + "get_shared_dynamic_message is not implemented for Subscription"); } - std::shared_ptr - get_serialization_support() override + rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support() override { throw rclcpp::exceptions::UnimplementedError( - "get_serialization_support is not implemented for Subscription"); + "get_shared_dynamic_serialization_support is not implemented for Subscription"); } void handle_dynamic_message( - const std::shared_ptr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, const rclcpp::MessageInfo & message_info) override { (void) dyn_data; diff --git a/rclcpp/include/rclcpp/subscription_base.hpp b/rclcpp/include/rclcpp/subscription_base.hpp index bfdcce330e..1b588394dd 100644 --- a/rclcpp/include/rclcpp/subscription_base.hpp +++ b/rclcpp/include/rclcpp/subscription_base.hpp @@ -31,6 +31,9 @@ #include "rclcpp/any_subscription_callback.hpp" #include "rclcpp/detail/cpp_callback_trampoline.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/experimental/intra_process_manager.hpp" #include "rclcpp/experimental/subscription_intra_process_base.hpp" #include "rclcpp/macros.hpp" @@ -546,26 +549,25 @@ class SubscriptionBase : public std::enable_shared_from_this // TODO(methylDragon): Reorder later RCLCPP_PUBLIC virtual - std::shared_ptr - get_dynamic_type() = 0; + rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr + get_shared_dynamic_message_type() = 0; RCLCPP_PUBLIC virtual - std::shared_ptr - get_dynamic_data() = 0; + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr + get_shared_dynamic_message() = 0; RCLCPP_PUBLIC virtual - std::shared_ptr - get_serialization_support() = 0; + rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support() = 0; RCLCPP_PUBLIC virtual void handle_dynamic_message( - const std::shared_ptr & dyn_data, - const rclcpp::MessageInfo & message_info - ) = 0; + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, + const rclcpp::MessageInfo & message_info) = 0; // TODO(methylDragon): // RCLCPP_PUBLIC diff --git a/rclcpp/src/rclcpp/dynamic_subscription.cpp b/rclcpp/src/rclcpp/dynamic_subscription.cpp index d0a3b538c4..17a7342d5c 100644 --- a/rclcpp/src/rclcpp/dynamic_subscription.cpp +++ b/rclcpp/src/rclcpp/dynamic_subscription.cpp @@ -34,8 +34,7 @@ std::shared_ptr DynamicSubscription::create_serialize return std::make_shared(0); } -void DynamicSubscription::handle_message( - std::shared_ptr &, const rclcpp::MessageInfo &) +void DynamicSubscription::handle_message(std::shared_ptr &, const rclcpp::MessageInfo &) { throw rclcpp::exceptions::UnimplementedError( "handle_message is not implemented for DynamicSubscription"); @@ -48,8 +47,7 @@ void DynamicSubscription::handle_serialized_message( "handle_serialized_message is not implemented for DynamicSubscription"); } -void DynamicSubscription::handle_loaned_message( - void *, const rclcpp::MessageInfo &) +void DynamicSubscription::handle_loaned_message(void *, const rclcpp::MessageInfo &) { throw rclcpp::exceptions::UnimplementedError( "handle_loaned_message is not implemented for DynamicSubscription"); @@ -70,44 +68,26 @@ void DynamicSubscription::return_serialized_message( // DYNAMIC TYPE ==================================================================================== // TODO(methylDragon): Re-order later -std::shared_ptr -DynamicSubscription::get_dynamic_type() +rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr +DynamicSubscription::get_shared_dynamic_message_type() { - auto ts_impl = (rmw_dynamic_typesupport_impl_t *)(ts_.data); - - // no-op deleter because the lifetime is managed by the typesupport outside - return std::shared_ptr( - ts_impl->dynamic_type, [](rosidl_dynamic_typesupport_dynamic_type_t *){} - ); + return dynamic_message_type_; }; -// NOTE(methylDragon): Should we store a separate copy of dynamic data in the sub so it isn't tied -// to the typesupport instead? -// If that's the case, will there ever be a lifetime contention between a sub -// that manages the data and the callback/user usage of the data? -std::shared_ptr -DynamicSubscription::get_dynamic_data() +rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr +DynamicSubscription::get_shared_dynamic_message() { - auto ts_impl = (rmw_dynamic_typesupport_impl_t *)(ts_.data); - - // no-op deleter because the lifetime is managed by the typesupport outside - return std::shared_ptr( - ts_impl->dynamic_data, [](rosidl_dynamic_typesupport_dynamic_data_t *){} - ); + return dynamic_message_; }; -std::shared_ptr DynamicSubscription::get_serialization_support() +rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr +DynamicSubscription::get_shared_dynamic_serialization_support() { - auto ts_impl = (rmw_dynamic_typesupport_impl_t *)(ts_.data); - - // no-op deleter because the lifetime is managed by the typesupport outside - return std::shared_ptr( - ts_impl->serialization_support, [](rosidl_dynamic_typesupport_serialization_support_t *){} - ); + return serialization_support_; }; void DynamicSubscription::handle_dynamic_message( - const std::shared_ptr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, const rclcpp::MessageInfo &) { callback_(dyn_data); diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp index 499a8127d8..14a446645c 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp @@ -156,7 +156,10 @@ DynamicData::DynamicData( DynamicData::DynamicData( DynamicData::SharedPtr parent_data, rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data) -: DynamicData(parent_data->get_shared_dynamic_serialization_support(), rosidl_loaned_data) +: serialization_support_(parent_data->get_shared_dynamic_serialization_support()), + rosidl_dynamic_data_(nullptr), + is_loaned_(true), + parent_data_(nullptr) { if (!parent_data) { throw std::runtime_error("parent dynamic data cannot be nullptr!"); @@ -165,8 +168,21 @@ DynamicData::DynamicData( throw std::runtime_error("loaned rosidl dynamic data cannot be nullptr!"); } + if (serialization_support_) { + if (!match_serialization_support_(*serialization_support_, *rosidl_loaned_data)) { + throw std::runtime_error( + "serialization support library identifier does not match loaned dynamic data's!"); + } + } + + rosidl_dynamic_data_.reset( + rosidl_loaned_data, + // Custom no-op deleter + [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { + // Data fini and destruction is deferred to return_loaned_value() + (void) rosidl_dynamic_data; + }); parent_data_ = parent_data; - is_loaned_ = true; } @@ -384,8 +400,7 @@ DynamicData::loan_value(rosidl_dynamic_typesupport_member_id_t id) { return DynamicData::make_shared( shared_from_this(), - rosidl_dynamic_typesupport_dynamic_data_loan_value( - get_rosidl_dynamic_data(), id)); + rosidl_dynamic_typesupport_dynamic_data_loan_value(get_rosidl_dynamic_data(), id)); } diff --git a/rclcpp/src/rclcpp/executor.cpp b/rclcpp/src/rclcpp/executor.cpp index dc9c96108a..6feb8658b4 100644 --- a/rclcpp/src/rclcpp/executor.cpp +++ b/rclcpp/src/rclcpp/executor.cpp @@ -627,18 +627,15 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) [&]() {return subscription->take_serialized(*serialized_msg.get(), message_info);}, [&]() { - std::shared_ptr serialization_support = subscription->get_serialization_support(); - std::shared_ptr dyn_data = subscription->get_dynamic_data(); - // NOTE(methylDragon): We might want to consider cloning the dynamic data here + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr dynamic_message = + subscription->get_shared_dynamic_message(); - rcl_ret_t ret = rmw_serialized_to_dynamic_data( - &serialized_msg->get_rcl_serialized_message(), dyn_data.get()); - - if (ret != RMW_RET_OK) { + bool ret = dynamic_message->deserialize(&serialized_msg->get_rcl_serialized_message()); + if (!ret) { throw_from_rcl_error(ret, "Couldn't convert serialized message to dynamic data!"); } - subscription->handle_dynamic_message(dyn_data, message_info); + subscription->handle_dynamic_message(dynamic_message, message_info); } ); subscription->return_serialized_message(serialized_msg); diff --git a/rclcpp/src/rclcpp/generic_subscription.cpp b/rclcpp/src/rclcpp/generic_subscription.cpp index 41b342748b..d7ce004c42 100644 --- a/rclcpp/src/rclcpp/generic_subscription.cpp +++ b/rclcpp/src/rclcpp/generic_subscription.cpp @@ -72,32 +72,32 @@ void GenericSubscription::return_serialized_message( } -// DYNAMIC TYPE ================================================================================== +// DYNAMIC TYPE ==================================================================================== // TODO(methylDragon): Reorder later -std::shared_ptr -GenericSubscription::get_dynamic_type() +rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr +GenericSubscription::get_shared_dynamic_message_type() { throw rclcpp::exceptions::UnimplementedError( - "get_dynamic_type is not implemented for GenericSubscription"); + "get_shared_dynamic_message_type is not implemented for GenericSubscription"); } -std::shared_ptr -GenericSubscription::get_dynamic_data() +rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr +GenericSubscription::get_shared_dynamic_message() { throw rclcpp::exceptions::UnimplementedError( - "get_dynamic_data is not implemented for GenericSubscription"); + "get_shared_dynamic_message is not implemented for GenericSubscription"); } -std::shared_ptr -GenericSubscription::get_serialization_support() +rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr +GenericSubscription::get_shared_dynamic_serialization_support() { throw rclcpp::exceptions::UnimplementedError( - "get_serialization_support is not implemented for GenericSubscription"); + "get_shared_dynamic_serialization_support is not implemented for GenericSubscription"); } void GenericSubscription::handle_dynamic_message( - const std::shared_ptr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, const rclcpp::MessageInfo & message_info) { (void) dyn_data; diff --git a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp index aeecba5683..906f3ade49 100644 --- a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp +++ b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp @@ -28,6 +28,11 @@ #include "../../mocking_utils/patch.hpp" #include "../../utils/rclcpp_gtest_macros.hpp" +using rclcpp::dynamic_typesupport::DynamicMessageType; +using rclcpp::dynamic_typesupport::DynamicMessage; +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; + + namespace { @@ -78,11 +83,11 @@ class TestSubscription : public rclcpp::SubscriptionBase void return_message(std::shared_ptr &) override {} void return_serialized_message(std::shared_ptr &) override {} - std::shared_ptr get_dynamic_type() override {return nullptr;} - std::shared_ptr get_dynamic_data() override {return nullptr;} - std::shared_ptr get_serialization_support() override {return nullptr;} + DynamicMessageType::SharedPtr get_shared_dynamic_message_type() override {return nullptr;} + DynamicMessage::SharedPtr get_shared_dynamic_message() override {return nullptr;} + DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() override {return nullptr;} void handle_dynamic_message( - const std::shared_ptr &, + const DynamicMessage::SharedPtr &, const rclcpp::MessageInfo &) override {} }; From 9ff28439d1c0ffa57c86c65c90d86e2259fde212 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Thu, 23 Mar 2023 14:42:51 -0700 Subject: [PATCH 10/27] Implement direct taking of dynamic messages Signed-off-by: methylDragon --- .../include/rclcpp/dynamic_subscription.hpp | 14 +++++-- .../dynamic_typesupport/dynamic_data.hpp | 9 +++++ .../include/rclcpp/generic_subscription.hpp | 9 ++++- rclcpp/include/rclcpp/subscription.hpp | 20 +++++++++- rclcpp/include/rclcpp/subscription_base.hpp | 40 ++++++++++++------- rclcpp/src/rclcpp/dynamic_subscription.cpp | 20 +++++++++- .../dynamic_typesupport/dynamic_data.cpp | 19 +++++++++ rclcpp/src/rclcpp/executor.cpp | 35 +++++++++------- rclcpp/src/rclcpp/generic_subscription.cpp | 20 +++++++++- rclcpp/src/rclcpp/subscription_base.cpp | 32 ++++++++++++--- .../node_interfaces/test_node_topics.cpp | 8 ++-- 11 files changed, 176 insertions(+), 50 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp index 6822f9e210..396423eb20 100644 --- a/rclcpp/include/rclcpp/dynamic_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -56,7 +56,7 @@ class DynamicSubscription : public rclcpp::SubscriptionBase const rclcpp::QoS & qos, std::function callback, const rclcpp::SubscriptionOptionsWithAllocator & options, - bool use_take_dynamic_message = false) + bool use_take_dynamic_message = true) : SubscriptionBase( node_base, *(type_support->get_rosidl_message_type_support()), @@ -161,16 +161,22 @@ class DynamicSubscription : public rclcpp::SubscriptionBase get_shared_dynamic_message_type() override; RCLCPP_PUBLIC - rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr - get_shared_dynamic_message() override; + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr get_shared_dynamic_message() override; RCLCPP_PUBLIC rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() override; + RCLCPP_PUBLIC + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr create_dynamic_message() override; + + RCLCPP_PUBLIC + void return_dynamic_message( + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message) override; + RCLCPP_PUBLIC void handle_dynamic_message( - const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message, const rclcpp::MessageInfo & message_info) override; private: diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp index 36a6de270a..5be366048f 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp @@ -19,6 +19,7 @@ #include #include +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" @@ -177,6 +178,14 @@ class DynamicData : public std::enable_shared_from_this DynamicData::SharedPtr clone_shared() const; + RCLCPP_PUBLIC + DynamicData + init_from_type(DynamicMessageType & type) const; + + RCLCPP_PUBLIC + DynamicData::SharedPtr + init_from_type_shared(DynamicMessageType & type) const; + RCLCPP_PUBLIC bool equals(const DynamicData & other) const; diff --git a/rclcpp/include/rclcpp/generic_subscription.hpp b/rclcpp/include/rclcpp/generic_subscription.hpp index 27fc363b3e..9e4c731209 100644 --- a/rclcpp/include/rclcpp/generic_subscription.hpp +++ b/rclcpp/include/rclcpp/generic_subscription.hpp @@ -137,9 +137,16 @@ class GenericSubscription : public rclcpp::SubscriptionBase rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() override; + RCLCPP_PUBLIC + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr create_dynamic_message() override; + + RCLCPP_PUBLIC + void return_dynamic_message( + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message) override; + RCLCPP_PUBLIC void handle_dynamic_message( - const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message, const rclcpp::MessageInfo & message_info) override; private: diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index 8888bb01e4..204032a23e 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -412,12 +412,28 @@ class Subscription : public SubscriptionBase "get_shared_dynamic_serialization_support is not implemented for Subscription"); } + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr + create_dynamic_message() override + { + throw rclcpp::exceptions::UnimplementedError( + "create_dynamic_message is not implemented for Subscription"); + } + + void + return_dynamic_message( + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message) override + { + (void) message; + throw rclcpp::exceptions::UnimplementedError( + "return_dynamic_message is not implemented for Subscription"); + } + void handle_dynamic_message( - const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message, const rclcpp::MessageInfo & message_info) override { - (void) dyn_data; + (void) message; (void) message_info; throw rclcpp::exceptions::UnimplementedError( "handle_dynamic_message is not implemented for Subscription"); diff --git a/rclcpp/include/rclcpp/subscription_base.hpp b/rclcpp/include/rclcpp/subscription_base.hpp index 1b588394dd..72b922d8c2 100644 --- a/rclcpp/include/rclcpp/subscription_base.hpp +++ b/rclcpp/include/rclcpp/subscription_base.hpp @@ -80,8 +80,8 @@ class SubscriptionBase : public std::enable_shared_from_this * \param[in] topic_name Name of the topic to subscribe to. * \param[in] subscription_options Options for the subscription. * \param[in] is_serialized is true if the message will be delivered still serialized - * \param[in] use_dynamic_message_cb is true if the message will be taken serialized and then handled - * using dynamic type and dynamic data (type constructed at runtime) + * \param[in] is_dynamic is true if the message will be delivered dynamic (type constructed at + * runtime) */ RCLCPP_PUBLIC SubscriptionBase( @@ -92,11 +92,8 @@ class SubscriptionBase : public std::enable_shared_from_this const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks, bool is_serialized = false, - bool use_dynamic_message_cb = false, + bool is_dynamic = false, bool use_take_dynamic_message = false); - // TODO(methylDragon): If we don't need this, remove it, - // rclcpp::node_interfaces::NodeGraphInterface * node_graph = 0, - // rclcpp::node_interfaces::NodeServicesInterface * node_services = 0); /// Destructor. RCLCPP_PUBLIC @@ -562,28 +559,41 @@ class SubscriptionBase : public std::enable_shared_from_this rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() = 0; + /// Borrow a new serialized message (this clones!) + /** \return Shared pointer to a rclcpp::dynamic_typesupport::DynamicMessage. */ + RCLCPP_PUBLIC + virtual + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr + create_dynamic_message() = 0; + + RCLCPP_PUBLIC + virtual + void + return_dynamic_message(rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message) = 0; + RCLCPP_PUBLIC virtual void handle_dynamic_message( - const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message, const rclcpp::MessageInfo & message_info) = 0; - // TODO(methylDragon): - // RCLCPP_PUBLIC - // bool - // take_dynamic_message(rosidl_dynamic_typesupport_dynamic_data_t * message_out, rclcpp::MessageInfo & message_info_out); + RCLCPP_PUBLIC + bool + take_dynamic_message( + rclcpp::dynamic_typesupport::DynamicMessage & message_out, + rclcpp::MessageInfo & message_info_out); - /// Return if the subscription should use dynamic type + /// Return if the subscription handles dynamic messages /** * This will cause the subscription to use the handle_dynamic_message methods, which must be * used with take_serialized or take_dynamic_message. * - * \return `true` if the subscription should use a dynamic type callback, `false` otherwise + * \return `true` if the subscription should use a dynamic message callback, `false` otherwise */ RCLCPP_PUBLIC bool - use_dynamic_message_cb() const; + is_dynamic() const; RCLCPP_PUBLIC bool @@ -648,7 +658,7 @@ class SubscriptionBase : public std::enable_shared_from_this rosidl_message_type_support_t type_support_; bool is_serialized_; - bool use_dynamic_message_cb_; + bool is_dynamic_; bool use_take_dynamic_message_; std::atomic subscription_in_use_by_wait_set_{false}; diff --git a/rclcpp/src/rclcpp/dynamic_subscription.cpp b/rclcpp/src/rclcpp/dynamic_subscription.cpp index 17a7342d5c..d39e6d4342 100644 --- a/rclcpp/src/rclcpp/dynamic_subscription.cpp +++ b/rclcpp/src/rclcpp/dynamic_subscription.cpp @@ -68,12 +68,15 @@ void DynamicSubscription::return_serialized_message( // DYNAMIC TYPE ==================================================================================== // TODO(methylDragon): Re-order later + +// Does not clone rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr DynamicSubscription::get_shared_dynamic_message_type() { return dynamic_message_type_; }; +// Does not clone rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr DynamicSubscription::get_shared_dynamic_message() { @@ -86,11 +89,24 @@ DynamicSubscription::get_shared_dynamic_serialization_support() return serialization_support_; }; +rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr +DynamicSubscription::create_dynamic_message() +{ + return dynamic_message_->init_from_type_shared(*dynamic_message_type_); +}; + +void +DynamicSubscription::return_dynamic_message( + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message) +{ + message.reset(); +}; + void DynamicSubscription::handle_dynamic_message( - const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message, const rclcpp::MessageInfo &) { - callback_(dyn_data); + callback_(message); } } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp index 14a446645c..02601199c0 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp @@ -16,6 +16,7 @@ #include #include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/dynamic_typesupport/dynamic_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" @@ -384,6 +385,24 @@ DynamicData::clone_shared() const } +DynamicData +DynamicData::init_from_type(DynamicMessageType & type) const +{ + return DynamicData( + serialization_support_, + rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(type.get_rosidl_dynamic_type())); +} + + +DynamicData::SharedPtr +DynamicData::init_from_type_shared(DynamicMessageType & type) const +{ + return DynamicData::make_shared( + serialization_support_, + rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(type.get_rosidl_dynamic_type())); +} + + bool DynamicData::equals(const DynamicData & other) const { diff --git a/rclcpp/src/rclcpp/executor.cpp b/rclcpp/src/rclcpp/executor.cpp index 6feb8658b4..fde6f8019c 100644 --- a/rclcpp/src/rclcpp/executor.cpp +++ b/rclcpp/src/rclcpp/executor.cpp @@ -24,6 +24,7 @@ #include "rcl/error_handling.h" #include "rcpputils/scope_exit.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #include "rclcpp/exceptions.hpp" #include "rclcpp/executor.hpp" #include "rclcpp/guard_condition.hpp" @@ -598,12 +599,13 @@ take_and_do_error_handling( void Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) { + using rclcpp::dynamic_typesupport::DynamicMessage; + rclcpp::MessageInfo message_info; message_info.get_rmw_message_info().from_intra_process = false; - // PROPOSED ====================================================================================== - // If a subscription is meant to use_dynamic_message_cb, then it will use its - // serialization-specific dynamic data. + // DYNAMIC SUBSCRIPTION ========================================================================== + // If a subscription is dynamic, then it will use its serialization-specific dynamic data. // // Two cases: // - Dynamic type subscription using dynamic type stored in its own internal type support struct @@ -611,26 +613,30 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) // - Subscriptions of this type must be able to lookup the local message description to // generate a dynamic type at runtime! // - TODO(methylDragon): I won't be handling this case yet - // - // TODO(methylDragon): - // - use_dynamic_message_cb (can use take_serialized or take_dynamic_message) - // - take_dynamic_message (MUST have use_dynamic_message_cb true) - if (subscription->use_dynamic_message_cb()) { + if (subscription->is_dynamic()) { + // Take dynamic message directly from the middleware if (subscription->use_take_dynamic_message()) { - // TODO(methylDragon) - throw rclcpp::exceptions::UnimplementedError("take_dynamic_message is not implemented"); + DynamicMessage::SharedPtr dynamic_message = subscription->create_dynamic_message(); + take_and_do_error_handling( + "taking a dynamic message from topic", + subscription->get_topic_name(), + // This modifies the stored dynamic data in the DynamicMessage in-place + [&]() {return subscription->take_dynamic_message(*dynamic_message, message_info);}, + [&]() {subscription->handle_dynamic_message(dynamic_message, message_info);}); + subscription->return_dynamic_message(dynamic_message); + + // Take serialized and then convert to dynamic message } else { std::shared_ptr serialized_msg = subscription->create_serialized_message(); + + // NOTE(methylDragon): Is this clone necessary? If I'm following the pattern, it seems so. + DynamicMessage::SharedPtr dynamic_message = subscription->create_dynamic_message(); take_and_do_error_handling( "taking a serialized message from topic", subscription->get_topic_name(), [&]() {return subscription->take_serialized(*serialized_msg.get(), message_info);}, [&]() { - // NOTE(methylDragon): We might want to consider cloning the dynamic data here - rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr dynamic_message = - subscription->get_shared_dynamic_message(); - bool ret = dynamic_message->deserialize(&serialized_msg->get_rcl_serialized_message()); if (!ret) { throw_from_rcl_error(ret, "Couldn't convert serialized message to dynamic data!"); @@ -639,6 +645,7 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) } ); subscription->return_serialized_message(serialized_msg); + subscription->return_dynamic_message(dynamic_message); } return; } diff --git a/rclcpp/src/rclcpp/generic_subscription.cpp b/rclcpp/src/rclcpp/generic_subscription.cpp index d7ce004c42..94f08cf017 100644 --- a/rclcpp/src/rclcpp/generic_subscription.cpp +++ b/rclcpp/src/rclcpp/generic_subscription.cpp @@ -95,12 +95,28 @@ GenericSubscription::get_shared_dynamic_serialization_support() "get_shared_dynamic_serialization_support is not implemented for GenericSubscription"); } +rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr +GenericSubscription::create_dynamic_message() +{ + throw rclcpp::exceptions::UnimplementedError( + "create_dynamic_message is not implemented for GenericSubscription"); +} + +void +GenericSubscription::return_dynamic_message( + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message) +{ + (void) message; + throw rclcpp::exceptions::UnimplementedError( + "return_dynamic_message is not implemented for GenericSubscription"); +} + void GenericSubscription::handle_dynamic_message( - const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & dyn_data, + const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message, const rclcpp::MessageInfo & message_info) { - (void) dyn_data; + (void) message; (void) message_info; throw rclcpp::exceptions::UnimplementedError( "handle_dynamic_message is not implemented for GenericSubscription"); diff --git a/rclcpp/src/rclcpp/subscription_base.cpp b/rclcpp/src/rclcpp/subscription_base.cpp index 0a37e0575d..b5302291ac 100644 --- a/rclcpp/src/rclcpp/subscription_base.cpp +++ b/rclcpp/src/rclcpp/subscription_base.cpp @@ -22,6 +22,7 @@ #include "rcpputils/scope_exit.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #include "rclcpp/exceptions.hpp" #include "rclcpp/expand_topic_or_service_name.hpp" #include "rclcpp/experimental/intra_process_manager.hpp" @@ -32,6 +33,8 @@ #include "rmw/error_handling.h" #include "rmw/rmw.h" +#include "rosidl_dynamic_typesupport/types.h" + using rclcpp::SubscriptionBase; SubscriptionBase::SubscriptionBase( @@ -42,7 +45,7 @@ SubscriptionBase::SubscriptionBase( const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks, bool is_serialized, - bool use_dynamic_message_cb, + bool is_dynamic, bool use_take_dynamic_message) : node_base_(node_base), node_handle_(node_base_->get_shared_rcl_node_handle()), @@ -52,7 +55,7 @@ SubscriptionBase::SubscriptionBase( event_callbacks_(event_callbacks), type_support_(type_support_handle), is_serialized_(is_serialized), - use_dynamic_message_cb_(use_dynamic_message_cb), + is_dynamic_(is_dynamic), use_take_dynamic_message_(use_take_dynamic_message) { auto custom_deletor = [node_handle = this->node_handle_](rcl_subscription_t * rcl_subs) @@ -446,8 +449,7 @@ SubscriptionBase::set_content_filter( rcl_subscription_content_filter_options_t options = rcl_get_zero_initialized_subscription_content_filter_options(); - std::vector cstrings = - get_c_vector_string(expression_parameters); + std::vector cstrings = get_c_vector_string(expression_parameters); rcl_ret_t ret = rcl_subscription_content_filter_options_init( subscription_handle_.get(), get_c_string(filter_expression), @@ -524,9 +526,9 @@ SubscriptionBase::get_content_filter() const // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later bool -SubscriptionBase::use_dynamic_message_cb() const +SubscriptionBase::is_dynamic() const { - return use_dynamic_message_cb_; + return is_dynamic_; } bool @@ -534,3 +536,21 @@ SubscriptionBase::use_take_dynamic_message() const { return use_take_dynamic_message_; } + +bool +SubscriptionBase::take_dynamic_message( + rclcpp::dynamic_typesupport::DynamicMessage & message_out, + rclcpp::MessageInfo & message_info_out) +{ + rcl_ret_t ret = rcl_take_dynamic_message( + this->get_subscription_handle().get(), + message_out.get_rosidl_dynamic_data(), + &message_info_out.get_rmw_message_info(), + nullptr); + if (RCL_RET_SUBSCRIPTION_TAKE_FAILED == ret) { + return false; + } else if (RCL_RET_OK != ret) { + rclcpp::exceptions::throw_from_rcl_error(ret); + } + return true; +} diff --git a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp index 906f3ade49..e8e9728892 100644 --- a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp +++ b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp @@ -85,10 +85,10 @@ class TestSubscription : public rclcpp::SubscriptionBase DynamicMessageType::SharedPtr get_shared_dynamic_message_type() override {return nullptr;} DynamicMessage::SharedPtr get_shared_dynamic_message() override {return nullptr;} - DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() override {return nullptr;} - void handle_dynamic_message( - const DynamicMessage::SharedPtr &, - const rclcpp::MessageInfo &) override {} + DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() override {return nullptr;} + DynamicMessage::SharedPtr create_dynamic_message() override {return nullptr;} + void return_dynamic_message(DynamicMessage::SharedPtr &) override {} + void handle_dynamic_message(const DynamicMessage::SharedPtr &, const rclcpp::MessageInfo &) override {} }; class TestNodeTopics : public ::testing::Test From 78a568d14afc514a60ad76158e04465487e56d33 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Fri, 24 Mar 2023 01:22:02 -0700 Subject: [PATCH 11/27] Only use general type construction and implement default values Signed-off-by: methylDragon --- .../detail/dynamic_type_builder_impl.hpp | 52 ++++++++--- .../dynamic_type_builder.hpp | 51 ++++++---- .../dynamic_type_builder.cpp | 93 ++++++++++++------- 3 files changed, 130 insertions(+), 66 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp index e71d4702bd..d71bbcf010 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp @@ -33,40 +33,56 @@ template<> \ void \ DynamicTypeBuilder::add_member( \ - rosidl_dynamic_typesupport_member_id_t id, const std::string & name) \ + rosidl_dynamic_typesupport_member_id_t id, \ + const std::string & name, \ + const std::string & default_value) \ { \ rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## _member( \ - rosidl_dynamic_type_builder_.get(), id, name.c_str(), name.size()); \ + rosidl_dynamic_type_builder_.get(), \ + id, name.c_str(), name.size(), default_value.c_str(), default_value.size()); \ } #define __DYNAMIC_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN(MemberT, FunctionT) \ template<> \ void \ DynamicTypeBuilder::add_array_member( \ - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length) \ + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, \ + size_t array_length, \ + const std::string & default_value) \ { \ rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## _array_member( \ - rosidl_dynamic_type_builder_.get(), id, name.c_str(), name.size(), array_length); \ + rosidl_dynamic_type_builder_.get(), \ + id, name.c_str(), name.size(), default_value.c_str(), default_value.size(), \ + array_length); \ } #define __DYNAMIC_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ template<> \ void \ DynamicTypeBuilder::add_unbounded_sequence_member( \ - rosidl_dynamic_typesupport_member_id_t id, const std::string & name) \ + rosidl_dynamic_typesupport_member_id_t id, \ + const std::string & name, \ + const std::string & default_value) \ { \ - rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## _unbounded_sequence_member( \ - rosidl_dynamic_type_builder_.get(), id, name.c_str(), name.size()); \ + rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## \ + _unbounded_sequence_member( \ + rosidl_dynamic_type_builder_.get(), \ + id, name.c_str(), name.size(), default_value.c_str(), default_value.size()); \ } #define __DYNAMIC_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ template<> \ void \ DynamicTypeBuilder::add_bounded_sequence_member( \ - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound) \ + rosidl_dynamic_typesupport_member_id_t id, \ + const std::string & name, \ + size_t sequence_bound, \ + const std::string & default_value) \ { \ rosidl_dynamic_typesupport_dynamic_type_builder_add_ ## FunctionT ## _bounded_sequence_member( \ - rosidl_dynamic_type_builder_.get(), id, name.c_str(), name.size(), sequence_bound); \ + rosidl_dynamic_type_builder_.get(), \ + id, name.c_str(), name.size(), default_value.c_str(), default_value.size(), \ + sequence_bound); \ } #define DYNAMIC_TYPE_BUILDER_DEFINITIONS(MemberT, FunctionT) \ @@ -113,7 +129,10 @@ DYNAMIC_TYPE_BUILDER_DEFINITIONS(std::u16string, wstring); // THROW FOR UNSUPPORTED TYPES ===================================================================== template void -DynamicTypeBuilder::add_member(rosidl_dynamic_typesupport_member_id_t id, const std::string & name) +DynamicTypeBuilder::add_member( + rosidl_dynamic_typesupport_member_id_t id, + const std::string & name, + const std::string & default_value) { throw rclcpp::exceptions::UnimplementedError( "add_member is not implemented for input type"); @@ -123,7 +142,9 @@ DynamicTypeBuilder::add_member(rosidl_dynamic_typesupport_member_id_t id, const template void DynamicTypeBuilder::add_array_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length) + rosidl_dynamic_typesupport_member_id_t id, + const std::string & name, + size_t array_length, const std::string & default_value) { throw rclcpp::exceptions::UnimplementedError( "add_array_member is not implemented for input type"); @@ -133,7 +154,9 @@ DynamicTypeBuilder::add_array_member( template void DynamicTypeBuilder::add_unbounded_sequence_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name) + rosidl_dynamic_typesupport_member_id_t id, + const std::string & name, + const std::string & default_value) { throw rclcpp::exceptions::UnimplementedError( "add_unbounded_sequence_member is not implemented for input type"); @@ -143,7 +166,10 @@ DynamicTypeBuilder::add_unbounded_sequence_member( template void DynamicTypeBuilder::add_bounded_sequence_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound) + rosidl_dynamic_typesupport_member_id_t id, + const std::string & name, + size_t sequence_bound, + const std::string & default_value) { throw rclcpp::exceptions::UnimplementedError( "add_bounded_sequence_member is not implemented for input type"); diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp index 60cd03968f..f6ac5fdc0a 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp @@ -193,68 +193,77 @@ class DynamicTypeBuilder : public std::enable_shared_from_this void - add_member(rosidl_dynamic_typesupport_member_id_t id, const std::string & name); + add_member( + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + const std::string & default_value = ""); template void add_array_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length); + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length, + const std::string & default_value = ""); template void add_unbounded_sequence_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name); + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, + const std::string & default_value = ""); template void add_bounded_sequence_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound); + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound, + const std::string & default_value = ""); // ADD BOUNDED STRING MEMBERS ==================================================================== RCLCPP_PUBLIC void add_bounded_string_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound); + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound, + const std::string & default_value = ""); RCLCPP_PUBLIC void add_bounded_wstring_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound); + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound, + const std::string & default_value = ""); RCLCPP_PUBLIC void add_bounded_string_array_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - size_t string_bound, size_t array_length); + size_t string_bound, size_t array_length, const std::string & default_value = ""); RCLCPP_PUBLIC void add_bounded_wstring_array_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - size_t wstring_bound, size_t array_length); + size_t wstring_bound, size_t array_length, const std::string & default_value = ""); RCLCPP_PUBLIC void add_bounded_string_unbounded_sequence_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound); + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound, + const std::string & default_value = ""); RCLCPP_PUBLIC void add_bounded_wstring_unbounded_sequence_member( - rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound); + rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound, + const std::string & default_value = ""); RCLCPP_PUBLIC void add_bounded_string_bounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - size_t string_bound, size_t sequence_bound); + size_t string_bound, size_t sequence_bound, const std::string & default_value = ""); RCLCPP_PUBLIC void add_bounded_wstring_bounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - size_t wstring_bound, size_t sequence_bound); + size_t wstring_bound, size_t sequence_bound, const std::string & default_value = ""); // ADD NESTED MEMBERS ============================================================================ @@ -262,49 +271,51 @@ class DynamicTypeBuilder : public std::enable_shared_from_this Date: Tue, 28 Mar 2023 10:54:49 -0700 Subject: [PATCH 12/27] Use new deletes for memory management Signed-off-by: methylDragon --- .../detail/dynamic_data_impl.hpp | 4 +- .../dynamic_typesupport/dynamic_data.cpp | 10 ++-- .../dynamic_message_type_support.cpp | 50 ++++++++++--------- .../dynamic_typesupport/dynamic_type.cpp | 6 +-- .../dynamic_type_builder.cpp | 6 +-- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp index d2e77247ae..b27c237130 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp @@ -178,7 +178,7 @@ DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) rosidl_dynamic_typesupport_dynamic_data_get_string_value( get_rosidl_dynamic_data(), id, &buf, &buf_length); auto out = std::string(buf, buf_length); - free(buf); + delete buf; return out; } @@ -192,7 +192,7 @@ DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id rosidl_dynamic_typesupport_dynamic_data_get_wstring_value( get_rosidl_dynamic_data(), id, &buf, &buf_length); auto out = std::u16string(buf, buf_length); - free(buf); + delete buf; return out; } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp index 02601199c0..e53d21b7df 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp @@ -68,7 +68,7 @@ DynamicData::DynamicData(const DynamicTypeBuilder::SharedPtr dynamic_type_builde // Custom deleter [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); - free(rosidl_dynamic_data); + delete rosidl_dynamic_data; }); } @@ -101,7 +101,7 @@ DynamicData::DynamicData(const DynamicType::SharedPtr dynamic_type) // Custom deleter [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); - free(rosidl_dynamic_data); + delete rosidl_dynamic_data; }); } @@ -129,7 +129,7 @@ DynamicData::DynamicData( // Custom deleter [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); - free(rosidl_dynamic_data); + delete rosidl_dynamic_data; }); } @@ -517,7 +517,7 @@ DynamicData::get_bounded_string_value( rosidl_dynamic_typesupport_dynamic_data_get_bounded_string_value( get_rosidl_dynamic_data(), id, &buf, &buf_length, string_bound); auto out = std::string(buf, buf_length); - free(buf); + delete buf; return out; } @@ -538,7 +538,7 @@ DynamicData::get_bounded_wstring_value( rosidl_dynamic_typesupport_dynamic_data_get_bounded_wstring_value( get_rosidl_dynamic_data(), id, &buf, &buf_length, wstring_bound); auto out = std::u16string(buf, buf_length); - free(buf); + delete buf; return out; } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index 479be09b52..05129b10cd 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -242,40 +242,42 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( return; } + rmw_dynamic_typesupport_impl_t * ts_impl = new rmw_dynamic_typesupport_impl_t{ + middleware_can_take_dynamic_data, // take_dynamic_data + description, // description + serialization_support->get_rosidl_serialization_support(), // serialization_support + dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_type + dynamic_message->get_rosidl_dynamic_data() // dynamic_data + }; + if (!ts_impl) { + RCUTILS_LOG_ERROR_NAMED( + rmw_dynamic_typesupport_c__identifier, + "Could not allocate rmw_dynamic_typesupport_impl_t struct"); + return; + } + // NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members - // are managed by the passed in SharedPtr wrapper classes + // are managed by the passed in SharedPtr wrapper classes. We just delete it. rosidl_message_type_support_.reset( - new rosidl_message_type_support_t(), - [](rosidl_message_type_support_t * ts) -> void {free(const_cast(ts->data));} + new rosidl_message_type_support_t{ + rmw_dynamic_typesupport_c__identifier, // typesupport_identifier + ts_impl, // data + get_message_typesupport_handle_function, // func + nullptr // TODO(methylDragon): Populate type hash // type_hash + }, + [](rosidl_message_type_support_t * ts) -> void { + delete static_cast(ts->data); + delete ts->type_hash; // Only because we should've allocated it here + } ); if (!rosidl_message_type_support_) { RCUTILS_LOG_ERROR_NAMED( rmw_dynamic_typesupport_c__identifier, "Could not allocate rosidl_message_type_support_t struct"); + delete ts_impl; return; } - - rosidl_message_type_support_->typesupport_identifier = rmw_dynamic_typesupport_c__identifier; - - // NOTE(methylDragon): To populate dynamic_type and description if deferred, OUTSIDE - rosidl_message_type_support_->data = calloc(1, sizeof(rmw_dynamic_typesupport_impl_t)); - if (!rosidl_message_type_support_->data) { - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, - "Could not allocate rmw_dynamic_typesupport_impl_t struct"); - rosidl_message_type_support_.reset(); - } - - rmw_dynamic_typesupport_impl_t * ts_impl = - (rmw_dynamic_typesupport_impl_t *)rosidl_message_type_support_->data; - - ts_impl->take_dynamic_data = middleware_can_take_dynamic_data; - ts_impl->serialization_support = serialization_support->get_rosidl_serialization_support(); - ts_impl->dynamic_type = dynamic_message_type->get_rosidl_dynamic_type(); - ts_impl->dynamic_data = dynamic_message->get_rosidl_dynamic_data(); - ts_impl->description = description; - rosidl_message_type_support_->func = get_message_typesupport_handle_function; } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp index a189d88d53..bfe593a2cf 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp @@ -59,7 +59,7 @@ DynamicType::DynamicType(DynamicTypeBuilder::SharedPtr dynamic_type_builder) // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); - free(rosidl_dynamic_type); + delete rosidl_dynamic_type; }); } @@ -84,7 +84,7 @@ DynamicType::DynamicType( // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); - free(rosidl_dynamic_type); + delete rosidl_dynamic_type; }); } @@ -174,7 +174,7 @@ DynamicType::init_from_description( // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); - free(rosidl_dynamic_type); + delete rosidl_dynamic_type; }); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp index fb959b3b8b..f0f438e683 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp @@ -71,7 +71,7 @@ DynamicTypeBuilder::DynamicTypeBuilder( // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); - free(rosidl_dynamic_type_builder); + delete rosidl_dynamic_type_builder; }); } @@ -167,7 +167,7 @@ DynamicTypeBuilder::init_from_description( // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); - free(rosidl_dynamic_type_builder); + delete rosidl_dynamic_type_builder; }); } @@ -198,7 +198,7 @@ DynamicTypeBuilder::init_from_serialization_support_( // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); - free(rosidl_dynamic_type_builder); + delete rosidl_dynamic_type_builder; }); } From 363861f70c6f521b975522f319e2592f9153421f Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 28 Mar 2023 21:25:44 -0700 Subject: [PATCH 13/27] Alias dynamic_data with dynamic_message, pass desc, and build ts top-down Signed-off-by: methylDragon --- .../include/rclcpp/dynamic_subscription.hpp | 40 +--- .../dynamic_typesupport/dynamic_data.hpp | 5 + .../dynamic_typesupport/dynamic_message.hpp | 5 +- .../dynamic_message_type.hpp | 5 +- .../dynamic_message_type_support.hpp | 28 ++- .../dynamic_typesupport/dynamic_type.hpp | 13 +- .../dynamic_type_builder.hpp | 12 +- rclcpp/src/rclcpp/dynamic_subscription.cpp | 5 +- .../dynamic_message_type_support.cpp | 199 ++++++++++-------- .../dynamic_serialization_support.cpp | 2 +- .../dynamic_typesupport/dynamic_type.cpp | 9 +- .../dynamic_type_builder.cpp | 9 +- rclcpp/src/rclcpp/subscription_base.cpp | 5 + 13 files changed, 196 insertions(+), 141 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp index 396423eb20..d9606d1618 100644 --- a/rclcpp/include/rclcpp/dynamic_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -54,7 +54,10 @@ class DynamicSubscription : public rclcpp::SubscriptionBase rclcpp::dynamic_typesupport::DynamicMessageTypeSupport::SharedPtr type_support, const std::string & topic_name, const rclcpp::QoS & qos, - std::function callback, + std::function + )> callback, const rclcpp::SubscriptionOptionsWithAllocator & options, bool use_take_dynamic_message = true) : SubscriptionBase( @@ -64,8 +67,8 @@ class DynamicSubscription : public rclcpp::SubscriptionBase options.to_rcl_subscription_options(qos), options.event_callbacks, options.use_default_callbacks, - false, - true, + false, // is_serialized + true, // is_dynamic use_take_dynamic_message), ts_(type_support), callback_(callback), @@ -92,32 +95,6 @@ class DynamicSubscription : public rclcpp::SubscriptionBase // TODO(methylDragon): /// Deferred type description constructor, only usable if the middleware implementation supports /// type discovery - // template> - // DynamicSubscription( - // rclcpp::node_interfaces::NodeBaseInterface * node_base, - // const std::string & topic_name, - // const rclcpp::QoS & qos, - // // TODO(methylDragons): Eventually roll out an rclcpp::DynamicData that encompasses the serialization_support - // // support and DynamicData, and pass that to the callback - // std::function callback, - // const rclcpp::SubscriptionOptionsWithAllocator & options, - // const char * serialization_lib_name = nullptr) - // : SubscriptionBase( - // node_base, - // // NOTE(methylDragon): Since the typesupport is deferred, it needs to be modified post-hoc - // // which means it technically isn't const correct... - // *rmw_get_dynamic_message_typesupport_handle(serialization_lib_name), - // topic_name, - // options.to_rcl_subscription_options(qos), - // options.event_callbacks, - // options.use_default_callbacks, - // false, - // true), - // callback_(callback) - // {} RCLCPP_PUBLIC virtual ~DynamicSubscription() = default; @@ -183,7 +160,10 @@ class DynamicSubscription : public rclcpp::SubscriptionBase RCLCPP_DISABLE_COPY(DynamicSubscription) rclcpp::dynamic_typesupport::DynamicMessageTypeSupport::SharedPtr ts_; - std::function callback_; + std::function + )> callback_; rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr serialization_support_; rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr dynamic_message_; diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp index 5be366048f..46383be2f3 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp @@ -49,6 +49,11 @@ class DynamicTypeBuilder; * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer * must point to the same location in memory as the stored raw pointer! + * + * Note: This class is meant to map to the lower level rosidl_dynamic_typesupport_dynamic_data_t, + * even though rosidl_dynamic_typesupport_dynamic_data_t is equivalent to + * rmw_dynamic_message_t, exposing the fundamental methods available to + * rosidl_dynamic_typesupport_dynamic_data_t, allowing the user to access the data's fields. */ class DynamicData : public std::enable_shared_from_this { diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index 9fe612141e..5c377ede72 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -37,7 +37,10 @@ namespace dynamic_typesupport // NOTE(methylDragon): We just alias the type in this case... // I'd have made a wrapper class but then I'd need to redirect every single -// method (or dynamic cast everywhere else), so.. no thanks. +// method (or dynamic cast everywhere else) +// +/// This type maps to the underlying rmw_dynamic_message_t, rather than the equivalent +/// rosidl_dynamic_typesupport_dynamic_data_t struct. using DynamicMessage = DynamicData; } // namespace dynamic_typesupport diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index 3520179a56..68442d4567 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -35,7 +35,10 @@ namespace dynamic_typesupport // NOTE(methylDragon): We just alias the type in this case... // I'd have made a wrapper class but then I'd need to redirect every single -// method (or dynamic cast everywhere else), so.. no thanks. +// method (or dynamic cast everywhere else) +// +/// This type maps to the underlying rmw_dynamic_message_type_t, rather than the equivalent +/// rosidl_dynamic_typesupport_dynamic_type_t struct. using DynamicMessageType = DynamicType; diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp index 596dead05f..a52aabcb5d 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -39,7 +39,7 @@ namespace dynamic_typesupport /** * * NOTE: This class is the recommended way to obtain the dynamic message type - * support struct, instead of rcl_get_dynamic_message_typesupport_handle, + * support struct, instead of rcl_dynamic_message_typesupport_handle_init, * because this class will manage the lifetimes for you. * * Do NOT call rcl_dynamic_message_typesupport_handle_fini!! @@ -61,24 +61,36 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this { @@ -80,7 +89,7 @@ class DynamicType : public std::enable_shared_from_this RCLCPP_PUBLIC DynamicType( DynamicSerializationSupport::SharedPtr serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description); + const rosidl_runtime_c__type_description__TypeDescription & description); /// Copy constructor RCLCPP_PUBLIC @@ -105,7 +114,7 @@ class DynamicType : public std::enable_shared_from_this RCLCPP_PUBLIC void init_from_description( - const rosidl_runtime_c__type_description__TypeDescription * description, + const rosidl_runtime_c__type_description__TypeDescription & description, DynamicSerializationSupport::SharedPtr serialization_support = nullptr); // GETTERS ======================================================================================= diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp index f6ac5fdc0a..84ec949965 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp @@ -45,6 +45,14 @@ class DynamicType; * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer * must point to the same location in memory as the stored raw pointer! + * + * Note: This class is meant to map to rosidl_dynamic_typesupport_dynamic_type_builder_t, + * facilitating the construction of dynamic types bottom-up in the C++ layer. + * + * The usual method of obtaining a DynamicType is through construction of + * rosidl_message_type_support_t via rcl_dynamic_message_typesupport_handle_init(), then taking + * ownership of its contents. But DynamicTypeBuilder can also be used to obtain DynamicType by + * constructing it bottom-up instead, since it exposes the lower_level rosidl methods. */ class DynamicTypeBuilder : public std::enable_shared_from_this { @@ -97,7 +105,7 @@ class DynamicTypeBuilder : public std::enable_shared_from_thisget_shared_rosidl_runtime_c_type_description()); } } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index 05129b10cd..77b68c46a1 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -15,10 +15,12 @@ #include #include -#include "rmw/dynamic_typesupport.h" +#include "rmw/dynamic_message_typesupport.h" #include "rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp" +#include "rcl/rcl_dynamic_typesupport_c/message_introspection.h" + #include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" @@ -41,7 +43,7 @@ using rclcpp::dynamic_typesupport::DynamicMessageTypeSupport; // CONSTRUCTION ==================================================================================== DynamicMessageTypeSupport::DynamicMessageTypeSupport( - rosidl_runtime_c__type_description__TypeDescription * description, + const rosidl_runtime_c__type_description__TypeDescription & description, const std::string & serialization_library_name) : serialization_support_(nullptr), dynamic_message_type_(nullptr), @@ -49,41 +51,51 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( description_(nullptr), rosidl_message_type_support_(nullptr) { - if (!description) { - throw std::runtime_error("description cannot be nullptr!"); + rosidl_message_type_support_t * ts = nullptr; + rcl_ret_t ret; + + if (serialization_library_name.empty()) { + ret = rcl_dynamic_message_typesupport_handle_init(nullptr, &description, &ts); + } else { + ret = rcl_dynamic_message_typesupport_handle_init( + serialization_library_name.c_str(), &description, &ts); } - description_.reset( - description, - [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { - rosidl_runtime_c__type_description__TypeDescription__destroy(description); - }); - - init_serialization_support_(serialization_library_name); - if (!serialization_support_) { - throw std::runtime_error("could not init dynamic serialization support!"); + if (ret != RCL_RET_OK) { + throw std::runtime_error("error initializing rosidl message type support"); } - - init_dynamic_message_type_(serialization_support_, description); - if (!dynamic_message_type_) { - throw std::runtime_error("could not init dynamic message type!"); + if (!ts) { + throw std::runtime_error("could not init rosidl message type support"); } - - init_dynamic_message_(dynamic_message_type_); - if (!dynamic_message_) { - throw std::runtime_error("could not init dynamic message!"); + if (!ts->data) { + throw std::runtime_error("could not init rosidl message type support impl"); + } + if (ts->typesupport_identifier != rmw_dynamic_typesupport_c__identifier) { + throw std::runtime_error("rosidl message type support is of the wrong type"); } - init_rosidl_message_type_support_( - serialization_support_, dynamic_message_type_, dynamic_message_, description_.get()); + // NOTE(methylDragon): Not technically const correct, but since it's a const void *, + // we do it anyway... + auto ts_impl = static_cast(ts->data); + + manage_rosidl_message_type_support_(ts); + manage_description_(ts_impl->description); + serialization_support_ = DynamicSerializationSupport::make_shared(ts_impl->serialization_support); + + dynamic_message_type_ = DynamicMessageType::make_shared( + get_shared_dynamic_serialization_support(), ts_impl->dynamic_message_type); + + dynamic_message_ = DynamicMessage::make_shared( + get_shared_dynamic_serialization_support(), ts_impl->dynamic_message); + if (!rosidl_message_type_support_) { - throw std::runtime_error("could not init rosidl message type support!"); + throw std::runtime_error("could not init rosidl message type support."); } } DynamicMessageTypeSupport::DynamicMessageTypeSupport( DynamicSerializationSupport::SharedPtr serialization_support, - rosidl_runtime_c__type_description__TypeDescription * description) + const rosidl_runtime_c__type_description__TypeDescription & description) : serialization_support_(serialization_support), dynamic_message_type_(nullptr), dynamic_message_(nullptr), @@ -92,32 +104,38 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( { // Check null if (!serialization_support) { - throw std::runtime_error("serialization_support cannot be nullptr!"); - } - if (!description) { - throw std::runtime_error("description cannot be nullptr!"); + throw std::runtime_error("serialization_support cannot be nullptr."); } - description_.reset( - description, - [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { - rosidl_runtime_c__type_description__TypeDescription__destroy(description); - }); - // Init - init_dynamic_message_type_(serialization_support_, description); - if (!dynamic_message_type_) { - throw std::runtime_error("could not init dynamic message type!"); - } + rosidl_message_type_support_t * ts = nullptr; - init_dynamic_message_(dynamic_message_type_); - if (!dynamic_message_) { - throw std::runtime_error("could not init dynamic message!"); + ts = rmw_dynamic_message_typesupport_handle_init( + serialization_support->get_rosidl_serialization_support(), + rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY), + &description); + if (!ts) { + throw std::runtime_error("could not init rosidl message type support"); + } + if (!ts->data) { + throw std::runtime_error("could not init rosidl message type support impl"); + } + if (ts->typesupport_identifier != rmw_dynamic_typesupport_c__identifier) { + throw std::runtime_error("rosidl message type support is of the wrong type"); } - init_rosidl_message_type_support_( - serialization_support_, dynamic_message_type_, dynamic_message_, description_.get()); + auto ts_impl = static_cast(ts->data); + + manage_rosidl_message_type_support_(ts); + manage_description_(ts_impl->description); + + dynamic_message_type_ = DynamicMessageType::make_shared( + get_shared_dynamic_serialization_support(), ts_impl->dynamic_message_type); + + dynamic_message_ = DynamicMessage::make_shared( + get_shared_dynamic_serialization_support(), ts_impl->dynamic_message); + if (!rosidl_message_type_support_) { - throw std::runtime_error("could not init rosidl message type support!"); + throw std::runtime_error("could not init rosidl message type support."); } } @@ -126,7 +144,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( DynamicSerializationSupport::SharedPtr serialization_support, DynamicMessageType::SharedPtr dynamic_message_type, DynamicMessage::SharedPtr dynamic_message, - rosidl_runtime_c__type_description__TypeDescription * description) + const rosidl_runtime_c__type_description__TypeDescription & description) : serialization_support_(serialization_support), dynamic_message_type_(dynamic_message_type), dynamic_message_(dynamic_message), @@ -135,21 +153,27 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( { // Check null if (!serialization_support) { - throw std::runtime_error("serialization_support cannot be nullptr!"); + throw std::runtime_error("serialization_support cannot be nullptr."); } if (!dynamic_message_type) { - throw std::runtime_error("dynamic_message_type cannot be nullptr!"); + throw std::runtime_error("dynamic_message_type cannot be nullptr."); } if (!dynamic_message) { - throw std::runtime_error("dynamic_message cannot be nullptr!"); + throw std::runtime_error("dynamic_message cannot be nullptr."); } - if (description) { - description_.reset( - description, - [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { - rosidl_runtime_c__type_description__TypeDescription__destroy(description); - }); + description_.reset( + new rosidl_runtime_c__type_description__TypeDescription(), + [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { + rosidl_runtime_c__type_description__TypeDescription__destroy(description); + }); + if (!description_) + { + throw std::runtime_error("could not init type description."); + } + if (!rosidl_runtime_c__type_description__TypeDescription__copy(&description, description_.get())) + { + throw std::runtime_error("could not copy type description."); } // Check identifiers @@ -158,12 +182,12 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( { throw std::runtime_error( "serialization support library identifier does not match " - "dynamic message type library identifier!"); + "dynamic message type library identifier."); } if (dynamic_message_type->get_library_identifier() != dynamic_message->get_library_identifier()) { throw std::runtime_error( "dynamic message type library identifier does not match " - "dynamic message library identifier!"); + "dynamic message library identifier."); } // Check pointers @@ -173,7 +197,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( ->get_shared_dynamic_serialization_support() ->get_rosidl_serialization_support()) { - throw std::runtime_error("serialization support pointer dynamic message type's"); + throw std::runtime_error("serialization support pointer does not match dynamic message type's"); } if (dynamic_message_type ->get_shared_dynamic_serialization_support() @@ -182,14 +206,14 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( ->get_shared_dynamic_serialization_support() ->get_rosidl_serialization_support()) { - throw std::runtime_error("serialization support pointer dynamic message type's"); + throw std::runtime_error("serialization support does not match pointer dynamic message type's"); } /* *INDENT-ON* */ init_rosidl_message_type_support_( serialization_support_, dynamic_message_type_, dynamic_message_, description_.get()); if (!rosidl_message_type_support_) { - throw std::runtime_error("could not init rosidl message type support!"); + throw std::runtime_error("could not init rosidl message type support."); } } @@ -198,29 +222,39 @@ DynamicMessageTypeSupport::~DynamicMessageTypeSupport() {} void -DynamicMessageTypeSupport::init_serialization_support_( - const std::string & serialization_library_name) -{ - serialization_support_ = DynamicSerializationSupport::make_shared(serialization_library_name); -} - - -void -DynamicMessageTypeSupport::init_dynamic_message_type_( - DynamicSerializationSupport::SharedPtr serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description) +DynamicMessageTypeSupport::manage_rosidl_message_type_support_( + rosidl_message_type_support_t * rosidl_message_type_support) { - dynamic_message_type_ = DynamicMessageType::make_shared(serialization_support, description); + // NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members + // are managed by the passed in SharedPtr wrapper classes. We just delete it. + rosidl_message_type_support_.reset( + rosidl_message_type_support, + [](rosidl_message_type_support_t * ts) -> void { + delete static_cast(ts->data); + delete ts->type_hash; // Only because we should've allocated it here + delete ts; + } + ); } void -DynamicMessageTypeSupport::init_dynamic_message_(DynamicType::SharedPtr dynamic_type) +DynamicMessageTypeSupport::manage_description_( + rosidl_runtime_c__type_description__TypeDescription * description) { - dynamic_message_ = DynamicMessage::make_shared(dynamic_type); + if (!description) { + throw std::runtime_error("description cannot be nullptr"); + } + description_.reset( + description, + [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { + rosidl_runtime_c__type_description__TypeDescription__destroy(description); + }); } +// NOTE(methylDragon): This looks like rmw_dynamic_message_typesupport_handle_init, but instead +// just aggregates already initialized objects void DynamicMessageTypeSupport::init_rosidl_message_type_support_( DynamicSerializationSupport::SharedPtr serialization_support, @@ -230,29 +264,26 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( { bool middleware_supports_type_discovery = rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY); - bool middleware_can_take_dynamic_data = - rmw_feature_supported(RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_DATA); if (!middleware_supports_type_discovery && !description) { RCUTILS_LOG_ERROR_NAMED( rmw_dynamic_typesupport_c__identifier, "Middleware does not support type discovery! Deferred dynamic type" "message type support will never be populated! You must provide a type " - "description!"); + "description."); return; } - rmw_dynamic_typesupport_impl_t * ts_impl = new rmw_dynamic_typesupport_impl_t{ - middleware_can_take_dynamic_data, // take_dynamic_data + rmw_dynamic_message_typesupport_impl_t * ts_impl = new rmw_dynamic_message_typesupport_impl_t{ description, // description serialization_support->get_rosidl_serialization_support(), // serialization_support - dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_type - dynamic_message->get_rosidl_dynamic_data() // dynamic_data + dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_message_type + dynamic_message->get_rosidl_dynamic_data() // dynamic_message }; if (!ts_impl) { RCUTILS_LOG_ERROR_NAMED( rmw_dynamic_typesupport_c__identifier, - "Could not allocate rmw_dynamic_typesupport_impl_t struct"); + "Could not allocate rmw_dynamic_message_typesupport_impl_t struct"); return; } @@ -266,7 +297,7 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( nullptr // TODO(methylDragon): Populate type hash // type_hash }, [](rosidl_message_type_support_t * ts) -> void { - delete static_cast(ts->data); + delete static_cast(ts->data); delete ts->type_hash; // Only because we should've allocated it here } ); @@ -392,7 +423,7 @@ void DynamicMessageTypeSupport::print_description() const { if (!description_) { - RCUTILS_LOG_ERROR("Can't print description, no bound description!"); + RCUTILS_LOG_ERROR("Can't print description, no bound description."); } rosidl_runtime_c_type_description_utils_print_type_description(description_.get()); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp index f5d61960f1..1be0dcb671 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp @@ -18,7 +18,7 @@ #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/exceptions.hpp" #include "rcutils/logging_macros.h" -#include "rmw/dynamic_typesupport.h" +#include "rmw/dynamic_message_typesupport.h" #include diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp index bfe593a2cf..15bbcd1743 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp @@ -108,7 +108,7 @@ DynamicType::DynamicType( DynamicType::DynamicType( DynamicSerializationSupport::SharedPtr serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description) + const rosidl_runtime_c__type_description__TypeDescription & description) : serialization_support_(serialization_support), rosidl_dynamic_type_(nullptr) { init_from_description(description, serialization_support); @@ -150,12 +150,9 @@ DynamicType::~DynamicType() {} void DynamicType::init_from_description( - const rosidl_runtime_c__type_description__TypeDescription * description, + const rosidl_runtime_c__type_description__TypeDescription & description, DynamicSerializationSupport::SharedPtr serialization_support) { - if (!description) { - throw std::runtime_error("description cannot be nullptr!"); - } if (serialization_support) { // Swap serialization support if serialization support is given serialization_support_ = serialization_support; @@ -164,7 +161,7 @@ DynamicType::init_from_description( rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type = nullptr; rosidl_dynamic_type = rosidl_dynamic_typesupport_dynamic_type_init_from_description( - serialization_support_->get_rosidl_serialization_support(), description); + serialization_support_->get_rosidl_serialization_support(), &description); if (!rosidl_dynamic_type) { throw std::runtime_error("could not create new dynamic type object"); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp index f0f438e683..addcd0b3cd 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp @@ -97,7 +97,7 @@ DynamicTypeBuilder::DynamicTypeBuilder( DynamicTypeBuilder::DynamicTypeBuilder( DynamicSerializationSupport::SharedPtr serialization_support, - const rosidl_runtime_c__type_description__TypeDescription * description) + const rosidl_runtime_c__type_description__TypeDescription & description) : serialization_support_(serialization_support), rosidl_dynamic_type_builder_(nullptr) { @@ -143,12 +143,9 @@ DynamicTypeBuilder::~DynamicTypeBuilder() {} void DynamicTypeBuilder::init_from_description( - const rosidl_runtime_c__type_description__TypeDescription * description, + const rosidl_runtime_c__type_description__TypeDescription & description, DynamicSerializationSupport::SharedPtr serialization_support) { - if (!description) { - throw std::runtime_error("description cannot be nullptr!"); - } if (serialization_support) { // Swap serialization support if serialization support is given serialization_support_ = serialization_support; @@ -157,7 +154,7 @@ DynamicTypeBuilder::init_from_description( rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; rosidl_dynamic_type_builder = rosidl_dynamic_typesupport_dynamic_type_builder_init_from_description( - serialization_support_->get_rosidl_serialization_support(), description); + serialization_support_->get_rosidl_serialization_support(), &description); if (!rosidl_dynamic_type_builder) { throw std::runtime_error("could not create new dynamic type builder object"); } diff --git a/rclcpp/src/rclcpp/subscription_base.cpp b/rclcpp/src/rclcpp/subscription_base.cpp index b5302291ac..38e21e61c3 100644 --- a/rclcpp/src/rclcpp/subscription_base.cpp +++ b/rclcpp/src/rclcpp/subscription_base.cpp @@ -58,6 +58,11 @@ SubscriptionBase::SubscriptionBase( is_dynamic_(is_dynamic), use_take_dynamic_message_(use_take_dynamic_message) { + if (!rmw_feature_supported(RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_MESSAGE) && use_take_dynamic_message_) + { + throw std::runtime_error("Cannot use_take_dynamic_message, feature not supported in rmw"); + } + auto custom_deletor = [node_handle = this->node_handle_](rcl_subscription_t * rcl_subs) { if (rcl_subscription_fini(rcl_subs, node_handle.get()) != RCL_RET_OK) { From 57900a9f440f7fb9e91e555c8ae135e342119dd9 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Wed, 29 Mar 2023 09:52:27 -0700 Subject: [PATCH 14/27] Add fixed string support Signed-off-by: methylDragon --- .../dynamic_typesupport/dynamic_data.hpp | 45 +++++++++ .../dynamic_type_builder.hpp | 50 ++++++++++ .../dynamic_typesupport/dynamic_data.cpp | 97 +++++++++++++++++++ .../dynamic_type_builder.cpp | 97 +++++++++++++++++++ 4 files changed, 289 insertions(+) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp index 46383be2f3..76755c2e08 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp @@ -278,6 +278,51 @@ class DynamicData : public std::enable_shared_from_this insert_value(ValueT value); + // FIXED STRING MEMBER ACCESS ==================================================================== + RCLCPP_PUBLIC + const std::string + get_fixed_string_value(rosidl_dynamic_typesupport_member_id_t id, size_t string_length); + + RCLCPP_PUBLIC + const std::string + get_fixed_string_value(const std::string & name, size_t string_length); + + RCLCPP_PUBLIC + const std::u16string + get_fixed_wstring_value(rosidl_dynamic_typesupport_member_id_t id, size_t wstring_length); + + RCLCPP_PUBLIC + const std::u16string + get_fixed_wstring_value(const std::string & name, size_t wstring_length); + + RCLCPP_PUBLIC + void + set_fixed_string_value( + rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_length); + + RCLCPP_PUBLIC + void + set_fixed_string_value(const std::string & name, const std::string value, size_t string_length); + + RCLCPP_PUBLIC + void + set_fixed_wstring_value( + rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_length); + + RCLCPP_PUBLIC + void + set_fixed_wstring_value( + const std::string & name, const std::u16string value, size_t wstring_length); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_fixed_string_value(const std::string value, size_t string_length); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_fixed_wstring_value(const std::u16string value, size_t wstring_length); + + // BOUNDED STRING MEMBER ACCESS ================================================================== RCLCPP_PUBLIC const std::string diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp index 84ec949965..6fc8988a7d 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp @@ -224,6 +224,56 @@ class DynamicTypeBuilder : public std::enable_shared_from_this Date: Wed, 29 Mar 2023 16:50:39 -0700 Subject: [PATCH 15/27] Implement SubscriptionType enum flag Signed-off-by: methylDragon --- .../include/rclcpp/dynamic_subscription.hpp | 4 +- .../include/rclcpp/generic_subscription.hpp | 2 +- rclcpp/include/rclcpp/subscription.hpp | 14 +- rclcpp/include/rclcpp/subscription_base.hpp | 43 ++-- rclcpp/src/rclcpp/executor.cpp | 221 ++++++++++-------- rclcpp/src/rclcpp/subscription_base.cpp | 32 +-- 6 files changed, 153 insertions(+), 163 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp index d9606d1618..72125acca5 100644 --- a/rclcpp/include/rclcpp/dynamic_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -67,9 +67,7 @@ class DynamicSubscription : public rclcpp::SubscriptionBase options.to_rcl_subscription_options(qos), options.event_callbacks, options.use_default_callbacks, - false, // is_serialized - true, // is_dynamic - use_take_dynamic_message), + use_take_dynamic_message ? SubscriptionType::DYNAMIC_MESSAGE_DIRECT : SubscriptionType::DYNAMIC_MESSAGE_FROM_SERIALIZED), // NOLINT ts_(type_support), callback_(callback), serialization_support_(nullptr), diff --git a/rclcpp/include/rclcpp/generic_subscription.hpp b/rclcpp/include/rclcpp/generic_subscription.hpp index 9e4c731209..231f4d5f9e 100644 --- a/rclcpp/include/rclcpp/generic_subscription.hpp +++ b/rclcpp/include/rclcpp/generic_subscription.hpp @@ -84,7 +84,7 @@ class GenericSubscription : public rclcpp::SubscriptionBase options.to_rcl_subscription_options(qos), options.event_callbacks, options.use_default_callbacks, - true), + SubscriptionType::SERIALIZED_MESSAGE), callback_(callback), ts_lib_(ts_lib) {} diff --git a/rclcpp/include/rclcpp/subscription.hpp b/rclcpp/include/rclcpp/subscription.hpp index 204032a23e..4111d17af9 100644 --- a/rclcpp/include/rclcpp/subscription.hpp +++ b/rclcpp/include/rclcpp/subscription.hpp @@ -144,7 +144,7 @@ class Subscription : public SubscriptionBase // NOTE(methylDragon): Passing these args separately is necessary for event binding options.event_callbacks, options.use_default_callbacks, - callback.is_serialized_message_callback()), + callback.is_serialized_message_callback() ? SubscriptionType::SERIALIZED_MESSAGE : SubscriptionType::ROS_MESSAGE), // NOLINT any_callback_(callback), options_(options), message_memory_strategy_(message_memory_strategy) @@ -395,28 +395,28 @@ class Subscription : public SubscriptionBase get_shared_dynamic_message_type() override { throw rclcpp::exceptions::UnimplementedError( - "get_shared_dynamic_message_type is not implemented for Subscription"); + "get_shared_dynamic_message_type is not implemented for Subscription"); } rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr get_shared_dynamic_message() override { throw rclcpp::exceptions::UnimplementedError( - "get_shared_dynamic_message is not implemented for Subscription"); + "get_shared_dynamic_message is not implemented for Subscription"); } rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() override { throw rclcpp::exceptions::UnimplementedError( - "get_shared_dynamic_serialization_support is not implemented for Subscription"); + "get_shared_dynamic_serialization_support is not implemented for Subscription"); } rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr create_dynamic_message() override { throw rclcpp::exceptions::UnimplementedError( - "create_dynamic_message is not implemented for Subscription"); + "create_dynamic_message is not implemented for Subscription"); } void @@ -425,7 +425,7 @@ class Subscription : public SubscriptionBase { (void) message; throw rclcpp::exceptions::UnimplementedError( - "return_dynamic_message is not implemented for Subscription"); + "return_dynamic_message is not implemented for Subscription"); } void @@ -436,7 +436,7 @@ class Subscription : public SubscriptionBase (void) message; (void) message_info; throw rclcpp::exceptions::UnimplementedError( - "handle_dynamic_message is not implemented for Subscription"); + "handle_dynamic_message is not implemented for Subscription"); } private: diff --git a/rclcpp/include/rclcpp/subscription_base.hpp b/rclcpp/include/rclcpp/subscription_base.hpp index 72b922d8c2..ceb00b76e0 100644 --- a/rclcpp/include/rclcpp/subscription_base.hpp +++ b/rclcpp/include/rclcpp/subscription_base.hpp @@ -63,6 +63,14 @@ namespace experimental class IntraProcessManager; } // namespace experimental +enum class SubscriptionType : uint8_t +{ + ROS_MESSAGE = 1, // take message as ROS message and handle as ROS message + SERIALIZED_MESSAGE = 2, // take message as serialized and handle as serialized + DYNAMIC_MESSAGE_DIRECT = 3, // take message as DynamicMessage and handle as DynamicMessage + DYNAMIC_MESSAGE_FROM_SERIALIZED = 4 // take message as serialized and handle as DynamicMessage +}; + /// Virtual base class for subscriptions. This pattern allows us to iterate over different template /// specializations of Subscription, among other things. class SubscriptionBase : public std::enable_shared_from_this @@ -79,9 +87,7 @@ class SubscriptionBase : public std::enable_shared_from_this * \param[in] type_support_handle rosidl type support struct, for the Message type of the topic. * \param[in] topic_name Name of the topic to subscribe to. * \param[in] subscription_options Options for the subscription. - * \param[in] is_serialized is true if the message will be delivered still serialized - * \param[in] is_dynamic is true if the message will be delivered dynamic (type constructed at - * runtime) + * \param[in] subscription_type Enum flag to change how the message will be received and delivered */ RCLCPP_PUBLIC SubscriptionBase( @@ -91,9 +97,7 @@ class SubscriptionBase : public std::enable_shared_from_this const rcl_subscription_options_t & subscription_options, const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks, - bool is_serialized = false, - bool is_dynamic = false, - bool use_take_dynamic_message = false); + SubscriptionType subscription_type = SubscriptionType::ROS_MESSAGE); /// Destructor. RCLCPP_PUBLIC @@ -234,13 +238,13 @@ class SubscriptionBase : public std::enable_shared_from_this const rosidl_message_type_support_t & get_message_type_support_handle() const; - /// Return if the subscription is serialized + /// Return the type of the subscription. /** - * \return `true` if the subscription is serialized, `false` otherwise + * \return `SubscriptionType`, which adjusts how messages are received and delivered. */ RCLCPP_PUBLIC - bool - is_serialized() const; + SubscriptionType + get_subscription_type() const; /// Get matching publisher count. /** \return The number of publishers on this topic. */ @@ -583,21 +587,6 @@ class SubscriptionBase : public std::enable_shared_from_this take_dynamic_message( rclcpp::dynamic_typesupport::DynamicMessage & message_out, rclcpp::MessageInfo & message_info_out); - - /// Return if the subscription handles dynamic messages - /** - * This will cause the subscription to use the handle_dynamic_message methods, which must be - * used with take_serialized or take_dynamic_message. - * - * \return `true` if the subscription should use a dynamic message callback, `false` otherwise - */ - RCLCPP_PUBLIC - bool - is_dynamic() const; - - RCLCPP_PUBLIC - bool - use_take_dynamic_message() const; // =============================================================================================== @@ -657,9 +646,7 @@ class SubscriptionBase : public std::enable_shared_from_this RCLCPP_DISABLE_COPY(SubscriptionBase) rosidl_message_type_support_t type_support_; - bool is_serialized_; - bool is_dynamic_; - bool use_take_dynamic_message_; + SubscriptionType subscription_type_; std::atomic subscription_in_use_by_wait_set_{false}; std::atomic intra_process_subscription_waitable_in_use_by_wait_set_{false}; diff --git a/rclcpp/src/rclcpp/executor.cpp b/rclcpp/src/rclcpp/executor.cpp index fde6f8019c..af5069e10e 100644 --- a/rclcpp/src/rclcpp/executor.cpp +++ b/rclcpp/src/rclcpp/executor.cpp @@ -604,114 +604,133 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) rclcpp::MessageInfo message_info; message_info.get_rmw_message_info().from_intra_process = false; - // DYNAMIC SUBSCRIPTION ========================================================================== - // If a subscription is dynamic, then it will use its serialization-specific dynamic data. - // - // Two cases: - // - Dynamic type subscription using dynamic type stored in its own internal type support struct - // - Non-dynamic type subscription with no stored dynamic type - // - Subscriptions of this type must be able to lookup the local message description to - // generate a dynamic type at runtime! - // - TODO(methylDragon): I won't be handling this case yet - if (subscription->is_dynamic()) { - // Take dynamic message directly from the middleware - if (subscription->use_take_dynamic_message()) { - DynamicMessage::SharedPtr dynamic_message = subscription->create_dynamic_message(); - take_and_do_error_handling( - "taking a dynamic message from topic", - subscription->get_topic_name(), - // This modifies the stored dynamic data in the DynamicMessage in-place - [&]() {return subscription->take_dynamic_message(*dynamic_message, message_info);}, - [&]() {subscription->handle_dynamic_message(dynamic_message, message_info);}); - subscription->return_dynamic_message(dynamic_message); + switch (subscription->get_subscription_type()) { - // Take serialized and then convert to dynamic message - } else { - std::shared_ptr serialized_msg = subscription->create_serialized_message(); - - // NOTE(methylDragon): Is this clone necessary? If I'm following the pattern, it seems so. - DynamicMessage::SharedPtr dynamic_message = subscription->create_dynamic_message(); - take_and_do_error_handling( - "taking a serialized message from topic", - subscription->get_topic_name(), - [&]() {return subscription->take_serialized(*serialized_msg.get(), message_info);}, - [&]() - { - bool ret = dynamic_message->deserialize(&serialized_msg->get_rcl_serialized_message()); - if (!ret) { - throw_from_rcl_error(ret, "Couldn't convert serialized message to dynamic data!"); + // Take ROS message + case rclcpp::SubscriptionType::ROS_MESSAGE: + { + if (subscription->can_loan_messages()) { + // This is the case where a loaned message is taken from the middleware via + // inter-process communication, given to the user for their callback, + // and then returned. + void * loaned_msg = nullptr; + // TODO(wjwwood): refactor this into methods on subscription when LoanedMessage + // is extened to support subscriptions as well. + take_and_do_error_handling( + "taking a loaned message from topic", + subscription->get_topic_name(), + [&]() + { + rcl_ret_t ret = rcl_take_loaned_message( + subscription->get_subscription_handle().get(), + &loaned_msg, + &message_info.get_rmw_message_info(), + nullptr); + if (RCL_RET_SUBSCRIPTION_TAKE_FAILED == ret) { + return false; + } else if (RCL_RET_OK != ret) { + rclcpp::exceptions::throw_from_rcl_error(ret); + } + return true; + }, + [&]() {subscription->handle_loaned_message(loaned_msg, message_info);}); + if (nullptr != loaned_msg) { + rcl_ret_t ret = rcl_return_loaned_message_from_subscription( + subscription->get_subscription_handle().get(), loaned_msg); + if (RCL_RET_OK != ret) { + RCLCPP_ERROR( + rclcpp::get_logger( + "rclcpp"), + "rcl_return_loaned_message_from_subscription() failed for subscription on topic '%s':" + " %s", + subscription->get_topic_name(), rcl_get_error_string().str); + } + loaned_msg = nullptr; } - subscription->handle_dynamic_message(dynamic_message, message_info); + } else { + // This case is taking a copy of the message data from the middleware via + // inter-process communication. + std::shared_ptr message = subscription->create_message(); + take_and_do_error_handling( + "taking a message from topic", + subscription->get_topic_name(), + [&]() {return subscription->take_type_erased(message.get(), message_info);}, + [&]() {subscription->handle_message(message, message_info);}); + subscription->return_message(message); } - ); - subscription->return_serialized_message(serialized_msg); - subscription->return_dynamic_message(dynamic_message); - } - return; - } - // =============================================================================================== - - if (subscription->is_serialized()) { - // This is the case where a copy of the serialized message is taken from - // the middleware via inter-process communication. - std::shared_ptr serialized_msg = subscription->create_serialized_message(); - take_and_do_error_handling( - "taking a serialized message from topic", - subscription->get_topic_name(), - [&]() {return subscription->take_serialized(*serialized_msg.get(), message_info);}, - [&]() + break; + } + + // Take serialized message + case rclcpp::SubscriptionType::SERIALIZED_MESSAGE: { - subscription->handle_serialized_message(serialized_msg, message_info); - }); - subscription->return_serialized_message(serialized_msg); - } else if (subscription->can_loan_messages()) { - // This is the case where a loaned message is taken from the middleware via - // inter-process communication, given to the user for their callback, - // and then returned. - void * loaned_msg = nullptr; - // TODO(wjwwood): refactor this into methods on subscription when LoanedMessage - // is extened to support subscriptions as well. - take_and_do_error_handling( - "taking a loaned message from topic", - subscription->get_topic_name(), - [&]() + // This is the case where a copy of the serialized message is taken from + // the middleware via inter-process communication. + std::shared_ptr serialized_msg = + subscription->create_serialized_message(); + take_and_do_error_handling( + "taking a serialized message from topic", + subscription->get_topic_name(), + [&]() {return subscription->take_serialized(*serialized_msg.get(), message_info);}, + [&]() + { + subscription->handle_serialized_message(serialized_msg, message_info); + }); + subscription->return_serialized_message(serialized_msg); + break; + } + + // DYNAMIC SUBSCRIPTION ======================================================================== + // If a subscription is dynamic, then it will use its serialization-specific dynamic data. + // + // Two cases: + // - Dynamic type subscription using dynamic type stored in its own internal type support struct + // - Non-dynamic type subscription with no stored dynamic type + // - Subscriptions of this type must be able to lookup the local message description to + // generate a dynamic type at runtime! + // - TODO(methylDragon): I won't be handling this case yet + + // Take dynamic message directly from the middleware + case rclcpp::SubscriptionType::DYNAMIC_MESSAGE_DIRECT: { - rcl_ret_t ret = rcl_take_loaned_message( - subscription->get_subscription_handle().get(), - &loaned_msg, - &message_info.get_rmw_message_info(), - nullptr); - if (RCL_RET_SUBSCRIPTION_TAKE_FAILED == ret) { - return false; - } else if (RCL_RET_OK != ret) { - rclcpp::exceptions::throw_from_rcl_error(ret); - } - return true; - }, - [&]() {subscription->handle_loaned_message(loaned_msg, message_info);}); - if (nullptr != loaned_msg) { - rcl_ret_t ret = rcl_return_loaned_message_from_subscription( - subscription->get_subscription_handle().get(), - loaned_msg); - if (RCL_RET_OK != ret) { - RCLCPP_ERROR( - rclcpp::get_logger("rclcpp"), - "rcl_return_loaned_message_from_subscription() failed for subscription on topic '%s': %s", - subscription->get_topic_name(), rcl_get_error_string().str); + DynamicMessage::SharedPtr dynamic_message = subscription->create_dynamic_message(); + take_and_do_error_handling( + "taking a dynamic message from topic", + subscription->get_topic_name(), + // This modifies the stored dynamic data in the DynamicMessage in-place + [&]() {return subscription->take_dynamic_message(*dynamic_message, message_info);}, + [&]() {subscription->handle_dynamic_message(dynamic_message, message_info);}); + subscription->return_dynamic_message(dynamic_message); + break; + } + + // Take serialized and then convert to dynamic message + case rclcpp::SubscriptionType::DYNAMIC_MESSAGE_FROM_SERIALIZED: + { + std::shared_ptr serialized_msg = + subscription->create_serialized_message(); + + // NOTE(methylDragon): Is this clone necessary? If I'm following the pattern, it seems so. + DynamicMessage::SharedPtr dynamic_message = subscription->create_dynamic_message(); + take_and_do_error_handling( + "taking a serialized message from topic", + subscription->get_topic_name(), + [&]() {return subscription->take_serialized(*serialized_msg.get(), message_info);}, + [&]() + { + bool ret = dynamic_message->deserialize(&serialized_msg->get_rcl_serialized_message()); + if (!ret) { + throw_from_rcl_error(ret, "Couldn't convert serialized message to dynamic data!"); + } + subscription->handle_dynamic_message(dynamic_message, message_info); + } + ); + subscription->return_serialized_message(serialized_msg); + subscription->return_dynamic_message(dynamic_message); + break; } - loaned_msg = nullptr; - } - } else { - // This case is taking a copy of the message data from the middleware via - // inter-process communication. - std::shared_ptr message = subscription->create_message(); - take_and_do_error_handling( - "taking a message from topic", - subscription->get_topic_name(), - [&]() {return subscription->take_type_erased(message.get(), message_info);}, - [&]() {subscription->handle_message(message, message_info);}); - subscription->return_message(message); } + return; } void diff --git a/rclcpp/src/rclcpp/subscription_base.cpp b/rclcpp/src/rclcpp/subscription_base.cpp index 38e21e61c3..5d89308c4a 100644 --- a/rclcpp/src/rclcpp/subscription_base.cpp +++ b/rclcpp/src/rclcpp/subscription_base.cpp @@ -44,9 +44,7 @@ SubscriptionBase::SubscriptionBase( const rcl_subscription_options_t & subscription_options, const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks, - bool is_serialized, - bool is_dynamic, - bool use_take_dynamic_message) + SubscriptionType subscription_type) : node_base_(node_base), node_handle_(node_base_->get_shared_rcl_node_handle()), node_logger_(rclcpp::get_node_logger(node_handle_.get())), @@ -54,13 +52,13 @@ SubscriptionBase::SubscriptionBase( intra_process_subscription_id_(0), event_callbacks_(event_callbacks), type_support_(type_support_handle), - is_serialized_(is_serialized), - is_dynamic_(is_dynamic), - use_take_dynamic_message_(use_take_dynamic_message) + subscription_type_(subscription_type) { - if (!rmw_feature_supported(RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_MESSAGE) && use_take_dynamic_message_) + if (!rmw_feature_supported(RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_MESSAGE) + && subscription_type == rclcpp::SubscriptionType::DYNAMIC_MESSAGE_DIRECT) { - throw std::runtime_error("Cannot use_take_dynamic_message, feature not supported in rmw"); + throw std::runtime_error( + "Cannot set subscription to take dynamic message directly, feature not supported in rmw"); } auto custom_deletor = [node_handle = this->node_handle_](rcl_subscription_t * rcl_subs) @@ -267,10 +265,10 @@ SubscriptionBase::get_message_type_support_handle() const return type_support_; } -bool -SubscriptionBase::is_serialized() const +rclcpp::SubscriptionType +SubscriptionBase::get_subscription_type() const { - return is_serialized_; + return subscription_type_; } size_t @@ -530,18 +528,6 @@ SubscriptionBase::get_content_filter() const // DYNAMIC TYPE ================================================================================== // TODO(methylDragon): Reorder later -bool -SubscriptionBase::is_dynamic() const -{ - return is_dynamic_; -} - -bool -SubscriptionBase::use_take_dynamic_message() const -{ - return use_take_dynamic_message_; -} - bool SubscriptionBase::take_dynamic_message( rclcpp::dynamic_typesupport::DynamicMessage & message_out, From 24e533eba7919cced4b1f51466b4ab1660def3fe Mon Sep 17 00:00:00 2001 From: methylDragon Date: Wed, 29 Mar 2023 17:29:42 -0700 Subject: [PATCH 16/27] Unalias dynamic typesupport types Signed-off-by: methylDragon --- rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp | 2 +- rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp | 2 +- .../include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp index 76755c2e08..0482499915 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp @@ -52,7 +52,7 @@ class DynamicTypeBuilder; * * Note: This class is meant to map to the lower level rosidl_dynamic_typesupport_dynamic_data_t, * even though rosidl_dynamic_typesupport_dynamic_data_t is equivalent to - * rmw_dynamic_message_t, exposing the fundamental methods available to + * rosidl_dynamic_typesupport_dynamic_data_t, exposing the fundamental methods available to * rosidl_dynamic_typesupport_dynamic_data_t, allowing the user to access the data's fields. */ class DynamicData : public std::enable_shared_from_this diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index 5c377ede72..abdc56a926 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -39,7 +39,7 @@ namespace dynamic_typesupport // I'd have made a wrapper class but then I'd need to redirect every single // method (or dynamic cast everywhere else) // -/// This type maps to the underlying rmw_dynamic_message_t, rather than the equivalent +/// This type maps to the underlying rosidl_dynamic_typesupport_dynamic_data_t, rather than the equivalent /// rosidl_dynamic_typesupport_dynamic_data_t struct. using DynamicMessage = DynamicData; diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index 68442d4567..60e31ec63f 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -37,7 +37,7 @@ namespace dynamic_typesupport // I'd have made a wrapper class but then I'd need to redirect every single // method (or dynamic cast everywhere else) // -/// This type maps to the underlying rmw_dynamic_message_type_t, rather than the equivalent +/// This type maps to the underlying rosidl_dynamic_typesupport_dynamic_type_t, rather than the equivalent /// rosidl_dynamic_typesupport_dynamic_type_t struct. using DynamicMessageType = DynamicType; From aac28e7b9f3f9d8cdb4e63f1fd29bd2bf035e35e Mon Sep 17 00:00:00 2001 From: methylDragon Date: Thu, 30 Mar 2023 13:15:33 -0700 Subject: [PATCH 17/27] Remove dynamic data/type aliases Signed-off-by: methylDragon --- rclcpp/CMakeLists.txt | 6 +- ...data_impl.hpp => dynamic_message_impl.hpp} | 124 ++--- ... => dynamic_message_type_builder_impl.hpp} | 84 ++-- .../dynamic_typesupport/dynamic_data.hpp | 433 ------------------ .../dynamic_typesupport/dynamic_message.hpp | 404 +++++++++++++++- .../dynamic_message_type.hpp | 176 ++++++- ...r.hpp => dynamic_message_type_builder.hpp} | 79 ++-- .../dynamic_message_type_support.hpp | 4 +- .../dynamic_typesupport/dynamic_type.hpp | 205 --------- rclcpp/include/rclcpp/rclcpp.hpp | 8 +- .../{dynamic_data.cpp => dynamic_message.cpp} | 201 ++++---- ...amic_type.cpp => dynamic_message_type.cpp} | 86 ++-- ...r.cpp => dynamic_message_type_builder.cpp} | 170 +++---- .../dynamic_message_type_support.cpp | 6 +- .../node_interfaces/test_node_topics.cpp | 2 +- 15 files changed, 944 insertions(+), 1044 deletions(-) rename rclcpp/include/rclcpp/dynamic_typesupport/detail/{dynamic_data_impl.hpp => dynamic_message_impl.hpp} (62%) rename rclcpp/include/rclcpp/dynamic_typesupport/detail/{dynamic_type_builder_impl.hpp => dynamic_message_type_builder_impl.hpp} (60%) delete mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp rename rclcpp/include/rclcpp/dynamic_typesupport/{dynamic_type_builder.hpp => dynamic_message_type_builder.hpp} (83%) delete mode 100644 rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type.hpp rename rclcpp/src/rclcpp/dynamic_typesupport/{dynamic_data.cpp => dynamic_message.cpp} (77%) rename rclcpp/src/rclcpp/dynamic_typesupport/{dynamic_type.cpp => dynamic_message_type.cpp} (79%) rename rclcpp/src/rclcpp/dynamic_typesupport/{dynamic_type_builder.cpp => dynamic_message_type_builder.cpp} (78%) diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index 2a36c5fc07..bfe2b74563 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -49,11 +49,11 @@ set(${PROJECT_NAME}_SRCS src/rclcpp/detail/rmw_implementation_specific_subscription_payload.cpp src/rclcpp/detail/utilities.cpp src/rclcpp/duration.cpp - src/rclcpp/dynamic_typesupport/dynamic_data.cpp + src/rclcpp/dynamic_typesupport/dynamic_message.cpp + src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp + src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp - src/rclcpp/dynamic_typesupport/dynamic_type.cpp - src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp src/rclcpp/event.cpp src/rclcpp/exceptions/exceptions.cpp src/rclcpp/executable_list.cpp diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp similarity index 62% rename from rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp rename to rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp index b27c237130..79e04d68b3 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_ -#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_ +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_ #include #include @@ -24,15 +24,15 @@ #include #include "rclcpp/exceptions.hpp" -#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_ -#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_ +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #endif -#define __DYNAMIC_DATA_GET_VALUE_BY_ID_FN(ValueT, FunctionT) \ +#define __DYNAMIC_MESSAGE_GET_VALUE_BY_ID_FN(ValueT, FunctionT) \ template<> \ ValueT \ - DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) \ + DynamicMessage::get_value(rosidl_dynamic_typesupport_member_id_t id) \ { \ ValueT out; \ rosidl_dynamic_typesupport_dynamic_data_get_ ## FunctionT ## _value( \ @@ -40,35 +40,35 @@ return out; \ } -#define __DYNAMIC_DATA_GET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ +#define __DYNAMIC_MESSAGE_GET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ template<> \ ValueT \ - DynamicData::get_value(const std::string & name) \ + DynamicMessage::get_value(const std::string & name) \ { \ return get_value(get_member_id(name)); \ } -#define __DYNAMIC_DATA_SET_VALUE_BY_ID_FN(ValueT, FunctionT) \ +#define __DYNAMIC_MESSAGE_SET_VALUE_BY_ID_FN(ValueT, FunctionT) \ template<> \ void \ - DynamicData::set_value(rosidl_dynamic_typesupport_member_id_t id, ValueT value) \ + DynamicMessage::set_value(rosidl_dynamic_typesupport_member_id_t id, ValueT value) \ { \ rosidl_dynamic_typesupport_dynamic_data_set_ ## FunctionT ## _value( \ rosidl_dynamic_data_.get(), id, value); \ } -#define __DYNAMIC_DATA_SET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ +#define __DYNAMIC_MESSAGE_SET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ template<> \ void \ - DynamicData::set_value(const std::string & name, ValueT value) \ + DynamicMessage::set_value(const std::string & name, ValueT value) \ { \ set_value(get_member_id(name), value); \ } -#define __DYNAMIC_DATA_INSERT_VALUE(ValueT, FunctionT) \ +#define __DYNAMIC_MESSAGE_INSERT_VALUE(ValueT, FunctionT) \ template<> \ rosidl_dynamic_typesupport_member_id_t \ - DynamicData::insert_value(ValueT value) \ + DynamicMessage::insert_value(ValueT value) \ { \ rosidl_dynamic_typesupport_member_id_t out; \ rosidl_dynamic_typesupport_dynamic_data_insert_ ## FunctionT ## _value( \ @@ -76,12 +76,12 @@ return out; \ } -#define DYNAMIC_DATA_DEFINITIONS(ValueT, FunctionT) \ - __DYNAMIC_DATA_GET_VALUE_BY_ID_FN(ValueT, FunctionT) \ - __DYNAMIC_DATA_GET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ - __DYNAMIC_DATA_SET_VALUE_BY_ID_FN(ValueT, FunctionT) \ - __DYNAMIC_DATA_SET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ - __DYNAMIC_DATA_INSERT_VALUE(ValueT, FunctionT) +#define DYNAMIC_MESSAGE_DEFINITIONS(ValueT, FunctionT) \ + __DYNAMIC_MESSAGE_GET_VALUE_BY_ID_FN(ValueT, FunctionT) \ + __DYNAMIC_MESSAGE_GET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ + __DYNAMIC_MESSAGE_SET_VALUE_BY_ID_FN(ValueT, FunctionT) \ + __DYNAMIC_MESSAGE_SET_VALUE_BY_NAME_FN(ValueT, FunctionT) \ + __DYNAMIC_MESSAGE_INSERT_VALUE(ValueT, FunctionT) namespace rclcpp @@ -101,21 +101,21 @@ namespace dynamic_typesupport * - String types: std::string, std::u16string */ -DYNAMIC_DATA_DEFINITIONS(bool, bool); -// DYNAMIC_DATA_DEFINITIONS(std::byte, byte); -DYNAMIC_DATA_DEFINITIONS(char, char); -DYNAMIC_DATA_DEFINITIONS(float, float32); -DYNAMIC_DATA_DEFINITIONS(double, float64); -DYNAMIC_DATA_DEFINITIONS(int8_t, int8); -DYNAMIC_DATA_DEFINITIONS(int16_t, int16); -DYNAMIC_DATA_DEFINITIONS(int32_t, int32); -DYNAMIC_DATA_DEFINITIONS(int64_t, int64); -DYNAMIC_DATA_DEFINITIONS(uint8_t, uint8); -DYNAMIC_DATA_DEFINITIONS(uint16_t, uint16); -DYNAMIC_DATA_DEFINITIONS(uint32_t, uint32); -DYNAMIC_DATA_DEFINITIONS(uint64_t, uint64); -// DYNAMIC_DATA_DEFINITIONS(std::string, std::string); -// DYNAMIC_DATA_DEFINITIONS(std::u16string, std::u16string); +DYNAMIC_MESSAGE_DEFINITIONS(bool, bool); +// DYNAMIC_MESSAGE_DEFINITIONS(std::byte, byte); +DYNAMIC_MESSAGE_DEFINITIONS(char, char); +DYNAMIC_MESSAGE_DEFINITIONS(float, float32); +DYNAMIC_MESSAGE_DEFINITIONS(double, float64); +DYNAMIC_MESSAGE_DEFINITIONS(int8_t, int8); +DYNAMIC_MESSAGE_DEFINITIONS(int16_t, int16); +DYNAMIC_MESSAGE_DEFINITIONS(int32_t, int32); +DYNAMIC_MESSAGE_DEFINITIONS(int64_t, int64); +DYNAMIC_MESSAGE_DEFINITIONS(uint8_t, uint8); +DYNAMIC_MESSAGE_DEFINITIONS(uint16_t, uint16); +DYNAMIC_MESSAGE_DEFINITIONS(uint32_t, uint32); +DYNAMIC_MESSAGE_DEFINITIONS(uint64_t, uint64); +// DYNAMIC_MESSAGE_DEFINITIONS(std::string, std::string); +// DYNAMIC_MESSAGE_DEFINITIONS(std::u16string, std::u16string); // Byte and String getters have a different implementation and are defined below @@ -123,7 +123,7 @@ DYNAMIC_DATA_DEFINITIONS(uint64_t, uint64); // BYTE ============================================================================================ template<> std::byte -DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) +DynamicMessage::get_value(rosidl_dynamic_typesupport_member_id_t id) { unsigned char out; rosidl_dynamic_typesupport_dynamic_data_get_byte_value(get_rosidl_dynamic_data(), id, &out); @@ -133,7 +133,7 @@ DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) template<> std::byte -DynamicData::get_value(const std::string & name) +DynamicMessage::get_value(const std::string & name) { return get_value(get_member_id(name)); } @@ -141,7 +141,7 @@ DynamicData::get_value(const std::string & name) template<> void -DynamicData::set_value( +DynamicMessage::set_value( rosidl_dynamic_typesupport_member_id_t id, const std::byte value) { rosidl_dynamic_typesupport_dynamic_data_set_byte_value( @@ -151,7 +151,7 @@ DynamicData::set_value( template<> void -DynamicData::set_value(const std::string & name, const std::byte value) +DynamicMessage::set_value(const std::string & name, const std::byte value) { set_value(get_member_id(name), value); } @@ -159,7 +159,7 @@ DynamicData::set_value(const std::string & name, const std::byte valu template<> rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_value(const std::byte value) +DynamicMessage::insert_value(const std::byte value) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_byte_value( @@ -171,7 +171,7 @@ DynamicData::insert_value(const std::byte value) // STRINGS ========================================================================================= template<> std::string -DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) +DynamicMessage::get_value(rosidl_dynamic_typesupport_member_id_t id) { size_t buf_length; char * buf = nullptr; @@ -185,7 +185,7 @@ DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) template<> std::u16string -DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) +DynamicMessage::get_value(rosidl_dynamic_typesupport_member_id_t id) { size_t buf_length; char16_t * buf = nullptr; @@ -199,7 +199,7 @@ DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id template<> std::string -DynamicData::get_value(const std::string & name) +DynamicMessage::get_value(const std::string & name) { return get_value(get_member_id(name)); } @@ -207,7 +207,7 @@ DynamicData::get_value(const std::string & name) template<> std::u16string -DynamicData::get_value(const std::string & name) +DynamicMessage::get_value(const std::string & name) { return get_value(get_member_id(name)); } @@ -215,7 +215,7 @@ DynamicData::get_value(const std::string & name) template<> void -DynamicData::set_value( +DynamicMessage::set_value( rosidl_dynamic_typesupport_member_id_t id, const std::string value) { rosidl_dynamic_typesupport_dynamic_data_set_string_value( @@ -225,7 +225,7 @@ DynamicData::set_value( template<> void -DynamicData::set_value( +DynamicMessage::set_value( rosidl_dynamic_typesupport_member_id_t id, const std::u16string value) { rosidl_dynamic_typesupport_dynamic_data_set_wstring_value( @@ -235,7 +235,7 @@ DynamicData::set_value( template<> void -DynamicData::set_value(const std::string & name, const std::string value) +DynamicMessage::set_value(const std::string & name, const std::string value) { set_value(get_member_id(name), value); } @@ -243,7 +243,7 @@ DynamicData::set_value(const std::string & name, const std::string template<> void -DynamicData::set_value(const std::string & name, const std::u16string value) +DynamicMessage::set_value(const std::string & name, const std::u16string value) { set_value(get_member_id(name), value); } @@ -251,7 +251,7 @@ DynamicData::set_value(const std::string & name, const std::u16s template<> rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_value(const std::string value) +DynamicMessage::insert_value(const std::string value) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_string_value( @@ -262,7 +262,7 @@ DynamicData::insert_value(const std::string value) template<> rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_value(const std::u16string value) +DynamicMessage::insert_value(const std::u16string value) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_wstring_value( @@ -274,7 +274,7 @@ DynamicData::insert_value(const std::u16string value) // THROW FOR UNSUPPORTED TYPES ===================================================================== template ValueT -DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) +DynamicMessage::get_value(rosidl_dynamic_typesupport_member_id_t id) { throw rclcpp::exceptions::UnimplementedError("get_value is not implemented for input type"); } @@ -282,7 +282,7 @@ DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id) template ValueT -DynamicData::get_value(const std::string & name) +DynamicMessage::get_value(const std::string & name) { throw rclcpp::exceptions::UnimplementedError("get_value is not implemented for input type"); } @@ -290,7 +290,7 @@ DynamicData::get_value(const std::string & name) template void -DynamicData::set_value( +DynamicMessage::set_value( rosidl_dynamic_typesupport_member_id_t id, ValueT value) { throw rclcpp::exceptions::UnimplementedError("set_value is not implemented for input type"); @@ -299,7 +299,7 @@ DynamicData::set_value( template void -DynamicData::set_value(const std::string & name, ValueT value) +DynamicMessage::set_value(const std::string & name, ValueT value) { throw rclcpp::exceptions::UnimplementedError("set_value is not implemented for input type"); } @@ -307,7 +307,7 @@ DynamicData::set_value(const std::string & name, ValueT value) template rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_value(ValueT value) +DynamicMessage::insert_value(ValueT value) { throw rclcpp::exceptions::UnimplementedError("insert_value is not implemented for input type"); } @@ -316,11 +316,11 @@ DynamicData::insert_value(ValueT value) } // namespace dynamic_typesupport } // namespace rclcpp -#undef __DYNAMIC_DATA_GET_VALUE_BY_ID_FN -#undef __DYNAMIC_DATA_GET_VALUE_BY_NAME_FN -#undef __DYNAMIC_DATA_SET_VALUE_BY_ID_FN -#undef __DYNAMIC_DATA_SET_VALUE_BY_NAME_FN -#undef __DYNAMIC_DATA_INSERT_VALUE -#undef DYNAMIC_DATA_DEFINITIONS +#undef __DYNAMIC_MESSAGE_GET_VALUE_BY_ID_FN +#undef __DYNAMIC_MESSAGE_GET_VALUE_BY_NAME_FN +#undef __DYNAMIC_MESSAGE_SET_VALUE_BY_ID_FN +#undef __DYNAMIC_MESSAGE_SET_VALUE_BY_NAME_FN +#undef __DYNAMIC_MESSAGE_INSERT_VALUE +#undef DYNAMIC_MESSAGE_DEFINITIONS -#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_ +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp similarity index 60% rename from rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp rename to rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp index d71bbcf010..a0c3285fba 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_TYPE_BUILDER_IMPL_HPP_ -#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_TYPE_BUILDER_IMPL_HPP_ +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_ #include #include @@ -24,15 +24,15 @@ #include #include "rclcpp/exceptions.hpp" -#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_ -#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_ +#include "rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp" #endif -#define __DYNAMIC_TYPE_BUILDER_ADD_MEMBER_FN(MemberT, FunctionT) \ +#define __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_MEMBER_FN(MemberT, FunctionT) \ template<> \ void \ - DynamicTypeBuilder::add_member( \ + DynamicMessageTypeBuilder::add_member( \ rosidl_dynamic_typesupport_member_id_t id, \ const std::string & name, \ const std::string & default_value) \ @@ -42,10 +42,10 @@ id, name.c_str(), name.size(), default_value.c_str(), default_value.size()); \ } -#define __DYNAMIC_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN(MemberT, FunctionT) \ +#define __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN(MemberT, FunctionT) \ template<> \ void \ - DynamicTypeBuilder::add_array_member( \ + DynamicMessageTypeBuilder::add_array_member( \ rosidl_dynamic_typesupport_member_id_t id, const std::string & name, \ size_t array_length, \ const std::string & default_value) \ @@ -56,10 +56,10 @@ array_length); \ } -#define __DYNAMIC_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ +#define __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ template<> \ void \ - DynamicTypeBuilder::add_unbounded_sequence_member( \ + DynamicMessageTypeBuilder::add_unbounded_sequence_member( \ rosidl_dynamic_typesupport_member_id_t id, \ const std::string & name, \ const std::string & default_value) \ @@ -70,10 +70,10 @@ id, name.c_str(), name.size(), default_value.c_str(), default_value.size()); \ } -#define __DYNAMIC_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ +#define __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ template<> \ void \ - DynamicTypeBuilder::add_bounded_sequence_member( \ + DynamicMessageTypeBuilder::add_bounded_sequence_member( \ rosidl_dynamic_typesupport_member_id_t id, \ const std::string & name, \ size_t sequence_bound, \ @@ -85,11 +85,11 @@ sequence_bound); \ } -#define DYNAMIC_TYPE_BUILDER_DEFINITIONS(MemberT, FunctionT) \ - __DYNAMIC_TYPE_BUILDER_ADD_MEMBER_FN(MemberT, FunctionT) \ - __DYNAMIC_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN(MemberT, FunctionT) \ - __DYNAMIC_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ - __DYNAMIC_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ +#define DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(MemberT, FunctionT) \ + __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_MEMBER_FN(MemberT, FunctionT) \ + __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN(MemberT, FunctionT) \ + __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ + __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \ namespace rclcpp @@ -109,27 +109,27 @@ namespace dynamic_typesupport * - String types: std::string, std::u16string */ -DYNAMIC_TYPE_BUILDER_DEFINITIONS(bool, bool); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(std::byte, byte); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(char, char); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(float, float32); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(double, float64); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(int8_t, int8); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(int16_t, int16); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(int32_t, int32); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(int64_t, int64); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(uint8_t, uint8); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(uint16_t, uint16); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(uint32_t, uint32); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(uint64_t, uint64); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(std::string, string); -DYNAMIC_TYPE_BUILDER_DEFINITIONS(std::u16string, wstring); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(bool, bool); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(std::byte, byte); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(char, char); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(float, float32); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(double, float64); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(int8_t, int8); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(int16_t, int16); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(int32_t, int32); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(int64_t, int64); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(uint8_t, uint8); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(uint16_t, uint16); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(uint32_t, uint32); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(uint64_t, uint64); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(std::string, string); +DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS(std::u16string, wstring); // THROW FOR UNSUPPORTED TYPES ===================================================================== template void -DynamicTypeBuilder::add_member( +DynamicMessageTypeBuilder::add_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, const std::string & default_value) @@ -141,7 +141,7 @@ DynamicTypeBuilder::add_member( template void -DynamicTypeBuilder::add_array_member( +DynamicMessageTypeBuilder::add_array_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length, const std::string & default_value) @@ -153,7 +153,7 @@ DynamicTypeBuilder::add_array_member( template void -DynamicTypeBuilder::add_unbounded_sequence_member( +DynamicMessageTypeBuilder::add_unbounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, const std::string & default_value) @@ -165,7 +165,7 @@ DynamicTypeBuilder::add_unbounded_sequence_member( template void -DynamicTypeBuilder::add_bounded_sequence_member( +DynamicMessageTypeBuilder::add_bounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound, @@ -179,10 +179,10 @@ DynamicTypeBuilder::add_bounded_sequence_member( } // namespace dynamic_typesupport } // namespace rclcpp -#undef __DYNAMIC_TYPE_BUILDER_ADD_MEMBER_FN -#undef __DYNAMIC_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN -#undef __DYNAMIC_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN -#undef __DYNAMIC_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN -#undef DYNAMIC_TYPE_BUILDER_DEFINITIONS +#undef __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_MEMBER_FN +#undef __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN +#undef __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN +#undef __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN +#undef DYNAMIC_MESSAGE_TYPE_BUILDER_DEFINITIONS -#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_TYPE_BUILDER_IMPL_HPP_ +#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp deleted file mode 100644 index 0482499915..0000000000 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_data.hpp +++ /dev/null @@ -1,433 +0,0 @@ -// Copyright 2023 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. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_ -#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_ - - -#include -#include - -#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/macros.hpp" -#include "rclcpp/visibility_control.hpp" - -#include -#include - - -namespace rclcpp -{ -namespace dynamic_typesupport -{ - - -class DynamicType; -class DynamicTypeBuilder; - -/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_data_t * -/** - * This class: - * - Manages the lifetime of the raw pointer. - * - Exposes getter methods to get the raw pointer and shared pointers - * - Exposes the underlying serialization support API - * - * Ownership: - * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed - * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. - * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer - * must point to the same location in memory as the stored raw pointer! - * - * Note: This class is meant to map to the lower level rosidl_dynamic_typesupport_dynamic_data_t, - * even though rosidl_dynamic_typesupport_dynamic_data_t is equivalent to - * rosidl_dynamic_typesupport_dynamic_data_t, exposing the fundamental methods available to - * rosidl_dynamic_typesupport_dynamic_data_t, allowing the user to access the data's fields. - */ -class DynamicData : public std::enable_shared_from_this -{ -public: - RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicData) - - // CONSTRUCTION ================================================================================== - // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the - // lifetime of the serialization support (if the constructor cannot otherwise get it from args). - // - // In cases where a dynamic data pointer is passed, the serialization support composed by - // the data should be the exact same object managed by the DynamicSerializationSupport, - // otherwise the lifetime management will not work properly. - - /// Construct a new DynamicData with the provided dynamic type builder - RCLCPP_PUBLIC - explicit DynamicData(std::shared_ptr dynamic_type_builder); - - /// Construct a new DynamicData with the provided dynamic type - RCLCPP_PUBLIC - explicit DynamicData(std::shared_ptr dynamic_type); - - /// Assume ownership of raw pointer - RCLCPP_PUBLIC - DynamicData( - DynamicSerializationSupport::SharedPtr serialization_support, - rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data); - - /// Copy shared pointer - RCLCPP_PUBLIC - DynamicData( - DynamicSerializationSupport::SharedPtr serialization_support, - std::shared_ptr rosidl_dynamic_data); - - /// Loaning constructor - /// Must only be called with raw ptr obtained from loaning! - // NOTE(methylDragon): I'd put this in protected, but I need this exposed to - // enable_shared_from_this... - RCLCPP_PUBLIC - DynamicData( - DynamicData::SharedPtr parent_data, - rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data); - - // NOTE(methylDragon): Deliberately no constructor from description to nudge users towards using - // construction from dynamic type/builder, which is more efficient - - /// Copy constructor - RCLCPP_PUBLIC - DynamicData(const DynamicData & other); - - /// Move constructor - RCLCPP_PUBLIC - DynamicData(DynamicData && other) noexcept; - - /// Copy assignment - RCLCPP_PUBLIC - DynamicData & operator=(const DynamicData & other); - - /// Move assignment - RCLCPP_PUBLIC - DynamicData & operator=(DynamicData && other) noexcept; - - RCLCPP_PUBLIC - virtual ~DynamicData(); - - - // GETTERS ======================================================================================= - RCLCPP_PUBLIC - const std::string - get_library_identifier() const; - - RCLCPP_PUBLIC - const std::string - get_name() const; - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_dynamic_data_t * - get_rosidl_dynamic_data(); - - RCLCPP_PUBLIC - const rosidl_dynamic_typesupport_dynamic_data_t * - get_rosidl_dynamic_data() const; - - RCLCPP_PUBLIC - std::shared_ptr - get_shared_rosidl_dynamic_data(); - - RCLCPP_PUBLIC - std::shared_ptr - get_shared_rosidl_dynamic_data() const; - - RCLCPP_PUBLIC - DynamicSerializationSupport::SharedPtr - get_shared_dynamic_serialization_support(); - - RCLCPP_PUBLIC - DynamicSerializationSupport::ConstSharedPtr - get_shared_dynamic_serialization_support() const; - - RCLCPP_PUBLIC - size_t - get_item_count() const; - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - get_member_id(size_t index) const; - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - get_member_id(const std::string & name) const; - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - get_array_index(size_t index) const; - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - get_array_index(const std::string & name) const; - - - // METHODS ======================================================================================= - RCLCPP_PUBLIC - DynamicData - clone() const; - - RCLCPP_PUBLIC - DynamicData::SharedPtr - clone_shared() const; - - RCLCPP_PUBLIC - DynamicData - init_from_type(DynamicMessageType & type) const; - - RCLCPP_PUBLIC - DynamicData::SharedPtr - init_from_type_shared(DynamicMessageType & type) const; - - RCLCPP_PUBLIC - bool - equals(const DynamicData & other) const; - - RCLCPP_PUBLIC - DynamicData::SharedPtr - loan_value(rosidl_dynamic_typesupport_member_id_t id); - - RCLCPP_PUBLIC - DynamicData::SharedPtr - loan_value(const std::string & name); - - RCLCPP_PUBLIC - void - clear_all_values(); - - RCLCPP_PUBLIC - void - clear_nonkey_values(); - - RCLCPP_PUBLIC - void - clear_value(rosidl_dynamic_typesupport_member_id_t id); - - RCLCPP_PUBLIC - void - clear_value(const std::string & name); - - RCLCPP_PUBLIC - void - clear_sequence(); - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - insert_sequence_data(); - - RCLCPP_PUBLIC - void - remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index); - - RCLCPP_PUBLIC - void - print() const; - - RCLCPP_PUBLIC - bool - serialize(rcl_serialized_message_t * buffer); - - RCLCPP_PUBLIC - bool - deserialize(rcl_serialized_message_t * buffer); - - - // MEMBER ACCESS TEMPLATES ======================================================================= - /** - * Since we're in a ROS layer, these should support all ROS interface C++ types as found in: - * https://docs.ros.org/en/rolling/Concepts/About-ROS-Interfaces.html - * - * Explicitly: - * - Basic types: bool, byte, char - * - Float types: float, double - * - Int types: int8_t, int16_t, int32_t, int64_t - * - Unsigned int types: uint8_t, uint16_t, uint32_t, uint64_t - * - String types: std::string, std::u16string - */ - - template - ValueT - get_value(rosidl_dynamic_typesupport_member_id_t id); - - template - ValueT - get_value(const std::string & name); - - template - void - set_value(rosidl_dynamic_typesupport_member_id_t id, ValueT value); - - template - void - set_value(const std::string & name, ValueT value); - - template - rosidl_dynamic_typesupport_member_id_t - insert_value(ValueT value); - - - // FIXED STRING MEMBER ACCESS ==================================================================== - RCLCPP_PUBLIC - const std::string - get_fixed_string_value(rosidl_dynamic_typesupport_member_id_t id, size_t string_length); - - RCLCPP_PUBLIC - const std::string - get_fixed_string_value(const std::string & name, size_t string_length); - - RCLCPP_PUBLIC - const std::u16string - get_fixed_wstring_value(rosidl_dynamic_typesupport_member_id_t id, size_t wstring_length); - - RCLCPP_PUBLIC - const std::u16string - get_fixed_wstring_value(const std::string & name, size_t wstring_length); - - RCLCPP_PUBLIC - void - set_fixed_string_value( - rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_length); - - RCLCPP_PUBLIC - void - set_fixed_string_value(const std::string & name, const std::string value, size_t string_length); - - RCLCPP_PUBLIC - void - set_fixed_wstring_value( - rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_length); - - RCLCPP_PUBLIC - void - set_fixed_wstring_value( - const std::string & name, const std::u16string value, size_t wstring_length); - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - insert_fixed_string_value(const std::string value, size_t string_length); - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - insert_fixed_wstring_value(const std::u16string value, size_t wstring_length); - - - // BOUNDED STRING MEMBER ACCESS ================================================================== - RCLCPP_PUBLIC - const std::string - get_bounded_string_value(rosidl_dynamic_typesupport_member_id_t id, size_t string_bound); - - RCLCPP_PUBLIC - const std::string - get_bounded_string_value(const std::string & name, size_t string_bound); - - RCLCPP_PUBLIC - const std::u16string - get_bounded_wstring_value(rosidl_dynamic_typesupport_member_id_t id, size_t wstring_bound); - - RCLCPP_PUBLIC - const std::u16string - get_bounded_wstring_value(const std::string & name, size_t wstring_bound); - - RCLCPP_PUBLIC - void - set_bounded_string_value( - rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_bound); - - RCLCPP_PUBLIC - void - set_bounded_string_value(const std::string & name, const std::string value, size_t string_bound); - - RCLCPP_PUBLIC - void - set_bounded_wstring_value( - rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_bound); - - RCLCPP_PUBLIC - void - set_bounded_wstring_value( - const std::string & name, const std::u16string value, size_t wstring_bound); - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - insert_bounded_string_value(const std::string value, size_t string_bound); - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - insert_bounded_wstring_value(const std::u16string value, size_t wstring_bound); - - - // NESTED MEMBER ACCESS ========================================================================== - RCLCPP_PUBLIC - DynamicData - get_complex_value(rosidl_dynamic_typesupport_member_id_t id); - - RCLCPP_PUBLIC - DynamicData - get_complex_value(const std::string & name); - - RCLCPP_PUBLIC - DynamicData::SharedPtr - get_complex_value_shared(rosidl_dynamic_typesupport_member_id_t id); - - RCLCPP_PUBLIC - DynamicData::SharedPtr - get_complex_value_shared(const std::string & name); - - RCLCPP_PUBLIC - void - set_complex_value(rosidl_dynamic_typesupport_member_id_t id, DynamicData & value); - - RCLCPP_PUBLIC - void - set_complex_value(const std::string & name, DynamicData & value); - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - insert_complex_value_copy(const DynamicData & value); - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_member_id_t - insert_complex_value(DynamicData & value); - -protected: - // NOTE(methylDragon): - // This is just here to extend the lifetime of the serialization support - // It isn't actually used by the builder since the builder should compose its own support - // - // ... Though ideally it should be the exact same support as the one stored in the - // DynamicSerializationSupport - DynamicSerializationSupport::SharedPtr serialization_support_; - - std::shared_ptr rosidl_dynamic_data_; - - bool is_loaned_; - DynamicData::SharedPtr parent_data_; // Used for returning the loaned value, and lifetime management - -private: - RCLCPP_PUBLIC - DynamicData(); - - RCLCPP_PUBLIC - bool - match_serialization_support_( - const DynamicSerializationSupport & serialization_support, - const rosidl_dynamic_typesupport_dynamic_data_t & dynamic_data); -}; - - -} // namespace dynamic_typesupport -} // namespace rclcpp - -#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index abdc56a926..80e7cb4b39 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -19,13 +19,12 @@ #include #include -#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" +#include #include @@ -35,13 +34,398 @@ namespace dynamic_typesupport { -// NOTE(methylDragon): We just alias the type in this case... -// I'd have made a wrapper class but then I'd need to redirect every single -// method (or dynamic cast everywhere else) -// -/// This type maps to the underlying rosidl_dynamic_typesupport_dynamic_data_t, rather than the equivalent -/// rosidl_dynamic_typesupport_dynamic_data_t struct. -using DynamicMessage = DynamicData; +class DynamicMessageType; +class DynamicMessageTypeBuilder; + +/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_data_t * +/** + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Exposes the underlying serialization support API + * + * Ownership: + * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed + * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. + * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer + * must point to the same location in memory as the stored raw pointer! + * + * Note: This class is meant to map to the lower level rosidl_dynamic_typesupport_dynamic_data_t, + * even though rosidl_dynamic_typesupport_dynamic_data_t is equivalent to + * rosidl_dynamic_typesupport_dynamic_data_t, exposing the fundamental methods available to + * rosidl_dynamic_typesupport_dynamic_data_t, allowing the user to access the data's fields. + */ +class DynamicMessage : public std::enable_shared_from_this +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessage) + + // CONSTRUCTION ================================================================================== + // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the + // lifetime of the serialization support (if the constructor cannot otherwise get it from args). + // + // In cases where a dynamic data pointer is passed, the serialization support composed by + // the data should be the exact same object managed by the DynamicSerializationSupport, + // otherwise the lifetime management will not work properly. + + /// Construct a new DynamicMessage with the provided dynamic type builder + RCLCPP_PUBLIC + explicit DynamicMessage(std::shared_ptr dynamic_type_builder); + + /// Construct a new DynamicMessage with the provided dynamic type + RCLCPP_PUBLIC + explicit DynamicMessage(std::shared_ptr dynamic_type); + + /// Assume ownership of raw pointer + RCLCPP_PUBLIC + DynamicMessage( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data); + + /// Copy shared pointer + RCLCPP_PUBLIC + DynamicMessage( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_data); + + /// Loaning constructor + /// Must only be called with raw ptr obtained from loaning! + // NOTE(methylDragon): I'd put this in protected, but I need this exposed to + // enable_shared_from_this... + RCLCPP_PUBLIC + DynamicMessage( + DynamicMessage::SharedPtr parent_data, + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data); + + // NOTE(methylDragon): Deliberately no constructor from description to nudge users towards using + // construction from dynamic type/builder, which is more efficient + + /// Copy constructor + RCLCPP_PUBLIC + DynamicMessage(const DynamicMessage & other); + + /// Move constructor + RCLCPP_PUBLIC + DynamicMessage(DynamicMessage && other) noexcept; + + /// Copy assignment + RCLCPP_PUBLIC + DynamicMessage & operator=(const DynamicMessage & other); + + /// Move assignment + RCLCPP_PUBLIC + DynamicMessage & operator=(DynamicMessage && other) noexcept; + + RCLCPP_PUBLIC + virtual ~DynamicMessage(); + + + // GETTERS ======================================================================================= + RCLCPP_PUBLIC + const std::string + get_library_identifier() const; + + RCLCPP_PUBLIC + const std::string + get_name() const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_dynamic_data_t * + get_rosidl_dynamic_data(); + + RCLCPP_PUBLIC + const rosidl_dynamic_typesupport_dynamic_data_t * + get_rosidl_dynamic_data() const; + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_data(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_data() const; + + RCLCPP_PUBLIC + DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support(); + + RCLCPP_PUBLIC + DynamicSerializationSupport::ConstSharedPtr + get_shared_dynamic_serialization_support() const; + + RCLCPP_PUBLIC + size_t + get_item_count() const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + get_member_id(size_t index) const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + get_member_id(const std::string & name) const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + get_array_index(size_t index) const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + get_array_index(const std::string & name) const; + + + // METHODS ======================================================================================= + RCLCPP_PUBLIC + DynamicMessage + clone() const; + + RCLCPP_PUBLIC + DynamicMessage::SharedPtr + clone_shared() const; + + RCLCPP_PUBLIC + DynamicMessage + init_from_type(DynamicMessageType & type) const; + + RCLCPP_PUBLIC + DynamicMessage::SharedPtr + init_from_type_shared(DynamicMessageType & type) const; + + RCLCPP_PUBLIC + bool + equals(const DynamicMessage & other) const; + + RCLCPP_PUBLIC + DynamicMessage::SharedPtr + loan_value(rosidl_dynamic_typesupport_member_id_t id); + + RCLCPP_PUBLIC + DynamicMessage::SharedPtr + loan_value(const std::string & name); + + RCLCPP_PUBLIC + void + clear_all_values(); + + RCLCPP_PUBLIC + void + clear_nonkey_values(); + + RCLCPP_PUBLIC + void + clear_value(rosidl_dynamic_typesupport_member_id_t id); + + RCLCPP_PUBLIC + void + clear_value(const std::string & name); + + RCLCPP_PUBLIC + void + clear_sequence(); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_sequence_data(); + + RCLCPP_PUBLIC + void + remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index); + + RCLCPP_PUBLIC + void + print() const; + + RCLCPP_PUBLIC + bool + serialize(rcl_serialized_message_t * buffer); + + RCLCPP_PUBLIC + bool + deserialize(rcl_serialized_message_t * buffer); + + + // MEMBER ACCESS TEMPLATES ======================================================================= + /** + * Since we're in a ROS layer, these should support all ROS interface C++ types as found in: + * https://docs.ros.org/en/rolling/Concepts/About-ROS-Interfaces.html + * + * Explicitly: + * - Basic types: bool, byte, char + * - Float types: float, double + * - Int types: int8_t, int16_t, int32_t, int64_t + * - Unsigned int types: uint8_t, uint16_t, uint32_t, uint64_t + * - String types: std::string, std::u16string + */ + + template + ValueT + get_value(rosidl_dynamic_typesupport_member_id_t id); + + template + ValueT + get_value(const std::string & name); + + template + void + set_value(rosidl_dynamic_typesupport_member_id_t id, ValueT value); + + template + void + set_value(const std::string & name, ValueT value); + + template + rosidl_dynamic_typesupport_member_id_t + insert_value(ValueT value); + + + // FIXED STRING MEMBER ACCESS ==================================================================== + RCLCPP_PUBLIC + const std::string + get_fixed_string_value(rosidl_dynamic_typesupport_member_id_t id, size_t string_length); + + RCLCPP_PUBLIC + const std::string + get_fixed_string_value(const std::string & name, size_t string_length); + + RCLCPP_PUBLIC + const std::u16string + get_fixed_wstring_value(rosidl_dynamic_typesupport_member_id_t id, size_t wstring_length); + + RCLCPP_PUBLIC + const std::u16string + get_fixed_wstring_value(const std::string & name, size_t wstring_length); + + RCLCPP_PUBLIC + void + set_fixed_string_value( + rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_length); + + RCLCPP_PUBLIC + void + set_fixed_string_value(const std::string & name, const std::string value, size_t string_length); + + RCLCPP_PUBLIC + void + set_fixed_wstring_value( + rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_length); + + RCLCPP_PUBLIC + void + set_fixed_wstring_value( + const std::string & name, const std::u16string value, size_t wstring_length); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_fixed_string_value(const std::string value, size_t string_length); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_fixed_wstring_value(const std::u16string value, size_t wstring_length); + + + // BOUNDED STRING MEMBER ACCESS ================================================================== + RCLCPP_PUBLIC + const std::string + get_bounded_string_value(rosidl_dynamic_typesupport_member_id_t id, size_t string_bound); + + RCLCPP_PUBLIC + const std::string + get_bounded_string_value(const std::string & name, size_t string_bound); + + RCLCPP_PUBLIC + const std::u16string + get_bounded_wstring_value(rosidl_dynamic_typesupport_member_id_t id, size_t wstring_bound); + + RCLCPP_PUBLIC + const std::u16string + get_bounded_wstring_value(const std::string & name, size_t wstring_bound); + + RCLCPP_PUBLIC + void + set_bounded_string_value( + rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_bound); + + RCLCPP_PUBLIC + void + set_bounded_string_value(const std::string & name, const std::string value, size_t string_bound); + + RCLCPP_PUBLIC + void + set_bounded_wstring_value( + rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_bound); + + RCLCPP_PUBLIC + void + set_bounded_wstring_value( + const std::string & name, const std::u16string value, size_t wstring_bound); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_bounded_string_value(const std::string value, size_t string_bound); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_bounded_wstring_value(const std::u16string value, size_t wstring_bound); + + + // NESTED MEMBER ACCESS ========================================================================== + RCLCPP_PUBLIC + DynamicMessage + get_complex_value(rosidl_dynamic_typesupport_member_id_t id); + + RCLCPP_PUBLIC + DynamicMessage + get_complex_value(const std::string & name); + + RCLCPP_PUBLIC + DynamicMessage::SharedPtr + get_complex_value_shared(rosidl_dynamic_typesupport_member_id_t id); + + RCLCPP_PUBLIC + DynamicMessage::SharedPtr + get_complex_value_shared(const std::string & name); + + RCLCPP_PUBLIC + void + set_complex_value(rosidl_dynamic_typesupport_member_id_t id, DynamicMessage & value); + + RCLCPP_PUBLIC + void + set_complex_value(const std::string & name, DynamicMessage & value); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_complex_value_copy(const DynamicMessage & value); + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_member_id_t + insert_complex_value(DynamicMessage & value); + +protected: + // NOTE(methylDragon): + // This is just here to extend the lifetime of the serialization support + // It isn't actually used by the builder since the builder should compose its own support + // + // ... Though ideally it should be the exact same support as the one stored in the + // DynamicSerializationSupport + DynamicSerializationSupport::SharedPtr serialization_support_; + + std::shared_ptr rosidl_dynamic_data_; + + bool is_loaned_; + DynamicMessage::SharedPtr parent_data_; // Used for returning the loaned value, and lifetime management + +private: + RCLCPP_PUBLIC + DynamicMessage(); + + RCLCPP_PUBLIC + bool + match_serialization_support_( + const DynamicSerializationSupport & serialization_support, + const rosidl_dynamic_typesupport_dynamic_data_t & dynamic_data); +}; + } // namespace dynamic_typesupport } // namespace rclcpp diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index 60e31ec63f..5a6f7d2e93 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -19,8 +19,6 @@ #include #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" @@ -33,13 +31,173 @@ namespace dynamic_typesupport { -// NOTE(methylDragon): We just alias the type in this case... -// I'd have made a wrapper class but then I'd need to redirect every single -// method (or dynamic cast everywhere else) -// -/// This type maps to the underlying rosidl_dynamic_typesupport_dynamic_type_t, rather than the equivalent -/// rosidl_dynamic_typesupport_dynamic_type_t struct. -using DynamicMessageType = DynamicType; +class DynamicMessage; +class DynamicMessageTypeBuilder; + +/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_type_t * +/** + * This class: + * - Manages the lifetime of the raw pointer. + * - Exposes getter methods to get the raw pointer and shared pointers + * - Exposes the underlying serialization support API + * + * Ownership: + * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed + * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. + * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer + * must point to the same location in memory as the stored raw pointer! + * + * Note: This class is meant to map to the lower level rosidl_dynamic_typesupport_dynamic_type_t, + * which can be constructed via DynamicMessageTypeBuilder, which maps to + * rosidl_dynamic_typesupport_dynamic_type_builder_t. + * + * The usual method of obtaining a DynamicMessageType is through construction of + * rosidl_message_type_support_t via rcl_dynamic_message_typesupport_handle_init(), then + * taking ownership of its contents. But DynamicMessageTypeBuilder can also be used to obtain + * DynamicMessageType by constructing it bottom-up instead, since it exposes the lower_level + * rosidl methods. + */ +class DynamicMessageType : public std::enable_shared_from_this +{ +public: + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageType) + + // CONSTRUCTION ================================================================================== + // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the + // lifetime of the serialization support (if the constructor cannot otherwise get it from args). + // + // In cases where a dynamic type pointer is passed, the serialization support composed by + // the type should be the exact same object managed by the DynamicSerializationSupport, + // otherwise the lifetime management will not work properly. + + /// Construct a new DynamicMessageType with the provided dynamic type builder + RCLCPP_PUBLIC + explicit DynamicMessageType(std::shared_ptr dynamic_type_builder); + + /// Assume ownership of raw pointer + RCLCPP_PUBLIC + DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type); + + /// Copy shared pointer + RCLCPP_PUBLIC + DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + std::shared_ptr rosidl_dynamic_type); + + /// From description + RCLCPP_PUBLIC + DynamicMessageType( + DynamicSerializationSupport::SharedPtr serialization_support, + const rosidl_runtime_c__type_description__TypeDescription & description); + + /// Copy constructor + RCLCPP_PUBLIC + DynamicMessageType(const DynamicMessageType & other); + + /// Move constructor + RCLCPP_PUBLIC + DynamicMessageType(DynamicMessageType && other) noexcept; + + /// Copy assignment + RCLCPP_PUBLIC + DynamicMessageType & operator=(const DynamicMessageType & other); + + /// Move assignment + RCLCPP_PUBLIC + DynamicMessageType & operator=(DynamicMessageType && other) noexcept; + + RCLCPP_PUBLIC + virtual ~DynamicMessageType(); + + /// Swaps the serialization support if serialization_support is populated + RCLCPP_PUBLIC + void + init_from_description( + const rosidl_runtime_c__type_description__TypeDescription & description, + DynamicSerializationSupport::SharedPtr serialization_support = nullptr); + + // GETTERS ======================================================================================= + RCLCPP_PUBLIC + const std::string + get_library_identifier() const; + + RCLCPP_PUBLIC + const std::string + get_name() const; + + RCLCPP_PUBLIC + size_t + get_member_count() const; + + RCLCPP_PUBLIC + rosidl_dynamic_typesupport_dynamic_type_t * + get_rosidl_dynamic_type(); + + RCLCPP_PUBLIC + const rosidl_dynamic_typesupport_dynamic_type_t * + get_rosidl_dynamic_type() const; + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_type(); + + RCLCPP_PUBLIC + std::shared_ptr + get_shared_rosidl_dynamic_type() const; + + RCLCPP_PUBLIC + DynamicSerializationSupport::SharedPtr + get_shared_dynamic_serialization_support(); + + RCLCPP_PUBLIC + DynamicSerializationSupport::ConstSharedPtr + get_shared_dynamic_serialization_support() const; + + + // METHODS ======================================================================================= + RCLCPP_PUBLIC + DynamicMessageType + clone() const; + + RCLCPP_PUBLIC + DynamicMessageType::SharedPtr + clone_shared() const; + + RCLCPP_PUBLIC + bool + equals(const DynamicMessageType & other) const; + + RCLCPP_PUBLIC + DynamicMessage + build_dynamic_message(); + + RCLCPP_PUBLIC + std::shared_ptr + build_dynamic_message_shared(); + +protected: + // NOTE(methylDragon): + // This is just here to extend the lifetime of the serialization support + // It isn't actually used by the builder since the builder should compose its own support + // + // ... Though ideally it should be the exact same support as the one stored in the + // DynamicSerializationSupport + DynamicSerializationSupport::SharedPtr serialization_support_; + + std::shared_ptr rosidl_dynamic_type_; + +private: + RCLCPP_PUBLIC + DynamicMessageType(); + + RCLCPP_PUBLIC + bool + match_serialization_support_( + const DynamicSerializationSupport & serialization_support, + const rosidl_dynamic_typesupport_dynamic_type_t & rosidl_dynamic_type); +}; } // namespace dynamic_typesupport diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp similarity index 83% rename from rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp rename to rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp index 6fc8988a7d..74f456ac04 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_ -#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_ +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_ +#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_ #include #include @@ -30,8 +30,8 @@ namespace rclcpp namespace dynamic_typesupport { -class DynamicData; -class DynamicType; +class DynamicMessage; +class DynamicMessageType; /// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_type_builder_t * /** @@ -49,15 +49,16 @@ class DynamicType; * Note: This class is meant to map to rosidl_dynamic_typesupport_dynamic_type_builder_t, * facilitating the construction of dynamic types bottom-up in the C++ layer. * - * The usual method of obtaining a DynamicType is through construction of + * The usual method of obtaining a DynamicMessageType is through construction of * rosidl_message_type_support_t via rcl_dynamic_message_typesupport_handle_init(), then taking - * ownership of its contents. But DynamicTypeBuilder can also be used to obtain DynamicType by - * constructing it bottom-up instead, since it exposes the lower_level rosidl methods. + * ownership of its contents. But DynamicMessageTypeBuilder can also be used to obtain + * DynamicMessageType by constructing it bottom-up instead, since it exposes the lower_level + * rosidl methods. */ -class DynamicTypeBuilder : public std::enable_shared_from_this +class DynamicMessageTypeBuilder : public std::enable_shared_from_this { public: - RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicTypeBuilder) + RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageTypeBuilder) // CONSTRUCTION ================================================================================== // All constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the @@ -67,48 +68,48 @@ class DynamicTypeBuilder : public std::enable_shared_from_this dynamic_type_builder); /// Copy constructor RCLCPP_PUBLIC - DynamicTypeBuilder(const DynamicTypeBuilder & other); + DynamicMessageTypeBuilder(const DynamicMessageTypeBuilder & other); /// Move constructor RCLCPP_PUBLIC - DynamicTypeBuilder(DynamicTypeBuilder && other) noexcept; + DynamicMessageTypeBuilder(DynamicMessageTypeBuilder && other) noexcept; /// Copy assignment RCLCPP_PUBLIC - DynamicTypeBuilder & operator=(const DynamicTypeBuilder & other); + DynamicMessageTypeBuilder & operator=(const DynamicMessageTypeBuilder & other); /// Move assignment RCLCPP_PUBLIC - DynamicTypeBuilder & operator=(DynamicTypeBuilder && other) noexcept; + DynamicMessageTypeBuilder & operator=(DynamicMessageTypeBuilder && other) noexcept; /// From description RCLCPP_PUBLIC - DynamicTypeBuilder( + DynamicMessageTypeBuilder( DynamicSerializationSupport::SharedPtr serialization_support, const rosidl_runtime_c__type_description__TypeDescription & description); RCLCPP_PUBLIC - virtual ~DynamicTypeBuilder(); + virtual ~DynamicMessageTypeBuilder(); /// Swaps the serialization support if serialization_support is populated RCLCPP_PUBLIC @@ -158,11 +159,11 @@ class DynamicTypeBuilder : public std::enable_shared_from_this - build_data_shared(); + DynamicMessage::SharedPtr + build_dynamic_message_shared(); RCLCPP_PUBLIC - DynamicType - build_type(); + DynamicMessageType + build_dynamic_message_type(); RCLCPP_PUBLIC - std::shared_ptr - build_type_shared(); + DynamicMessageType::SharedPtr + build_dynamic_message_type_shared(); // ADD MEMBERS TEMPLATES ========================================================================= @@ -329,50 +330,50 @@ class DynamicTypeBuilder : public std::enable_shared_from_this #include -#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/macros.hpp" @@ -193,7 +193,7 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this -#include - -#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/macros.hpp" -#include "rclcpp/visibility_control.hpp" - -#include - - -namespace rclcpp -{ -namespace dynamic_typesupport -{ - - -class DynamicData; -class DynamicTypeBuilder; - -/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_type_t * -/** - * This class: - * - Manages the lifetime of the raw pointer. - * - Exposes getter methods to get the raw pointer and shared pointers - * - Exposes the underlying serialization support API - * - * Ownership: - * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed - * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. - * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer - * must point to the same location in memory as the stored raw pointer! - * - * Note: This class is meant to map to the lower level rosidl_dynamic_typesupport_dynamic_type_t, - * which can be constructed via DynamicTypeBuilder, which maps to - * rosidl_dynamic_typesupport_dynamic_type_builder_t. - * - * The usual method of obtaining a DynamicType is through construction of - * rosidl_message_type_support_t via rcl_dynamic_message_typesupport_handle_init(), then taking - * ownership of its contents. But DynamicTypeBuilder can also be used to obtain DynamicType by - * constructing it bottom-up instead, since it exposes the lower_level rosidl methods. - */ -class DynamicType : public std::enable_shared_from_this -{ -public: - RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicType) - - // CONSTRUCTION ================================================================================== - // Most constructors require a passed in DynamicSerializationSupport::SharedPtr, to extend the - // lifetime of the serialization support (if the constructor cannot otherwise get it from args). - // - // In cases where a dynamic type pointer is passed, the serialization support composed by - // the type should be the exact same object managed by the DynamicSerializationSupport, - // otherwise the lifetime management will not work properly. - - /// Construct a new DynamicType with the provided dynamic type builder - RCLCPP_PUBLIC - explicit DynamicType(std::shared_ptr dynamic_type_builder); - - /// Assume ownership of raw pointer - RCLCPP_PUBLIC - DynamicType( - DynamicSerializationSupport::SharedPtr serialization_support, - rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type); - - /// Copy shared pointer - RCLCPP_PUBLIC - DynamicType( - DynamicSerializationSupport::SharedPtr serialization_support, - std::shared_ptr rosidl_dynamic_type); - - /// From description - RCLCPP_PUBLIC - DynamicType( - DynamicSerializationSupport::SharedPtr serialization_support, - const rosidl_runtime_c__type_description__TypeDescription & description); - - /// Copy constructor - RCLCPP_PUBLIC - DynamicType(const DynamicType & other); - - /// Move constructor - RCLCPP_PUBLIC - DynamicType(DynamicType && other) noexcept; - - /// Copy assignment - RCLCPP_PUBLIC - DynamicType & operator=(const DynamicType & other); - - /// Move assignment - RCLCPP_PUBLIC - DynamicType & operator=(DynamicType && other) noexcept; - - RCLCPP_PUBLIC - virtual ~DynamicType(); - - /// Swaps the serialization support if serialization_support is populated - RCLCPP_PUBLIC - void - init_from_description( - const rosidl_runtime_c__type_description__TypeDescription & description, - DynamicSerializationSupport::SharedPtr serialization_support = nullptr); - - // GETTERS ======================================================================================= - RCLCPP_PUBLIC - const std::string - get_library_identifier() const; - - RCLCPP_PUBLIC - const std::string - get_name() const; - - RCLCPP_PUBLIC - size_t - get_member_count() const; - - RCLCPP_PUBLIC - rosidl_dynamic_typesupport_dynamic_type_t * - get_rosidl_dynamic_type(); - - RCLCPP_PUBLIC - const rosidl_dynamic_typesupport_dynamic_type_t * - get_rosidl_dynamic_type() const; - - RCLCPP_PUBLIC - std::shared_ptr - get_shared_rosidl_dynamic_type(); - - RCLCPP_PUBLIC - std::shared_ptr - get_shared_rosidl_dynamic_type() const; - - RCLCPP_PUBLIC - DynamicSerializationSupport::SharedPtr - get_shared_dynamic_serialization_support(); - - RCLCPP_PUBLIC - DynamicSerializationSupport::ConstSharedPtr - get_shared_dynamic_serialization_support() const; - - - // METHODS ======================================================================================= - RCLCPP_PUBLIC - DynamicType - clone() const; - - RCLCPP_PUBLIC - DynamicType::SharedPtr - clone_shared() const; - - RCLCPP_PUBLIC - bool - equals(const DynamicType & other) const; - - RCLCPP_PUBLIC - DynamicData - build_data(); - - RCLCPP_PUBLIC - std::shared_ptr - build_data_shared(); - -protected: - // NOTE(methylDragon): - // This is just here to extend the lifetime of the serialization support - // It isn't actually used by the builder since the builder should compose its own support - // - // ... Though ideally it should be the exact same support as the one stored in the - // DynamicSerializationSupport - DynamicSerializationSupport::SharedPtr serialization_support_; - - std::shared_ptr rosidl_dynamic_type_; - -private: - RCLCPP_PUBLIC - DynamicType(); - - RCLCPP_PUBLIC - bool - match_serialization_support_( - const DynamicSerializationSupport & serialization_support, - const rosidl_dynamic_typesupport_dynamic_type_t & rosidl_dynamic_type); -}; - - -} // namespace dynamic_typesupport -} // namespace rclcpp - -#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_HPP_ diff --git a/rclcpp/include/rclcpp/rclcpp.hpp b/rclcpp/include/rclcpp/rclcpp.hpp index 0acbfb82b2..7cd7e21a8a 100644 --- a/rclcpp/include/rclcpp/rclcpp.hpp +++ b/rclcpp/include/rclcpp/rclcpp.hpp @@ -118,18 +118,14 @@ * - rclcpp/allocator/allocator_common.hpp * - rclcpp/allocator/allocator_deleter.hpp * - Dynamic typesupport wrappers - * - rclcpp::dynamic_typesupport::DynamicData * - rclcpp::dynamic_typesupport::DynamicMessage * - rclcpp::dynamic_typesupport::DynamicMessageType + * - rclcpp::dynamic_typesupport::DynamicMessageTypeBuilder * - rclcpp::dynamic_typesupport::DynamicSerializationSupport - * - rclcpp::dynamic_typesupport::DynamicTypeBuilder - * - rclcpp::dynamic_typesupport::DynamicType - * - rclcpp/dynamic_typesupport/dynamic_data.hpp * - rclcpp/dynamic_typesupport/dynamic_message.hpp * - rclcpp/dynamic_typesupport/dynamic_message_type.hpp + * - rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp * - rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp - * - rclcpp/dynamic_typesupport/dynamic_type_builder.hpp - * - rclcpp/dynamic_typesupport/dynamic_type.hpp * - Dynamic typesupport * - rclcpp::dynamic_typesupport::DynamicMessageTypeSupport * - rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp similarity index 77% rename from rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp rename to rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp index ce74469c8e..8775c928ea 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_data.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp @@ -15,11 +15,10 @@ #include #include -#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" #include "rclcpp/exceptions.hpp" #include "rcl/types.h" #include "rcutils/logging_macros.h" @@ -28,19 +27,19 @@ #include #include -using rclcpp::dynamic_typesupport::DynamicData; +using rclcpp::dynamic_typesupport::DynamicMessage; +using rclcpp::dynamic_typesupport::DynamicMessageType; +using rclcpp::dynamic_typesupport::DynamicMessageTypeBuilder; using rclcpp::dynamic_typesupport::DynamicSerializationSupport; -using rclcpp::dynamic_typesupport::DynamicType; -using rclcpp::dynamic_typesupport::DynamicTypeBuilder; -#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_ +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_ // Template specialization implementations -#include "rclcpp/dynamic_typesupport/detail/dynamic_data_impl.hpp" +#include "rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp" #endif // CONSTRUCTION ================================================================================== -DynamicData::DynamicData(const DynamicTypeBuilder::SharedPtr dynamic_type_builder) +DynamicMessage::DynamicMessage(const DynamicMessageTypeBuilder::SharedPtr dynamic_type_builder) : serialization_support_(dynamic_type_builder->get_shared_dynamic_serialization_support()), rosidl_dynamic_data_(nullptr), is_loaned_(false), @@ -73,7 +72,7 @@ DynamicData::DynamicData(const DynamicTypeBuilder::SharedPtr dynamic_type_builde } -DynamicData::DynamicData(const DynamicType::SharedPtr dynamic_type) +DynamicMessage::DynamicMessage(const DynamicMessageType::SharedPtr dynamic_type) : serialization_support_(dynamic_type->get_shared_dynamic_serialization_support()), rosidl_dynamic_data_(nullptr), is_loaned_(false), @@ -106,7 +105,7 @@ DynamicData::DynamicData(const DynamicType::SharedPtr dynamic_type) } -DynamicData::DynamicData( +DynamicMessage::DynamicMessage( DynamicSerializationSupport::SharedPtr serialization_support, rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data) : serialization_support_(serialization_support), @@ -134,7 +133,7 @@ DynamicData::DynamicData( } -DynamicData::DynamicData( +DynamicMessage::DynamicMessage( DynamicSerializationSupport::SharedPtr serialization_support, std::shared_ptr rosidl_dynamic_data) : serialization_support_(serialization_support), @@ -154,8 +153,8 @@ DynamicData::DynamicData( } -DynamicData::DynamicData( - DynamicData::SharedPtr parent_data, +DynamicMessage::DynamicMessage( + DynamicMessage::SharedPtr parent_data, rosidl_dynamic_typesupport_dynamic_data_t * rosidl_loaned_data) : serialization_support_(parent_data->get_shared_dynamic_serialization_support()), rosidl_dynamic_data_(nullptr), @@ -187,21 +186,21 @@ DynamicData::DynamicData( } -DynamicData::DynamicData(const DynamicData & other) +DynamicMessage::DynamicMessage(const DynamicMessage & other) : enable_shared_from_this(), serialization_support_(nullptr), rosidl_dynamic_data_(nullptr), is_loaned_(false), parent_data_(nullptr) { - DynamicData out = other.clone(); + DynamicMessage out = other.clone(); // We don't copy is_loaned_ or parent_data_ because it's a fresh copy now std::swap(serialization_support_, out.serialization_support_); std::swap(rosidl_dynamic_data_, out.rosidl_dynamic_data_); } -DynamicData::DynamicData(DynamicData && other) noexcept +DynamicMessage::DynamicMessage(DynamicMessage && other) noexcept : serialization_support_(std::exchange(other.serialization_support_, nullptr)), rosidl_dynamic_data_(std::exchange(other.rosidl_dynamic_data_, nullptr)), is_loaned_(other.is_loaned_), @@ -209,15 +208,15 @@ DynamicData::DynamicData(DynamicData && other) noexcept {} -DynamicData & -DynamicData::operator=(const DynamicData & other) +DynamicMessage & +DynamicMessage::operator=(const DynamicMessage & other) { - return *this = DynamicData(other); + return *this = DynamicMessage(other); } -DynamicData & -DynamicData::operator=(DynamicData && other) noexcept +DynamicMessage & +DynamicMessage::operator=(DynamicMessage && other) noexcept { std::swap(serialization_support_, other.serialization_support_); std::swap(rosidl_dynamic_data_, other.rosidl_dynamic_data_); @@ -227,7 +226,7 @@ DynamicData::operator=(DynamicData && other) noexcept } -DynamicData::~DynamicData() +DynamicMessage::~DynamicMessage() { if (is_loaned_) { if (!parent_data_) { @@ -241,7 +240,7 @@ DynamicData::~DynamicData() bool -DynamicData::match_serialization_support_( +DynamicMessage::match_serialization_support_( const DynamicSerializationSupport & serialization_support, const rosidl_dynamic_typesupport_dynamic_data_t & rosidl_dynamic_type_data) { @@ -268,14 +267,14 @@ DynamicData::match_serialization_support_( // GETTERS ======================================================================================= const std::string -DynamicData::get_library_identifier() const +DynamicMessage::get_library_identifier() const { return std::string(rosidl_dynamic_data_->serialization_support->library_identifier); } const std::string -DynamicData::get_name() const +DynamicMessage::get_name() const { size_t buf_length; const char * buf = rosidl_dynamic_typesupport_dynamic_data_get_name( @@ -285,21 +284,21 @@ DynamicData::get_name() const rosidl_dynamic_typesupport_dynamic_data_t * -DynamicData::get_rosidl_dynamic_data() +DynamicMessage::get_rosidl_dynamic_data() { return rosidl_dynamic_data_.get(); } const rosidl_dynamic_typesupport_dynamic_data_t * -DynamicData::get_rosidl_dynamic_data() const +DynamicMessage::get_rosidl_dynamic_data() const { return rosidl_dynamic_data_.get(); } std::shared_ptr -DynamicData::get_shared_rosidl_dynamic_data() +DynamicMessage::get_shared_rosidl_dynamic_data() { return std::shared_ptr( shared_from_this(), rosidl_dynamic_data_.get()); @@ -307,7 +306,7 @@ DynamicData::get_shared_rosidl_dynamic_data() std::shared_ptr -DynamicData::get_shared_rosidl_dynamic_data() const +DynamicMessage::get_shared_rosidl_dynamic_data() const { return std::shared_ptr( shared_from_this(), rosidl_dynamic_data_.get()); @@ -315,28 +314,28 @@ DynamicData::get_shared_rosidl_dynamic_data() const DynamicSerializationSupport::SharedPtr -DynamicData::get_shared_dynamic_serialization_support() +DynamicMessage::get_shared_dynamic_serialization_support() { return serialization_support_; } DynamicSerializationSupport::ConstSharedPtr -DynamicData::get_shared_dynamic_serialization_support() const +DynamicMessage::get_shared_dynamic_serialization_support() const { return serialization_support_; } size_t -DynamicData::get_item_count() const +DynamicMessage::get_item_count() const { return rosidl_dynamic_typesupport_dynamic_data_get_item_count(get_rosidl_dynamic_data()); } rosidl_dynamic_typesupport_member_id_t -DynamicData::get_member_id(size_t index) const +DynamicMessage::get_member_id(size_t index) const { return rosidl_dynamic_typesupport_dynamic_data_get_member_id_at_index( get_rosidl_dynamic_data(), index); @@ -344,7 +343,7 @@ DynamicData::get_member_id(size_t index) const rosidl_dynamic_typesupport_member_id_t -DynamicData::get_member_id(const std::string & name) const +DynamicMessage::get_member_id(const std::string & name) const { return rosidl_dynamic_typesupport_dynamic_data_get_member_id_by_name( get_rosidl_dynamic_data(), name.c_str(), name.size()); @@ -352,7 +351,7 @@ DynamicData::get_member_id(const std::string & name) const rosidl_dynamic_typesupport_member_id_t -DynamicData::get_array_index(size_t index) const +DynamicMessage::get_array_index(size_t index) const { return rosidl_dynamic_typesupport_dynamic_data_get_array_index( get_rosidl_dynamic_data(), index); @@ -360,51 +359,51 @@ DynamicData::get_array_index(size_t index) const rosidl_dynamic_typesupport_member_id_t -DynamicData::get_array_index(const std::string & name) const +DynamicMessage::get_array_index(const std::string & name) const { return get_array_index(get_member_id(name)); } // METHODS ======================================================================================= -DynamicData -DynamicData::clone() const +DynamicMessage +DynamicMessage::clone() const { - return DynamicData( + return DynamicMessage( serialization_support_, rosidl_dynamic_typesupport_dynamic_data_clone(get_rosidl_dynamic_data())); } -DynamicData::SharedPtr -DynamicData::clone_shared() const +DynamicMessage::SharedPtr +DynamicMessage::clone_shared() const { - return DynamicData::make_shared( + return DynamicMessage::make_shared( serialization_support_, rosidl_dynamic_typesupport_dynamic_data_clone(get_rosidl_dynamic_data())); } -DynamicData -DynamicData::init_from_type(DynamicMessageType & type) const +DynamicMessage +DynamicMessage::init_from_type(DynamicMessageType & type) const { - return DynamicData( + return DynamicMessage( serialization_support_, rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(type.get_rosidl_dynamic_type())); } -DynamicData::SharedPtr -DynamicData::init_from_type_shared(DynamicMessageType & type) const +DynamicMessage::SharedPtr +DynamicMessage::init_from_type_shared(DynamicMessageType & type) const { - return DynamicData::make_shared( + return DynamicMessage::make_shared( serialization_support_, rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(type.get_rosidl_dynamic_type())); } bool -DynamicData::equals(const DynamicData & other) const +DynamicMessage::equals(const DynamicMessage & other) const { if (get_library_identifier() != other.get_library_identifier()) { throw std::runtime_error("library identifiers don't match"); @@ -414,59 +413,59 @@ DynamicData::equals(const DynamicData & other) const } -DynamicData::SharedPtr -DynamicData::loan_value(rosidl_dynamic_typesupport_member_id_t id) +DynamicMessage::SharedPtr +DynamicMessage::loan_value(rosidl_dynamic_typesupport_member_id_t id) { - return DynamicData::make_shared( + return DynamicMessage::make_shared( shared_from_this(), rosidl_dynamic_typesupport_dynamic_data_loan_value(get_rosidl_dynamic_data(), id)); } -DynamicData::SharedPtr -DynamicData::loan_value(const std::string & name) +DynamicMessage::SharedPtr +DynamicMessage::loan_value(const std::string & name) { return loan_value(get_member_id(name)); } void -DynamicData::clear_all_values() +DynamicMessage::clear_all_values() { rosidl_dynamic_typesupport_dynamic_data_clear_all_values(get_rosidl_dynamic_data()); } void -DynamicData::clear_nonkey_values() +DynamicMessage::clear_nonkey_values() { rosidl_dynamic_typesupport_dynamic_data_clear_nonkey_values(get_rosidl_dynamic_data()); } void -DynamicData::clear_value(rosidl_dynamic_typesupport_member_id_t id) +DynamicMessage::clear_value(rosidl_dynamic_typesupport_member_id_t id) { rosidl_dynamic_typesupport_dynamic_data_clear_value(get_rosidl_dynamic_data(), id); } void -DynamicData::clear_value(const std::string & name) +DynamicMessage::clear_value(const std::string & name) { clear_value(get_member_id(name)); } void -DynamicData::clear_sequence() +DynamicMessage::clear_sequence() { rosidl_dynamic_typesupport_dynamic_data_clear_sequence_data(get_rosidl_dynamic_data()); } rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_sequence_data() +DynamicMessage::insert_sequence_data() { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_sequence_data(get_rosidl_dynamic_data(), &out); @@ -475,7 +474,7 @@ DynamicData::insert_sequence_data() void -DynamicData::remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index) +DynamicMessage::remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index) { rosidl_dynamic_typesupport_dynamic_data_remove_sequence_data( get_rosidl_dynamic_data(), index); @@ -483,33 +482,33 @@ DynamicData::remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index) void -DynamicData::print() const +DynamicMessage::print() const { rosidl_dynamic_typesupport_dynamic_data_print(get_rosidl_dynamic_data()); } bool -DynamicData::serialize(rcl_serialized_message_t * buffer) +DynamicMessage::serialize(rcl_serialized_message_t * buffer) { return rosidl_dynamic_typesupport_dynamic_data_serialize(get_rosidl_dynamic_data(), buffer); } bool -DynamicData::deserialize(rcl_serialized_message_t * buffer) +DynamicMessage::deserialize(rcl_serialized_message_t * buffer) { return rosidl_dynamic_typesupport_dynamic_data_deserialize(get_rosidl_dynamic_data(), buffer); } // MEMBER ACCESS =================================================================================== -// Defined in "detail/dynamic_data_impl.hpp" +// Defined in "detail/dynamic_message_impl.hpp" // FIXED STRING MEMBER ACCESS ====================================================================== const std::string -DynamicData::get_fixed_string_value( +DynamicMessage::get_fixed_string_value( rosidl_dynamic_typesupport_member_id_t id, size_t string_length) { size_t buf_length; @@ -523,14 +522,14 @@ DynamicData::get_fixed_string_value( const std::string -DynamicData::get_fixed_string_value(const std::string & name, size_t string_length) +DynamicMessage::get_fixed_string_value(const std::string & name, size_t string_length) { return get_fixed_string_value(get_member_id(name), string_length); } const std::u16string -DynamicData::get_fixed_wstring_value( +DynamicMessage::get_fixed_wstring_value( rosidl_dynamic_typesupport_member_id_t id, size_t wstring_length) { size_t buf_length; @@ -544,14 +543,14 @@ DynamicData::get_fixed_wstring_value( const std::u16string -DynamicData::get_fixed_wstring_value(const std::string & name, size_t wstring_length) +DynamicMessage::get_fixed_wstring_value(const std::string & name, size_t wstring_length) { return get_fixed_wstring_value(get_member_id(name), wstring_length); } void -DynamicData::set_fixed_string_value( +DynamicMessage::set_fixed_string_value( rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_length) { rosidl_dynamic_typesupport_dynamic_data_set_fixed_string_value( @@ -560,7 +559,7 @@ DynamicData::set_fixed_string_value( void -DynamicData::set_fixed_string_value( +DynamicMessage::set_fixed_string_value( const std::string & name, const std::string value, size_t string_length) { set_fixed_string_value(get_member_id(name), value, string_length); @@ -568,7 +567,7 @@ DynamicData::set_fixed_string_value( void -DynamicData::set_fixed_wstring_value( +DynamicMessage::set_fixed_wstring_value( rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_length) { rosidl_dynamic_typesupport_dynamic_data_set_fixed_wstring_value( @@ -577,7 +576,7 @@ DynamicData::set_fixed_wstring_value( void -DynamicData::set_fixed_wstring_value( +DynamicMessage::set_fixed_wstring_value( const std::string & name, const std::u16string value, size_t wstring_length) { set_fixed_wstring_value(get_member_id(name), value, wstring_length); @@ -585,7 +584,7 @@ DynamicData::set_fixed_wstring_value( rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_fixed_string_value(const std::string value, size_t string_length) +DynamicMessage::insert_fixed_string_value(const std::string value, size_t string_length) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_fixed_string_value( @@ -595,7 +594,7 @@ DynamicData::insert_fixed_string_value(const std::string value, size_t string_le rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_fixed_wstring_value(const std::u16string value, size_t wstring_length) +DynamicMessage::insert_fixed_wstring_value(const std::u16string value, size_t wstring_length) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_fixed_wstring_value( @@ -606,7 +605,7 @@ DynamicData::insert_fixed_wstring_value(const std::u16string value, size_t wstri // BOUNDED STRING MEMBER ACCESS ==================================================================== const std::string -DynamicData::get_bounded_string_value( +DynamicMessage::get_bounded_string_value( rosidl_dynamic_typesupport_member_id_t id, size_t string_bound) { size_t buf_length; @@ -620,14 +619,14 @@ DynamicData::get_bounded_string_value( const std::string -DynamicData::get_bounded_string_value(const std::string & name, size_t string_bound) +DynamicMessage::get_bounded_string_value(const std::string & name, size_t string_bound) { return get_bounded_string_value(get_member_id(name), string_bound); } const std::u16string -DynamicData::get_bounded_wstring_value( +DynamicMessage::get_bounded_wstring_value( rosidl_dynamic_typesupport_member_id_t id, size_t wstring_bound) { size_t buf_length; @@ -641,14 +640,14 @@ DynamicData::get_bounded_wstring_value( const std::u16string -DynamicData::get_bounded_wstring_value(const std::string & name, size_t wstring_bound) +DynamicMessage::get_bounded_wstring_value(const std::string & name, size_t wstring_bound) { return get_bounded_wstring_value(get_member_id(name), wstring_bound); } void -DynamicData::set_bounded_string_value( +DynamicMessage::set_bounded_string_value( rosidl_dynamic_typesupport_member_id_t id, const std::string value, size_t string_bound) { rosidl_dynamic_typesupport_dynamic_data_set_bounded_string_value( @@ -657,7 +656,7 @@ DynamicData::set_bounded_string_value( void -DynamicData::set_bounded_string_value( +DynamicMessage::set_bounded_string_value( const std::string & name, const std::string value, size_t string_bound) { set_bounded_string_value(get_member_id(name), value, string_bound); @@ -665,7 +664,7 @@ DynamicData::set_bounded_string_value( void -DynamicData::set_bounded_wstring_value( +DynamicMessage::set_bounded_wstring_value( rosidl_dynamic_typesupport_member_id_t id, const std::u16string value, size_t wstring_bound) { rosidl_dynamic_typesupport_dynamic_data_set_bounded_wstring_value( @@ -674,7 +673,7 @@ DynamicData::set_bounded_wstring_value( void -DynamicData::set_bounded_wstring_value( +DynamicMessage::set_bounded_wstring_value( const std::string & name, const std::u16string value, size_t wstring_bound) { set_bounded_wstring_value(get_member_id(name), value, wstring_bound); @@ -682,7 +681,7 @@ DynamicData::set_bounded_wstring_value( rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_bounded_string_value(const std::string value, size_t string_bound) +DynamicMessage::insert_bounded_string_value(const std::string value, size_t string_bound) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_bounded_string_value( @@ -692,7 +691,7 @@ DynamicData::insert_bounded_string_value(const std::string value, size_t string_ rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_bounded_wstring_value(const std::u16string value, size_t wstring_bound) +DynamicMessage::insert_bounded_wstring_value(const std::u16string value, size_t wstring_bound) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_bounded_wstring_value( @@ -702,43 +701,43 @@ DynamicData::insert_bounded_wstring_value(const std::u16string value, size_t wst // NESTED MEMBER ACCESS ============================================================================ -DynamicData -DynamicData::get_complex_value(rosidl_dynamic_typesupport_member_id_t id) +DynamicMessage +DynamicMessage::get_complex_value(rosidl_dynamic_typesupport_member_id_t id) { rosidl_dynamic_typesupport_dynamic_data_t * out_ptr = nullptr; rosidl_dynamic_typesupport_dynamic_data_get_complex_value( get_rosidl_dynamic_data(), id, &out_ptr); - return DynamicData(get_shared_dynamic_serialization_support(), out_ptr); + return DynamicMessage(get_shared_dynamic_serialization_support(), out_ptr); } -DynamicData -DynamicData::get_complex_value(const std::string & name) +DynamicMessage +DynamicMessage::get_complex_value(const std::string & name) { return get_complex_value(get_member_id(name)); } -DynamicData::SharedPtr -DynamicData::get_complex_value_shared(rosidl_dynamic_typesupport_member_id_t id) +DynamicMessage::SharedPtr +DynamicMessage::get_complex_value_shared(rosidl_dynamic_typesupport_member_id_t id) { rosidl_dynamic_typesupport_dynamic_data_t * out_ptr = nullptr; rosidl_dynamic_typesupport_dynamic_data_get_complex_value( get_rosidl_dynamic_data(), id, &out_ptr); - return DynamicData::make_shared(get_shared_dynamic_serialization_support(), out_ptr); + return DynamicMessage::make_shared(get_shared_dynamic_serialization_support(), out_ptr); } -DynamicData::SharedPtr -DynamicData::get_complex_value_shared(const std::string & name) +DynamicMessage::SharedPtr +DynamicMessage::get_complex_value_shared(const std::string & name) { return get_complex_value_shared(get_member_id(name)); } void -DynamicData::set_complex_value( - rosidl_dynamic_typesupport_member_id_t id, DynamicData & value) +DynamicMessage::set_complex_value( + rosidl_dynamic_typesupport_member_id_t id, DynamicMessage & value) { rosidl_dynamic_typesupport_dynamic_data_set_complex_value( get_rosidl_dynamic_data(), id, value.get_rosidl_dynamic_data()); @@ -746,14 +745,14 @@ DynamicData::set_complex_value( void -DynamicData::set_complex_value(const std::string & name, DynamicData & value) +DynamicMessage::set_complex_value(const std::string & name, DynamicMessage & value) { set_complex_value(get_member_id(name), value); } rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_complex_value_copy(const DynamicData & value) +DynamicMessage::insert_complex_value_copy(const DynamicMessage & value) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_complex_value_copy( @@ -763,7 +762,7 @@ DynamicData::insert_complex_value_copy(const DynamicData & value) rosidl_dynamic_typesupport_member_id_t -DynamicData::insert_complex_value(DynamicData & value) +DynamicMessage::insert_complex_value(DynamicMessage & value) { rosidl_dynamic_typesupport_member_id_t out; rosidl_dynamic_typesupport_dynamic_data_insert_complex_value( diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp similarity index 79% rename from rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp rename to rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp index 15bbcd1743..ddf509fe71 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp @@ -15,10 +15,10 @@ #include #include -#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" #include "rclcpp/exceptions.hpp" #include "rcutils/logging_macros.h" @@ -26,14 +26,14 @@ #include #include -using rclcpp::dynamic_typesupport::DynamicData; +using rclcpp::dynamic_typesupport::DynamicMessage; +using rclcpp::dynamic_typesupport::DynamicMessageType; +using rclcpp::dynamic_typesupport::DynamicMessageTypeBuilder; using rclcpp::dynamic_typesupport::DynamicSerializationSupport; -using rclcpp::dynamic_typesupport::DynamicType; -using rclcpp::dynamic_typesupport::DynamicTypeBuilder; // CONSTRUCTION ==================================================================================== -DynamicType::DynamicType(DynamicTypeBuilder::SharedPtr dynamic_type_builder) +DynamicMessageType::DynamicMessageType(DynamicMessageTypeBuilder::SharedPtr dynamic_type_builder) : serialization_support_(dynamic_type_builder->get_shared_dynamic_serialization_support()), rosidl_dynamic_type_(nullptr) { @@ -64,7 +64,7 @@ DynamicType::DynamicType(DynamicTypeBuilder::SharedPtr dynamic_type_builder) } -DynamicType::DynamicType( +DynamicMessageType::DynamicMessageType( DynamicSerializationSupport::SharedPtr serialization_support, rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type) : serialization_support_(serialization_support), rosidl_dynamic_type_(nullptr) @@ -89,7 +89,7 @@ DynamicType::DynamicType( } -DynamicType::DynamicType( +DynamicMessageType::DynamicMessageType( DynamicSerializationSupport::SharedPtr serialization_support, std::shared_ptr rosidl_dynamic_type) : serialization_support_(serialization_support), rosidl_dynamic_type_(rosidl_dynamic_type) @@ -106,7 +106,7 @@ DynamicType::DynamicType( } -DynamicType::DynamicType( +DynamicMessageType::DynamicMessageType( DynamicSerializationSupport::SharedPtr serialization_support, const rosidl_runtime_c__type_description__TypeDescription & description) : serialization_support_(serialization_support), rosidl_dynamic_type_(nullptr) @@ -115,29 +115,29 @@ DynamicType::DynamicType( } -DynamicType::DynamicType(const DynamicType & other) +DynamicMessageType::DynamicMessageType(const DynamicMessageType & other) : enable_shared_from_this(), serialization_support_(nullptr), rosidl_dynamic_type_(nullptr) { - DynamicType out = other.clone(); + DynamicMessageType out = other.clone(); std::swap(serialization_support_, out.serialization_support_); std::swap(rosidl_dynamic_type_, out.rosidl_dynamic_type_); } -DynamicType::DynamicType(DynamicType && other) noexcept +DynamicMessageType::DynamicMessageType(DynamicMessageType && other) noexcept : serialization_support_(std::exchange(other.serialization_support_, nullptr)), rosidl_dynamic_type_(std::exchange(other.rosidl_dynamic_type_, nullptr)) {} -DynamicType & -DynamicType::operator=(const DynamicType & other) +DynamicMessageType & +DynamicMessageType::operator=(const DynamicMessageType & other) { - return *this = DynamicType(other); + return *this = DynamicMessageType(other); } -DynamicType & -DynamicType::operator=(DynamicType && other) noexcept +DynamicMessageType & +DynamicMessageType::operator=(DynamicMessageType && other) noexcept { std::swap(serialization_support_, other.serialization_support_); std::swap(rosidl_dynamic_type_, other.rosidl_dynamic_type_); @@ -145,11 +145,11 @@ DynamicType::operator=(DynamicType && other) noexcept } -DynamicType::~DynamicType() {} +DynamicMessageType::~DynamicMessageType() {} void -DynamicType::init_from_description( +DynamicMessageType::init_from_description( const rosidl_runtime_c__type_description__TypeDescription & description, DynamicSerializationSupport::SharedPtr serialization_support) { @@ -177,7 +177,7 @@ DynamicType::init_from_description( bool -DynamicType::match_serialization_support_( +DynamicMessageType::match_serialization_support_( const DynamicSerializationSupport & serialization_support, const rosidl_dynamic_typesupport_dynamic_type_t & rosidl_dynamic_type) { @@ -206,14 +206,14 @@ DynamicType::match_serialization_support_( // GETTERS ========================================================================================= const std::string -DynamicType::get_library_identifier() const +DynamicMessageType::get_library_identifier() const { return std::string(rosidl_dynamic_type_->serialization_support->library_identifier); } const std::string -DynamicType::get_name() const +DynamicMessageType::get_name() const { size_t buf_length; const char * buf = rosidl_dynamic_typesupport_dynamic_type_get_name( @@ -223,28 +223,28 @@ DynamicType::get_name() const size_t -DynamicType::get_member_count() const +DynamicMessageType::get_member_count() const { return rosidl_dynamic_typesupport_dynamic_type_get_member_count(rosidl_dynamic_type_.get()); } rosidl_dynamic_typesupport_dynamic_type_t * -DynamicType::get_rosidl_dynamic_type() +DynamicMessageType::get_rosidl_dynamic_type() { return rosidl_dynamic_type_.get(); } const rosidl_dynamic_typesupport_dynamic_type_t * -DynamicType::get_rosidl_dynamic_type() const +DynamicMessageType::get_rosidl_dynamic_type() const { return rosidl_dynamic_type_.get(); } std::shared_ptr -DynamicType::get_shared_rosidl_dynamic_type() +DynamicMessageType::get_shared_rosidl_dynamic_type() { return std::shared_ptr( shared_from_this(), rosidl_dynamic_type_.get()); @@ -252,7 +252,7 @@ DynamicType::get_shared_rosidl_dynamic_type() std::shared_ptr -DynamicType::get_shared_rosidl_dynamic_type() const +DynamicMessageType::get_shared_rosidl_dynamic_type() const { return std::shared_ptr( shared_from_this(), rosidl_dynamic_type_.get()); @@ -260,40 +260,40 @@ DynamicType::get_shared_rosidl_dynamic_type() const DynamicSerializationSupport::SharedPtr -DynamicType::get_shared_dynamic_serialization_support() +DynamicMessageType::get_shared_dynamic_serialization_support() { return serialization_support_; } DynamicSerializationSupport::ConstSharedPtr -DynamicType::get_shared_dynamic_serialization_support() const +DynamicMessageType::get_shared_dynamic_serialization_support() const { return serialization_support_; } // METHODS ========================================================================================= -DynamicType -DynamicType::clone() const +DynamicMessageType +DynamicMessageType::clone() const { - return DynamicType( + return DynamicMessageType( serialization_support_, rosidl_dynamic_typesupport_dynamic_type_clone(get_rosidl_dynamic_type())); } -DynamicType::SharedPtr -DynamicType::clone_shared() const +DynamicMessageType::SharedPtr +DynamicMessageType::clone_shared() const { - return DynamicType::make_shared( + return DynamicMessageType::make_shared( serialization_support_, rosidl_dynamic_typesupport_dynamic_type_clone(get_rosidl_dynamic_type())); } bool -DynamicType::equals(const DynamicType & other) const +DynamicMessageType::equals(const DynamicMessageType & other) const { if (get_library_identifier() != other.get_library_identifier()) { throw std::runtime_error("library identifiers don't match"); @@ -303,15 +303,15 @@ DynamicType::equals(const DynamicType & other) const } -DynamicData -DynamicType::build_data() +DynamicMessage +DynamicMessageType::build_dynamic_message() { - return DynamicData(shared_from_this()); + return DynamicMessage(shared_from_this()); } -DynamicData::SharedPtr -DynamicType::build_data_shared() +DynamicMessage::SharedPtr +DynamicMessageType::build_dynamic_message_shared() { - return DynamicData::make_shared(shared_from_this()); + return DynamicMessage::make_shared(shared_from_this()); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp similarity index 78% rename from rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp rename to rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp index 47eef39c29..adfde4892f 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp @@ -15,10 +15,10 @@ #include #include -#include "rclcpp/dynamic_typesupport/dynamic_data.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type.hpp" -#include "rclcpp/dynamic_typesupport/dynamic_type_builder.hpp" #include "rclcpp/exceptions.hpp" #include "rcutils/logging_macros.h" @@ -26,20 +26,20 @@ #include #include -using rclcpp::dynamic_typesupport::DynamicData; +using rclcpp::dynamic_typesupport::DynamicMessage; +using rclcpp::dynamic_typesupport::DynamicMessageType; +using rclcpp::dynamic_typesupport::DynamicMessageTypeBuilder; using rclcpp::dynamic_typesupport::DynamicSerializationSupport; -using rclcpp::dynamic_typesupport::DynamicType; -using rclcpp::dynamic_typesupport::DynamicTypeBuilder; -#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_TYPE_BUILDER_IMPL_HPP_ +#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_ // Template specialization implementations -#include "rclcpp/dynamic_typesupport/detail/dynamic_type_builder_impl.hpp" +#include "rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp" #endif // CONSTRUCTION ================================================================================== -DynamicTypeBuilder::DynamicTypeBuilder( +DynamicMessageTypeBuilder::DynamicMessageTypeBuilder( DynamicSerializationSupport::SharedPtr serialization_support, const std::string & name) : serialization_support_(serialization_support), rosidl_dynamic_type_builder_(nullptr) { @@ -50,7 +50,7 @@ DynamicTypeBuilder::DynamicTypeBuilder( } -DynamicTypeBuilder::DynamicTypeBuilder( +DynamicMessageTypeBuilder::DynamicMessageTypeBuilder( DynamicSerializationSupport::SharedPtr serialization_support, rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder) : serialization_support_(serialization_support), rosidl_dynamic_type_builder_(nullptr) @@ -76,7 +76,7 @@ DynamicTypeBuilder::DynamicTypeBuilder( } -DynamicTypeBuilder::DynamicTypeBuilder( +DynamicMessageTypeBuilder::DynamicMessageTypeBuilder( DynamicSerializationSupport::SharedPtr serialization_support, std::shared_ptr rosidl_dynamic_type_builder) : serialization_support_(serialization_support), @@ -95,7 +95,7 @@ DynamicTypeBuilder::DynamicTypeBuilder( } -DynamicTypeBuilder::DynamicTypeBuilder( +DynamicMessageTypeBuilder::DynamicMessageTypeBuilder( DynamicSerializationSupport::SharedPtr serialization_support, const rosidl_runtime_c__type_description__TypeDescription & description) : serialization_support_(serialization_support), @@ -108,29 +108,29 @@ DynamicTypeBuilder::DynamicTypeBuilder( } -DynamicTypeBuilder::DynamicTypeBuilder(const DynamicTypeBuilder & other) +DynamicMessageTypeBuilder::DynamicMessageTypeBuilder(const DynamicMessageTypeBuilder & other) : enable_shared_from_this(), serialization_support_(nullptr), rosidl_dynamic_type_builder_(nullptr) { - DynamicTypeBuilder out = other.clone(); + DynamicMessageTypeBuilder out = other.clone(); std::swap(serialization_support_, out.serialization_support_); std::swap(rosidl_dynamic_type_builder_, out.rosidl_dynamic_type_builder_); } -DynamicTypeBuilder::DynamicTypeBuilder(DynamicTypeBuilder && other) noexcept +DynamicMessageTypeBuilder::DynamicMessageTypeBuilder(DynamicMessageTypeBuilder && other) noexcept : serialization_support_(std::exchange(other.serialization_support_, nullptr)), rosidl_dynamic_type_builder_(std::exchange(other.rosidl_dynamic_type_builder_, nullptr)) {} -DynamicTypeBuilder & -DynamicTypeBuilder::operator=(const DynamicTypeBuilder & other) +DynamicMessageTypeBuilder & +DynamicMessageTypeBuilder::operator=(const DynamicMessageTypeBuilder & other) { - return *this = DynamicTypeBuilder(other); + return *this = DynamicMessageTypeBuilder(other); } -DynamicTypeBuilder & -DynamicTypeBuilder::operator=(DynamicTypeBuilder && other) noexcept +DynamicMessageTypeBuilder & +DynamicMessageTypeBuilder::operator=(DynamicMessageTypeBuilder && other) noexcept { std::swap(serialization_support_, other.serialization_support_); std::swap(rosidl_dynamic_type_builder_, other.rosidl_dynamic_type_builder_); @@ -138,11 +138,11 @@ DynamicTypeBuilder::operator=(DynamicTypeBuilder && other) noexcept } -DynamicTypeBuilder::~DynamicTypeBuilder() {} +DynamicMessageTypeBuilder::~DynamicMessageTypeBuilder() {} void -DynamicTypeBuilder::init_from_description( +DynamicMessageTypeBuilder::init_from_description( const rosidl_runtime_c__type_description__TypeDescription & description, DynamicSerializationSupport::SharedPtr serialization_support) { @@ -170,7 +170,7 @@ DynamicTypeBuilder::init_from_description( void -DynamicTypeBuilder::init_from_serialization_support_( +DynamicMessageTypeBuilder::init_from_serialization_support_( DynamicSerializationSupport::SharedPtr serialization_support, const std::string & name) { @@ -201,7 +201,7 @@ DynamicTypeBuilder::init_from_serialization_support_( bool -DynamicTypeBuilder::match_serialization_support_( +DynamicMessageTypeBuilder::match_serialization_support_( const DynamicSerializationSupport & serialization_support, const rosidl_dynamic_typesupport_dynamic_type_builder_t & rosidl_dynamic_type_builder) { @@ -230,14 +230,14 @@ DynamicTypeBuilder::match_serialization_support_( // GETTERS ======================================================================================= const std::string -DynamicTypeBuilder::get_library_identifier() const +DynamicMessageTypeBuilder::get_library_identifier() const { return std::string(rosidl_dynamic_type_builder_->serialization_support->library_identifier); } const std::string -DynamicTypeBuilder::get_name() const +DynamicMessageTypeBuilder::get_name() const { size_t buf_length; const char * buf = rosidl_dynamic_typesupport_dynamic_type_builder_get_name( @@ -247,21 +247,21 @@ DynamicTypeBuilder::get_name() const rosidl_dynamic_typesupport_dynamic_type_builder_t * -DynamicTypeBuilder::get_rosidl_dynamic_type_builder() +DynamicMessageTypeBuilder::get_rosidl_dynamic_type_builder() { return rosidl_dynamic_type_builder_.get(); } const rosidl_dynamic_typesupport_dynamic_type_builder_t * -DynamicTypeBuilder::get_rosidl_dynamic_type_builder() const +DynamicMessageTypeBuilder::get_rosidl_dynamic_type_builder() const { return rosidl_dynamic_type_builder_.get(); } std::shared_ptr -DynamicTypeBuilder::get_shared_rosidl_dynamic_type_builder() +DynamicMessageTypeBuilder::get_shared_rosidl_dynamic_type_builder() { return std::shared_ptr( shared_from_this(), rosidl_dynamic_type_builder_.get()); @@ -269,7 +269,7 @@ DynamicTypeBuilder::get_shared_rosidl_dynamic_type_builder() std::shared_ptr -DynamicTypeBuilder::get_shared_rosidl_dynamic_type_builder() const +DynamicMessageTypeBuilder::get_shared_rosidl_dynamic_type_builder() const { return std::shared_ptr( shared_from_this(), rosidl_dynamic_type_builder_.get()); @@ -277,14 +277,14 @@ DynamicTypeBuilder::get_shared_rosidl_dynamic_type_builder() const DynamicSerializationSupport::SharedPtr -DynamicTypeBuilder::get_shared_dynamic_serialization_support() +DynamicMessageTypeBuilder::get_shared_dynamic_serialization_support() { return serialization_support_; } DynamicSerializationSupport::ConstSharedPtr -DynamicTypeBuilder::get_shared_dynamic_serialization_support() const +DynamicMessageTypeBuilder::get_shared_dynamic_serialization_support() const { return serialization_support_; } @@ -292,33 +292,33 @@ DynamicTypeBuilder::get_shared_dynamic_serialization_support() const // METHODS ======================================================================================= void -DynamicTypeBuilder::set_name(const std::string & name) +DynamicMessageTypeBuilder::set_name(const std::string & name) { rosidl_dynamic_typesupport_dynamic_type_builder_set_name( get_rosidl_dynamic_type_builder(), name.c_str(), name.size()); } -DynamicTypeBuilder -DynamicTypeBuilder::clone() const +DynamicMessageTypeBuilder +DynamicMessageTypeBuilder::clone() const { - return DynamicTypeBuilder( + return DynamicMessageTypeBuilder( serialization_support_, rosidl_dynamic_typesupport_dynamic_type_builder_clone(get_rosidl_dynamic_type_builder())); } -DynamicTypeBuilder::SharedPtr -DynamicTypeBuilder::clone_shared() const +DynamicMessageTypeBuilder::SharedPtr +DynamicMessageTypeBuilder::clone_shared() const { - return DynamicTypeBuilder::make_shared( + return DynamicMessageTypeBuilder::make_shared( serialization_support_, rosidl_dynamic_typesupport_dynamic_type_builder_clone(get_rosidl_dynamic_type_builder())); } void -DynamicTypeBuilder::clear() +DynamicMessageTypeBuilder::clear() { if (!serialization_support_) { throw std::runtime_error( @@ -333,41 +333,41 @@ DynamicTypeBuilder::clear() } -DynamicData -DynamicTypeBuilder::build_data() +DynamicMessage +DynamicMessageTypeBuilder::build_dynamic_message() { - return DynamicData(shared_from_this()); + return DynamicMessage(shared_from_this()); } -DynamicData::SharedPtr -DynamicTypeBuilder::build_data_shared() +DynamicMessage::SharedPtr +DynamicMessageTypeBuilder::build_dynamic_message_shared() { - return DynamicData::make_shared(shared_from_this()); + return DynamicMessage::make_shared(shared_from_this()); } -DynamicType -DynamicTypeBuilder::build_type() +DynamicMessageType +DynamicMessageTypeBuilder::build_dynamic_message_type() { - return DynamicType(shared_from_this()); + return DynamicMessageType(shared_from_this()); } -DynamicType::SharedPtr -DynamicTypeBuilder::build_type_shared() +DynamicMessageType::SharedPtr +DynamicMessageTypeBuilder::build_dynamic_message_type_shared() { - return DynamicType::make_shared(shared_from_this()); + return DynamicMessageType::make_shared(shared_from_this()); } // ADD MEMBERS ===================================================================================== -// Defined in "detail/dynamic_type_builder_impl.hpp" +// Defined in "detail/dynamic_message_type_builder_impl.hpp" // ADD FIXED STRING MEMBERS ======================================================================== void -DynamicTypeBuilder::add_fixed_string_member( +DynamicMessageTypeBuilder::add_fixed_string_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_length, const std::string & default_value) { @@ -379,7 +379,7 @@ DynamicTypeBuilder::add_fixed_string_member( void -DynamicTypeBuilder::add_fixed_wstring_member( +DynamicMessageTypeBuilder::add_fixed_wstring_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_length, const std::string & default_value) { @@ -391,7 +391,7 @@ DynamicTypeBuilder::add_fixed_wstring_member( void -DynamicTypeBuilder::add_fixed_string_array_member( +DynamicMessageTypeBuilder::add_fixed_string_array_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_length, size_t array_length, const std::string & default_value) { @@ -403,7 +403,7 @@ DynamicTypeBuilder::add_fixed_string_array_member( void -DynamicTypeBuilder::add_fixed_wstring_array_member( +DynamicMessageTypeBuilder::add_fixed_wstring_array_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_length, size_t array_length, const std::string & default_value) { @@ -415,7 +415,7 @@ DynamicTypeBuilder::add_fixed_wstring_array_member( void -DynamicTypeBuilder::add_fixed_string_unbounded_sequence_member( +DynamicMessageTypeBuilder::add_fixed_string_unbounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_length, const std::string & default_value) { @@ -427,7 +427,7 @@ DynamicTypeBuilder::add_fixed_string_unbounded_sequence_member( void -DynamicTypeBuilder::add_fixed_wstring_unbounded_sequence_member( +DynamicMessageTypeBuilder::add_fixed_wstring_unbounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_length, const std::string & default_value) { @@ -439,7 +439,7 @@ DynamicTypeBuilder::add_fixed_wstring_unbounded_sequence_member( void -DynamicTypeBuilder::add_fixed_string_bounded_sequence_member( +DynamicMessageTypeBuilder::add_fixed_string_bounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_length, size_t sequence_bound, const std::string & default_value) { @@ -451,7 +451,7 @@ DynamicTypeBuilder::add_fixed_string_bounded_sequence_member( void -DynamicTypeBuilder::add_fixed_wstring_bounded_sequence_member( +DynamicMessageTypeBuilder::add_fixed_wstring_bounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_length, size_t sequence_bound, const std::string & default_value) { @@ -464,7 +464,7 @@ DynamicTypeBuilder::add_fixed_wstring_bounded_sequence_member( // ADD BOUNDED STRING MEMBERS ====================================================================== void -DynamicTypeBuilder::add_bounded_string_member( +DynamicMessageTypeBuilder::add_bounded_string_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound, const std::string & default_value) { @@ -476,7 +476,7 @@ DynamicTypeBuilder::add_bounded_string_member( void -DynamicTypeBuilder::add_bounded_wstring_member( +DynamicMessageTypeBuilder::add_bounded_wstring_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound, const std::string & default_value) { @@ -488,7 +488,7 @@ DynamicTypeBuilder::add_bounded_wstring_member( void -DynamicTypeBuilder::add_bounded_string_array_member( +DynamicMessageTypeBuilder::add_bounded_string_array_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound, size_t array_length, const std::string & default_value) { @@ -500,7 +500,7 @@ DynamicTypeBuilder::add_bounded_string_array_member( void -DynamicTypeBuilder::add_bounded_wstring_array_member( +DynamicMessageTypeBuilder::add_bounded_wstring_array_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound, size_t array_length, const std::string & default_value) { @@ -512,7 +512,7 @@ DynamicTypeBuilder::add_bounded_wstring_array_member( void -DynamicTypeBuilder::add_bounded_string_unbounded_sequence_member( +DynamicMessageTypeBuilder::add_bounded_string_unbounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound, const std::string & default_value) { @@ -524,7 +524,7 @@ DynamicTypeBuilder::add_bounded_string_unbounded_sequence_member( void -DynamicTypeBuilder::add_bounded_wstring_unbounded_sequence_member( +DynamicMessageTypeBuilder::add_bounded_wstring_unbounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound, const std::string & default_value) { @@ -536,7 +536,7 @@ DynamicTypeBuilder::add_bounded_wstring_unbounded_sequence_member( void -DynamicTypeBuilder::add_bounded_string_bounded_sequence_member( +DynamicMessageTypeBuilder::add_bounded_string_bounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_bound, size_t sequence_bound, const std::string & default_value) { @@ -548,7 +548,7 @@ DynamicTypeBuilder::add_bounded_string_bounded_sequence_member( void -DynamicTypeBuilder::add_bounded_wstring_bounded_sequence_member( +DynamicMessageTypeBuilder::add_bounded_wstring_bounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_bound, size_t sequence_bound, const std::string & default_value) { @@ -561,9 +561,9 @@ DynamicTypeBuilder::add_bounded_wstring_bounded_sequence_member( // ADD NESTED MEMBERS ============================================================================== void -DynamicTypeBuilder::add_complex_member( +DynamicMessageTypeBuilder::add_complex_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicType & nested_type, const std::string & default_value) + DynamicMessageType & nested_type, const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_member( get_rosidl_dynamic_type_builder(), @@ -573,9 +573,9 @@ DynamicTypeBuilder::add_complex_member( void -DynamicTypeBuilder::add_complex_array_member( +DynamicMessageTypeBuilder::add_complex_array_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicType & nested_type, size_t array_length, const std::string & default_value) + DynamicMessageType & nested_type, size_t array_length, const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_array_member( get_rosidl_dynamic_type_builder(), @@ -585,9 +585,9 @@ DynamicTypeBuilder::add_complex_array_member( void -DynamicTypeBuilder::add_complex_unbounded_sequence_member( +DynamicMessageTypeBuilder::add_complex_unbounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicType & nested_type, const std::string & default_value) + DynamicMessageType & nested_type, const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_unbounded_sequence_member( get_rosidl_dynamic_type_builder(), @@ -597,9 +597,9 @@ DynamicTypeBuilder::add_complex_unbounded_sequence_member( void -DynamicTypeBuilder::add_complex_bounded_sequence_member( +DynamicMessageTypeBuilder::add_complex_bounded_sequence_member( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicType & nested_type, size_t sequence_bound, const std::string & default_value) + DynamicMessageType & nested_type, size_t sequence_bound, const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_bounded_sequence_member( get_rosidl_dynamic_type_builder(), @@ -609,9 +609,9 @@ DynamicTypeBuilder::add_complex_bounded_sequence_member( void -DynamicTypeBuilder::add_complex_member_builder( +DynamicMessageTypeBuilder::add_complex_member_builder( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicTypeBuilder & nested_type_builder, const std::string & default_value) + DynamicMessageTypeBuilder & nested_type_builder, const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_member_builder( get_rosidl_dynamic_type_builder(), @@ -621,9 +621,9 @@ DynamicTypeBuilder::add_complex_member_builder( void -DynamicTypeBuilder::add_complex_array_member_builder( +DynamicMessageTypeBuilder::add_complex_array_member_builder( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicTypeBuilder & nested_type_builder, size_t array_length, const std::string & default_value) + DynamicMessageTypeBuilder & nested_type_builder, size_t array_length, const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_array_member_builder( get_rosidl_dynamic_type_builder(), @@ -633,9 +633,9 @@ DynamicTypeBuilder::add_complex_array_member_builder( void -DynamicTypeBuilder::add_complex_unbounded_sequence_member_builder( +DynamicMessageTypeBuilder::add_complex_unbounded_sequence_member_builder( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicTypeBuilder & nested_type_builder, const std::string & default_value) + DynamicMessageTypeBuilder & nested_type_builder, const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_unbounded_sequence_member_builder( get_rosidl_dynamic_type_builder(), @@ -645,9 +645,9 @@ DynamicTypeBuilder::add_complex_unbounded_sequence_member_builder( void -DynamicTypeBuilder::add_complex_bounded_sequence_member_builder( +DynamicMessageTypeBuilder::add_complex_bounded_sequence_member_builder( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicTypeBuilder & nested_type_builder, size_t sequence_bound, + DynamicMessageTypeBuilder & nested_type_builder, size_t sequence_bound, const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_bounded_sequence_member_builder( diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index 77b68c46a1..42016f7cfe 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -21,8 +21,8 @@ #include "rcl/rcl_dynamic_typesupport_c/message_introspection.h" -#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/exceptions.hpp" #include "rclcpp/macros.hpp" @@ -35,10 +35,10 @@ #include #include -using rclcpp::dynamic_typesupport::DynamicSerializationSupport; using rclcpp::dynamic_typesupport::DynamicMessage; using rclcpp::dynamic_typesupport::DynamicMessageType; using rclcpp::dynamic_typesupport::DynamicMessageTypeSupport; +using rclcpp::dynamic_typesupport::DynamicSerializationSupport; // CONSTRUCTION ==================================================================================== @@ -61,7 +61,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( serialization_library_name.c_str(), &description, &ts); } if (ret != RCL_RET_OK) { - throw std::runtime_error("error initializing rosidl message type support"); + throw std::runtime_error("error initializing rosidl message type support"); } if (!ts) { throw std::runtime_error("could not init rosidl message type support"); diff --git a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp index e8e9728892..49026b14d4 100644 --- a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp +++ b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp @@ -28,8 +28,8 @@ #include "../../mocking_utils/patch.hpp" #include "../../utils/rclcpp_gtest_macros.hpp" -using rclcpp::dynamic_typesupport::DynamicMessageType; using rclcpp::dynamic_typesupport::DynamicMessage; +using rclcpp::dynamic_typesupport::DynamicMessageType; using rclcpp::dynamic_typesupport::DynamicSerializationSupport; From 113dc01dc70ca54fcab3d5a62f936c8e09f6f9b6 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sat, 1 Apr 2023 03:46:22 -0700 Subject: [PATCH 18/27] Migrate methods to use return types Signed-off-by: methylDragon --- .../dynamic_typesupport/dynamic_message.cpp | 142 +++++++++++++----- .../dynamic_message_type.cpp | 58 ++++--- .../dynamic_message_type_builder.cpp | 47 ++++-- .../dynamic_message_type_support.cpp | 7 +- .../dynamic_serialization_support.cpp | 10 +- 5 files changed, 188 insertions(+), 76 deletions(-) diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp index 8775c928ea..7b8053d634 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp @@ -56,10 +56,10 @@ DynamicMessage::DynamicMessage(const DynamicMessageTypeBuilder::SharedPtr dynami } rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; - rosidl_dynamic_data = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type_builder( - rosidl_dynamic_type_builder); - if (!rosidl_dynamic_data) { - throw std::runtime_error("could not create new dynamic data object"); + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type_builder( + rosidl_dynamic_type_builder, &rosidl_dynamic_data); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { + throw std::runtime_error("could not create new dynamic data object from dynamic type builder"); } rosidl_dynamic_data_.reset( @@ -89,10 +89,12 @@ DynamicMessage::DynamicMessage(const DynamicMessageType::SharedPtr dynamic_type) } rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; - rosidl_dynamic_data = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type( - rosidl_dynamic_type); - if (!rosidl_dynamic_data) { - throw std::runtime_error("could not create new dynamic data object"); + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type( + rosidl_dynamic_type, &rosidl_dynamic_data); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { + throw std::runtime_error( + std::string("could not create new dynamic data object from dynamic type") + + rcl_get_error_string().str); } rosidl_dynamic_data_.reset( @@ -277,8 +279,13 @@ const std::string DynamicMessage::get_name() const { size_t buf_length; - const char * buf = rosidl_dynamic_typesupport_dynamic_data_get_name( - get_rosidl_dynamic_data(), &buf_length); + const char * buf; + if ( + rosidl_dynamic_typesupport_dynamic_data_get_name(get_rosidl_dynamic_data(), &buf, &buf_length) + != RCUTILS_RET_OK) { + throw std::runtime_error( + std::string("could not get name for dynamic data") + rcl_get_error_string().str); + } return std::string(buf, buf_length); } @@ -330,31 +337,52 @@ DynamicMessage::get_shared_dynamic_serialization_support() const size_t DynamicMessage::get_item_count() const { - return rosidl_dynamic_typesupport_dynamic_data_get_item_count(get_rosidl_dynamic_data()); + size_t item_count; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_get_item_count( + get_rosidl_dynamic_data(), &item_count); + if (ret != RCUTILS_RET_OK) { + throw std::runtime_error("could not get item count of dynamic data"); + } + return item_count; } rosidl_dynamic_typesupport_member_id_t DynamicMessage::get_member_id(size_t index) const { - return rosidl_dynamic_typesupport_dynamic_data_get_member_id_at_index( - get_rosidl_dynamic_data(), index); + rosidl_dynamic_typesupport_member_id_t member_id; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_get_member_id_at_index( + get_rosidl_dynamic_data(), index, &member_id); + if (ret != RCUTILS_RET_OK) { + throw std::runtime_error("could not member id of dynamic data element by index"); + } + return member_id; } rosidl_dynamic_typesupport_member_id_t DynamicMessage::get_member_id(const std::string & name) const { - return rosidl_dynamic_typesupport_dynamic_data_get_member_id_by_name( - get_rosidl_dynamic_data(), name.c_str(), name.size()); + rosidl_dynamic_typesupport_member_id_t member_id; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_get_member_id_by_name( + get_rosidl_dynamic_data(), name.c_str(), name.size(), &member_id); + if (ret != RCUTILS_RET_OK) { + throw std::runtime_error("could not member id of dynamic data element by name"); + } + return member_id; } rosidl_dynamic_typesupport_member_id_t DynamicMessage::get_array_index(size_t index) const { - return rosidl_dynamic_typesupport_dynamic_data_get_array_index( - get_rosidl_dynamic_data(), index); + rosidl_dynamic_typesupport_member_id_t array_index; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_get_array_index( + get_rosidl_dynamic_data(), index, &array_index); + if (ret != RCUTILS_RET_OK) { + throw std::runtime_error("could not array index of dynamic data element by index"); + } + return array_index; } @@ -369,36 +397,54 @@ DynamicMessage::get_array_index(const std::string & name) const DynamicMessage DynamicMessage::clone() const { - return DynamicMessage( - serialization_support_, - rosidl_dynamic_typesupport_dynamic_data_clone(get_rosidl_dynamic_data())); + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_clone( + get_rosidl_dynamic_data(), &rosidl_dynamic_data); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { + throw std::runtime_error( + std::string("could not clone dynamic data: ") + rcl_get_error_string().str); + } + return DynamicMessage(serialization_support_, rosidl_dynamic_data); } DynamicMessage::SharedPtr DynamicMessage::clone_shared() const { - return DynamicMessage::make_shared( - serialization_support_, - rosidl_dynamic_typesupport_dynamic_data_clone(get_rosidl_dynamic_data())); + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_clone( + get_rosidl_dynamic_data(), &rosidl_dynamic_data); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { + throw std::runtime_error( + std::string("could not clone dynamic data: ") + rcl_get_error_string().str); + } + return DynamicMessage::make_shared(serialization_support_, rosidl_dynamic_data); } DynamicMessage DynamicMessage::init_from_type(DynamicMessageType & type) const { - return DynamicMessage( - serialization_support_, - rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(type.get_rosidl_dynamic_type())); + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type( + type.get_rosidl_dynamic_type(), &rosidl_dynamic_data); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { + throw std::runtime_error("could not create new dynamic data object from dynamic type"); + } + return DynamicMessage(serialization_support_, rosidl_dynamic_data); } DynamicMessage::SharedPtr DynamicMessage::init_from_type_shared(DynamicMessageType & type) const { - return DynamicMessage::make_shared( - serialization_support_, - rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(type.get_rosidl_dynamic_type())); + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type( + type.get_rosidl_dynamic_type(), &rosidl_dynamic_data); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { + throw std::runtime_error("could not create new dynamic data object from dynamic type"); + } + return DynamicMessage::make_shared(serialization_support_, rosidl_dynamic_data); } @@ -408,17 +454,27 @@ DynamicMessage::equals(const DynamicMessage & other) const if (get_library_identifier() != other.get_library_identifier()) { throw std::runtime_error("library identifiers don't match"); } - return rosidl_dynamic_typesupport_dynamic_data_equals( - get_rosidl_dynamic_data(), other.get_rosidl_dynamic_data()); + bool equals; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_equals( + get_rosidl_dynamic_data(), other.get_rosidl_dynamic_data(), &equals); + if (ret != RCUTILS_RET_OK) { + throw std::runtime_error("could not equate dynamic messages"); + } + return equals; } DynamicMessage::SharedPtr DynamicMessage::loan_value(rosidl_dynamic_typesupport_member_id_t id) { - return DynamicMessage::make_shared( - shared_from_this(), - rosidl_dynamic_typesupport_dynamic_data_loan_value(get_rosidl_dynamic_data(), id)); + rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_loan_value( + get_rosidl_dynamic_data(), id, &rosidl_dynamic_data); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { + throw std::runtime_error( + std::string("could not loan dynamic data: ") + rcl_get_error_string().str); + } + return DynamicMessage::make_shared(shared_from_this(), rosidl_dynamic_data); } @@ -491,14 +547,28 @@ DynamicMessage::print() const bool DynamicMessage::serialize(rcl_serialized_message_t * buffer) { - return rosidl_dynamic_typesupport_dynamic_data_serialize(get_rosidl_dynamic_data(), buffer); + bool success; + rcutils_ret_t ret = + rosidl_dynamic_typesupport_dynamic_data_serialize(get_rosidl_dynamic_data(), buffer, &success); + if (ret != RCUTILS_RET_OK || !success) { + throw std::runtime_error( + std::string("could serialize loan dynamic data: ") + rcl_get_error_string().str); + } + return success; } bool DynamicMessage::deserialize(rcl_serialized_message_t * buffer) { - return rosidl_dynamic_typesupport_dynamic_data_deserialize(get_rosidl_dynamic_data(), buffer); + bool success; + rcutils_ret_t ret = + rosidl_dynamic_typesupport_dynamic_data_deserialize(get_rosidl_dynamic_data(), buffer, &success); + if (ret != RCUTILS_RET_OK || !success) { + throw std::runtime_error( + std::string("could deserialize loan dynamic data: ") + rcl_get_error_string().str); + } + return success; } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp index ddf509fe71..54ad04c989 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp @@ -48,9 +48,9 @@ DynamicMessageType::DynamicMessageType(DynamicMessageTypeBuilder::SharedPtr dyna } rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type = nullptr; - rosidl_dynamic_type = rosidl_dynamic_typesupport_dynamic_type_init_from_dynamic_type_builder( - rosidl_dynamic_type_builder); - if (!rosidl_dynamic_type) { + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_init_from_dynamic_type_builder( + rosidl_dynamic_type_builder, &rosidl_dynamic_type); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type) { throw std::runtime_error("could not create new dynamic type object"); } @@ -159,10 +159,9 @@ DynamicMessageType::init_from_description( } rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type = nullptr; - rosidl_dynamic_type = - rosidl_dynamic_typesupport_dynamic_type_init_from_description( - serialization_support_->get_rosidl_serialization_support(), &description); - if (!rosidl_dynamic_type) { + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_init_from_description( + serialization_support_->get_rosidl_serialization_support(), &description, &rosidl_dynamic_type); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type) { throw std::runtime_error("could not create new dynamic type object"); } @@ -216,8 +215,8 @@ const std::string DynamicMessageType::get_name() const { size_t buf_length; - const char * buf = rosidl_dynamic_typesupport_dynamic_type_get_name( - get_rosidl_dynamic_type(), &buf_length); + const char * buf; + rosidl_dynamic_typesupport_dynamic_type_get_name(get_rosidl_dynamic_type(), &buf, &buf_length); return std::string(buf, buf_length); } @@ -225,7 +224,14 @@ DynamicMessageType::get_name() const size_t DynamicMessageType::get_member_count() const { - return rosidl_dynamic_typesupport_dynamic_type_get_member_count(rosidl_dynamic_type_.get()); + size_t out; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_get_member_count( + rosidl_dynamic_type_.get(), &out); + if (ret != RCUTILS_RET_OK) { + throw std::runtime_error( + std::string("could not get member count: ") + rcl_get_error_string().str); + } + return out; } @@ -277,18 +283,28 @@ DynamicMessageType::get_shared_dynamic_serialization_support() const DynamicMessageType DynamicMessageType::clone() const { - return DynamicMessageType( - serialization_support_, - rosidl_dynamic_typesupport_dynamic_type_clone(get_rosidl_dynamic_type())); + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_clone( + get_rosidl_dynamic_type(), &rosidl_dynamic_type); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type) { + throw std::runtime_error( + std::string("could not clone dynamic type: ") + rcl_get_error_string().str); + } + return DynamicMessageType(serialization_support_, rosidl_dynamic_type); } DynamicMessageType::SharedPtr DynamicMessageType::clone_shared() const { - return DynamicMessageType::make_shared( - serialization_support_, - rosidl_dynamic_typesupport_dynamic_type_clone(get_rosidl_dynamic_type())); + rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_clone( + get_rosidl_dynamic_type(), &rosidl_dynamic_type); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type) { + throw std::runtime_error( + std::string("could not clone dynamic type: ") + rcl_get_error_string().str); + } + return DynamicMessageType::make_shared(serialization_support_, rosidl_dynamic_type); } @@ -298,8 +314,14 @@ DynamicMessageType::equals(const DynamicMessageType & other) const if (get_library_identifier() != other.get_library_identifier()) { throw std::runtime_error("library identifiers don't match"); } - return rosidl_dynamic_typesupport_dynamic_type_equals( - get_rosidl_dynamic_type(), other.get_rosidl_dynamic_type()); + bool out; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_equals( + get_rosidl_dynamic_type(), other.get_rosidl_dynamic_type(), &out); + if (ret != RCUTILS_RET_OK) { + throw std::runtime_error( + std::string("could not equate dynamic message types: ") + rcl_get_error_string().str); + } + return out; } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp index adfde4892f..82712dafba 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp @@ -152,10 +152,10 @@ DynamicMessageTypeBuilder::init_from_description( } rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; - rosidl_dynamic_type_builder = - rosidl_dynamic_typesupport_dynamic_type_builder_init_from_description( - serialization_support_->get_rosidl_serialization_support(), &description); - if (!rosidl_dynamic_type_builder) { + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_init_from_description( + serialization_support_->get_rosidl_serialization_support(), &description, + &rosidl_dynamic_type_builder); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type_builder) { throw std::runtime_error("could not create new dynamic type builder object"); } @@ -183,11 +183,16 @@ DynamicMessageTypeBuilder::init_from_serialization_support_( rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; - rosidl_dynamic_type_builder = rosidl_dynamic_typesupport_dynamic_type_builder_init( - serialization_support->get_rosidl_serialization_support(), name.c_str(), name.size()); - + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_init( + serialization_support->get_rosidl_serialization_support(), + name.c_str(), name.size(), + &rosidl_dynamic_type_builder); + if (ret != RCUTILS_RET_OK) { + throw std::runtime_error( + std::string("could not init dynamic type builder: ") + rcl_get_error_string().str); + } if (!rosidl_dynamic_type_builder) { - throw std::runtime_error("could not create new dynamic type builder object"); + throw std::runtime_error("could not init dynamic type builder object"); } rosidl_dynamic_type_builder_.reset( @@ -240,8 +245,9 @@ const std::string DynamicMessageTypeBuilder::get_name() const { size_t buf_length; - const char * buf = rosidl_dynamic_typesupport_dynamic_type_builder_get_name( - get_rosidl_dynamic_type_builder(), &buf_length); + const char * buf; + rosidl_dynamic_typesupport_dynamic_type_builder_get_name( + get_rosidl_dynamic_type_builder(), &buf, &buf_length); return std::string(buf, buf_length); } @@ -302,18 +308,29 @@ DynamicMessageTypeBuilder::set_name(const std::string & name) DynamicMessageTypeBuilder DynamicMessageTypeBuilder::clone() const { - return DynamicMessageTypeBuilder( - serialization_support_, - rosidl_dynamic_typesupport_dynamic_type_builder_clone(get_rosidl_dynamic_type_builder())); + rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_clone( + get_rosidl_dynamic_type_builder(), &rosidl_dynamic_type_builder); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type_builder) { + throw std::runtime_error( + std::string("could not clone dynamic type builder: ") + rcl_get_error_string().str); + } + return DynamicMessageTypeBuilder(serialization_support_, rosidl_dynamic_type_builder); } DynamicMessageTypeBuilder::SharedPtr DynamicMessageTypeBuilder::clone_shared() const { + rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_clone( + get_rosidl_dynamic_type_builder(), &rosidl_dynamic_type_builder); + if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type_builder) { + throw std::runtime_error( + std::string("could not clone dynamic type builder: ") + rcl_get_error_string().str); + } return DynamicMessageTypeBuilder::make_shared( - serialization_support_, - rosidl_dynamic_typesupport_dynamic_type_builder_clone(get_rosidl_dynamic_type_builder())); + serialization_support_, rosidl_dynamic_type_builder); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index 42016f7cfe..00433e0df0 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -109,11 +109,12 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( rosidl_message_type_support_t * ts = nullptr; - ts = rmw_dynamic_message_typesupport_handle_init( + rmw_ret_t ret = rmw_dynamic_message_typesupport_handle_init( serialization_support->get_rosidl_serialization_support(), rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY), - &description); - if (!ts) { + &description, + &ts); + if (ret != RMW_RET_OK || !ts) { throw std::runtime_error("could not init rosidl message type support"); } if (!ts->data) { diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp index 1be0dcb671..f12a75cb8c 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp @@ -19,6 +19,7 @@ #include "rclcpp/exceptions.hpp" #include "rcutils/logging_macros.h" #include "rmw/dynamic_message_typesupport.h" +#include "rmw/ret_types.h" #include @@ -30,15 +31,16 @@ DynamicSerializationSupport::DynamicSerializationSupport( : rosidl_serialization_support_(nullptr) { rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support = nullptr; + rmw_ret_t ret = RMW_RET_ERROR; if (serialization_library_name.empty()) { - rosidl_serialization_support = rmw_get_serialization_support(NULL); + ret = rmw_get_serialization_support(NULL, &rosidl_serialization_support); } else { - rosidl_serialization_support = - rmw_get_serialization_support(serialization_library_name.c_str()); + ret = rmw_get_serialization_support( + serialization_library_name.c_str(), &rosidl_serialization_support); } - if (!rosidl_serialization_support) { + if (ret != RMW_RET_OK || !rosidl_serialization_support) { throw std::runtime_error("could not create new serialization support object"); } From 7e0d063154534b7c409226481db54e9057eb7eb3 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sat, 1 Apr 2023 05:48:08 -0700 Subject: [PATCH 19/27] Lint Signed-off-by: methylDragon --- .../include/rclcpp/dynamic_subscription.hpp | 9 ++-- .../detail/dynamic_message_impl.hpp | 5 ++- .../dynamic_message_type_builder_impl.hpp | 13 +++--- .../dynamic_typesupport/dynamic_message.hpp | 9 ++-- .../dynamic_message_type.hpp | 4 +- .../dynamic_message_type_builder.hpp | 7 +-- .../dynamic_message_type_support.hpp | 10 +++-- .../dynamic_serialization_support.hpp | 4 +- rclcpp/include/rclcpp/subscription_base.hpp | 1 - rclcpp/src/rclcpp/dynamic_subscription.cpp | 10 ++--- .../dynamic_typesupport/dynamic_message.cpp | 45 +++++++++++-------- .../dynamic_message_type.cpp | 20 +++++---- .../dynamic_message_type_builder.cpp | 22 +++++---- .../dynamic_message_type_support.cpp | 36 +++++++-------- .../dynamic_serialization_support.cpp | 8 ++-- rclcpp/src/rclcpp/executor.cpp | 8 ++-- rclcpp/src/rclcpp/generic_subscription.cpp | 12 ++--- rclcpp/src/rclcpp/subscription_base.cpp | 7 +-- .../node_interfaces/test_node_topics.cpp | 9 +++- 19 files changed, 132 insertions(+), 107 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp index 72125acca5..6db0eeb757 100644 --- a/rclcpp/include/rclcpp/dynamic_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -64,7 +64,8 @@ class DynamicSubscription : public rclcpp::SubscriptionBase node_base, *(type_support->get_rosidl_message_type_support()), topic_name, - options.to_rcl_subscription_options(qos), + options.to_rcl_subscription_options( + qos), options.event_callbacks, options.use_default_callbacks, use_take_dynamic_message ? SubscriptionType::DYNAMIC_MESSAGE_DIRECT : SubscriptionType::DYNAMIC_MESSAGE_FROM_SERIALIZED), // NOLINT @@ -159,9 +160,9 @@ class DynamicSubscription : public rclcpp::SubscriptionBase rclcpp::dynamic_typesupport::DynamicMessageTypeSupport::SharedPtr ts_; std::function - )> callback_; + rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr, + std::shared_ptr + )> callback_; rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr serialization_support_; rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr dynamic_message_; diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp index 79e04d68b3..eccdbccf4d 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp @@ -15,13 +15,14 @@ #ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_ #define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_ +#include +#include + #include #include #include #include -#include -#include #include "rclcpp/exceptions.hpp" #ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_ diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp index a0c3285fba..f28f8ce293 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp @@ -15,13 +15,14 @@ #ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_ #define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_ +#include +#include + #include #include #include #include -#include -#include #include "rclcpp/exceptions.hpp" #ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_ @@ -135,7 +136,7 @@ DynamicMessageTypeBuilder::add_member( const std::string & default_value) { throw rclcpp::exceptions::UnimplementedError( - "add_member is not implemented for input type"); + "add_member is not implemented for input type"); } @@ -147,7 +148,7 @@ DynamicMessageTypeBuilder::add_array_member( size_t array_length, const std::string & default_value) { throw rclcpp::exceptions::UnimplementedError( - "add_array_member is not implemented for input type"); + "add_array_member is not implemented for input type"); } @@ -159,7 +160,7 @@ DynamicMessageTypeBuilder::add_unbounded_sequence_member( const std::string & default_value) { throw rclcpp::exceptions::UnimplementedError( - "add_unbounded_sequence_member is not implemented for input type"); + "add_unbounded_sequence_member is not implemented for input type"); } @@ -172,7 +173,7 @@ DynamicMessageTypeBuilder::add_bounded_sequence_member( const std::string & default_value) { throw rclcpp::exceptions::UnimplementedError( - "add_bounded_sequence_member is not implemented for input type"); + "add_bounded_sequence_member is not implemented for input type"); } diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index 80e7cb4b39..b57fdabb95 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -15,6 +15,8 @@ #ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_ #define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_ +#include +#include #include #include @@ -24,9 +26,6 @@ #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" -#include -#include - namespace rclcpp { @@ -413,7 +412,9 @@ class DynamicMessage : public std::enable_shared_from_this std::shared_ptr rosidl_dynamic_data_; bool is_loaned_; - DynamicMessage::SharedPtr parent_data_; // Used for returning the loaned value, and lifetime management + + // Used for returning the loaned value, and lifetime management + DynamicMessage::SharedPtr parent_data_; private: RCLCPP_PUBLIC diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index 5a6f7d2e93..b26df70666 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -15,6 +15,8 @@ #ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_HPP_ #define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_HPP_ +#include + #include #include @@ -22,8 +24,6 @@ #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" -#include - namespace rclcpp { diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp index 74f456ac04..d88bba51d7 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp @@ -15,6 +15,8 @@ #ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_ #define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_ +#include + #include #include @@ -22,8 +24,6 @@ #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" -#include - namespace rclcpp { @@ -348,7 +348,8 @@ class DynamicMessageTypeBuilder : public std::enable_shared_from_this +#include +#include + #include #include @@ -25,9 +29,6 @@ #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" -#include -#include -#include namespace rclcpp { @@ -195,9 +196,10 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this + #include #include #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" -#include - namespace rclcpp { diff --git a/rclcpp/include/rclcpp/subscription_base.hpp b/rclcpp/include/rclcpp/subscription_base.hpp index ceb00b76e0..242bc03533 100644 --- a/rclcpp/include/rclcpp/subscription_base.hpp +++ b/rclcpp/include/rclcpp/subscription_base.hpp @@ -589,7 +589,6 @@ class SubscriptionBase : public std::enable_shared_from_this rclcpp::MessageInfo & message_info_out); // =============================================================================================== - protected: template void diff --git a/rclcpp/src/rclcpp/dynamic_subscription.cpp b/rclcpp/src/rclcpp/dynamic_subscription.cpp index badf3bdbaf..cdb87cbfea 100644 --- a/rclcpp/src/rclcpp/dynamic_subscription.cpp +++ b/rclcpp/src/rclcpp/dynamic_subscription.cpp @@ -74,33 +74,33 @@ rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr DynamicSubscription::get_shared_dynamic_message_type() { return dynamic_message_type_; -}; +} // Does not clone rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr DynamicSubscription::get_shared_dynamic_message() { return dynamic_message_; -}; +} rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr DynamicSubscription::get_shared_dynamic_serialization_support() { return serialization_support_; -}; +} rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr DynamicSubscription::create_dynamic_message() { return dynamic_message_->init_from_type_shared(*dynamic_message_type_); -}; +} void DynamicSubscription::return_dynamic_message( rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message) { message.reset(); -}; +} void DynamicSubscription::handle_dynamic_message( const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr & message, diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp index 7b8053d634..e7955fb05a 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp @@ -12,20 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include + #include #include +#include "rcl/types.h" +#include "rcutils/logging_macros.h" + #include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/exceptions.hpp" -#include "rcl/types.h" -#include "rcutils/logging_macros.h" -#include -#include -#include using rclcpp::dynamic_typesupport::DynamicMessage; using rclcpp::dynamic_typesupport::DynamicMessageType; @@ -93,8 +95,8 @@ DynamicMessage::DynamicMessage(const DynamicMessageType::SharedPtr dynamic_type) rosidl_dynamic_type, &rosidl_dynamic_data); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { throw std::runtime_error( - std::string("could not create new dynamic data object from dynamic type") + - rcl_get_error_string().str); + std::string("could not create new dynamic data object from dynamic type") + + rcl_get_error_string().str); } rosidl_dynamic_data_.reset( @@ -173,7 +175,7 @@ DynamicMessage::DynamicMessage( if (serialization_support_) { if (!match_serialization_support_(*serialization_support_, *rosidl_loaned_data)) { throw std::runtime_error( - "serialization support library identifier does not match loaned dynamic data's!"); + "serialization support library identifier does not match loaned dynamic data's!"); } } @@ -281,11 +283,14 @@ DynamicMessage::get_name() const size_t buf_length; const char * buf; if ( - rosidl_dynamic_typesupport_dynamic_data_get_name(get_rosidl_dynamic_data(), &buf, &buf_length) - != RCUTILS_RET_OK) { - throw std::runtime_error( - std::string("could not get name for dynamic data") + rcl_get_error_string().str); - } + rosidl_dynamic_typesupport_dynamic_data_get_name( + get_rosidl_dynamic_data(), &buf, + &buf_length) != + RCUTILS_RET_OK) + { + throw std::runtime_error( + std::string("could not get name for dynamic data") + rcl_get_error_string().str); + } return std::string(buf, buf_length); } @@ -402,7 +407,7 @@ DynamicMessage::clone() const get_rosidl_dynamic_data(), &rosidl_dynamic_data); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { throw std::runtime_error( - std::string("could not clone dynamic data: ") + rcl_get_error_string().str); + std::string("could not clone dynamic data: ") + rcl_get_error_string().str); } return DynamicMessage(serialization_support_, rosidl_dynamic_data); } @@ -416,7 +421,7 @@ DynamicMessage::clone_shared() const get_rosidl_dynamic_data(), &rosidl_dynamic_data); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { throw std::runtime_error( - std::string("could not clone dynamic data: ") + rcl_get_error_string().str); + std::string("could not clone dynamic data: ") + rcl_get_error_string().str); } return DynamicMessage::make_shared(serialization_support_, rosidl_dynamic_data); } @@ -472,7 +477,7 @@ DynamicMessage::loan_value(rosidl_dynamic_typesupport_member_id_t id) get_rosidl_dynamic_data(), id, &rosidl_dynamic_data); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_data) { throw std::runtime_error( - std::string("could not loan dynamic data: ") + rcl_get_error_string().str); + std::string("could not loan dynamic data: ") + rcl_get_error_string().str); } return DynamicMessage::make_shared(shared_from_this(), rosidl_dynamic_data); } @@ -552,7 +557,7 @@ DynamicMessage::serialize(rcl_serialized_message_t * buffer) rosidl_dynamic_typesupport_dynamic_data_serialize(get_rosidl_dynamic_data(), buffer, &success); if (ret != RCUTILS_RET_OK || !success) { throw std::runtime_error( - std::string("could serialize loan dynamic data: ") + rcl_get_error_string().str); + std::string("could serialize loan dynamic data: ") + rcl_get_error_string().str); } return success; } @@ -563,10 +568,12 @@ DynamicMessage::deserialize(rcl_serialized_message_t * buffer) { bool success; rcutils_ret_t ret = - rosidl_dynamic_typesupport_dynamic_data_deserialize(get_rosidl_dynamic_data(), buffer, &success); + rosidl_dynamic_typesupport_dynamic_data_deserialize( + get_rosidl_dynamic_data(), buffer, + &success); if (ret != RCUTILS_RET_OK || !success) { throw std::runtime_error( - std::string("could deserialize loan dynamic data: ") + rcl_get_error_string().str); + std::string("could deserialize loan dynamic data: ") + rcl_get_error_string().str); } return success; } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp index 54ad04c989..12719cdf5b 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp @@ -12,19 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include + #include #include +#include "rcutils/logging_macros.h" + #include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/exceptions.hpp" -#include "rcutils/logging_macros.h" -#include -#include -#include using rclcpp::dynamic_typesupport::DynamicMessage; using rclcpp::dynamic_typesupport::DynamicMessageType; @@ -192,7 +194,7 @@ DynamicMessageType::match_serialization_support_( // TODO(methylDragon): Can I do this?? Is it portable? if (serialization_support.get_rosidl_serialization_support() != - rosidl_dynamic_type.serialization_support) + rosidl_dynamic_type.serialization_support) { RCUTILS_LOG_ERROR( "serialization support pointer does not match dynamic type's"); @@ -229,7 +231,7 @@ DynamicMessageType::get_member_count() const rosidl_dynamic_type_.get(), &out); if (ret != RCUTILS_RET_OK) { throw std::runtime_error( - std::string("could not get member count: ") + rcl_get_error_string().str); + std::string("could not get member count: ") + rcl_get_error_string().str); } return out; } @@ -288,7 +290,7 @@ DynamicMessageType::clone() const get_rosidl_dynamic_type(), &rosidl_dynamic_type); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type) { throw std::runtime_error( - std::string("could not clone dynamic type: ") + rcl_get_error_string().str); + std::string("could not clone dynamic type: ") + rcl_get_error_string().str); } return DynamicMessageType(serialization_support_, rosidl_dynamic_type); } @@ -302,7 +304,7 @@ DynamicMessageType::clone_shared() const get_rosidl_dynamic_type(), &rosidl_dynamic_type); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type) { throw std::runtime_error( - std::string("could not clone dynamic type: ") + rcl_get_error_string().str); + std::string("could not clone dynamic type: ") + rcl_get_error_string().str); } return DynamicMessageType::make_shared(serialization_support_, rosidl_dynamic_type); } @@ -319,7 +321,7 @@ DynamicMessageType::equals(const DynamicMessageType & other) const get_rosidl_dynamic_type(), other.get_rosidl_dynamic_type(), &out); if (ret != RCUTILS_RET_OK) { throw std::runtime_error( - std::string("could not equate dynamic message types: ") + rcl_get_error_string().str); + std::string("could not equate dynamic message types: ") + rcl_get_error_string().str); } return out; } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp index 82712dafba..c6ec6e4305 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp @@ -12,19 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include + #include #include +#include "rcutils/logging_macros.h" + #include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/exceptions.hpp" -#include "rcutils/logging_macros.h" -#include -#include -#include using rclcpp::dynamic_typesupport::DynamicMessage; using rclcpp::dynamic_typesupport::DynamicMessageType; @@ -189,7 +191,7 @@ DynamicMessageTypeBuilder::init_from_serialization_support_( &rosidl_dynamic_type_builder); if (ret != RCUTILS_RET_OK) { throw std::runtime_error( - std::string("could not init dynamic type builder: ") + rcl_get_error_string().str); + std::string("could not init dynamic type builder: ") + rcl_get_error_string().str); } if (!rosidl_dynamic_type_builder) { throw std::runtime_error("could not init dynamic type builder object"); @@ -313,7 +315,7 @@ DynamicMessageTypeBuilder::clone() const get_rosidl_dynamic_type_builder(), &rosidl_dynamic_type_builder); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type_builder) { throw std::runtime_error( - std::string("could not clone dynamic type builder: ") + rcl_get_error_string().str); + std::string("could not clone dynamic type builder: ") + rcl_get_error_string().str); } return DynamicMessageTypeBuilder(serialization_support_, rosidl_dynamic_type_builder); } @@ -327,7 +329,7 @@ DynamicMessageTypeBuilder::clone_shared() const get_rosidl_dynamic_type_builder(), &rosidl_dynamic_type_builder); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type_builder) { throw std::runtime_error( - std::string("could not clone dynamic type builder: ") + rcl_get_error_string().str); + std::string("could not clone dynamic type builder: ") + rcl_get_error_string().str); } return DynamicMessageTypeBuilder::make_shared( serialization_support_, rosidl_dynamic_type_builder); @@ -339,7 +341,8 @@ DynamicMessageTypeBuilder::clear() { if (!serialization_support_) { throw std::runtime_error( - "cannot call clear() on a dynamic type builder with uninitialized serialization support"); + "cannot call clear() on a dynamic type builder with uninitialized serialization support" + ); } const std::string & name = get_name(); @@ -640,7 +643,8 @@ DynamicMessageTypeBuilder::add_complex_member_builder( void DynamicMessageTypeBuilder::add_complex_array_member_builder( rosidl_dynamic_typesupport_member_id_t id, const std::string & name, - DynamicMessageTypeBuilder & nested_type_builder, size_t array_length, const std::string & default_value) + DynamicMessageTypeBuilder & nested_type_builder, size_t array_length, + const std::string & default_value) { rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_array_member_builder( get_rosidl_dynamic_type_builder(), diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index 00433e0df0..0ed257efe3 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -12,28 +12,27 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include +#include +#include +#include + #include #include -#include "rmw/dynamic_message_typesupport.h" - -#include "rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp" - #include "rcl/rcl_dynamic_typesupport_c/message_introspection.h" +#include "rcutils/logging_macros.h" +#include "rmw/dynamic_message_typesupport.h" #include "rclcpp/dynamic_typesupport/dynamic_message.hpp" #include "rclcpp/dynamic_typesupport/dynamic_message_type.hpp" +#include "rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" #include "rclcpp/exceptions.hpp" #include "rclcpp/macros.hpp" #include "rclcpp/visibility_control.hpp" -#include "rcutils/logging_macros.h" -#include -#include -#include "rosidl_runtime_c/type_description_utils.h" -#include -#include using rclcpp::dynamic_typesupport::DynamicMessage; using rclcpp::dynamic_typesupport::DynamicMessageType; @@ -168,11 +167,12 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( [](rosidl_runtime_c__type_description__TypeDescription * description) -> void { rosidl_runtime_c__type_description__TypeDescription__destroy(description); }); - if (!description_) - { + if (!description_) { throw std::runtime_error("could not init type description."); } - if (!rosidl_runtime_c__type_description__TypeDescription__copy(&description, description_.get())) + if (!rosidl_runtime_c__type_description__TypeDescription__copy( + &description, + description_.get())) { throw std::runtime_error("could not copy type description."); } @@ -292,11 +292,11 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( // are managed by the passed in SharedPtr wrapper classes. We just delete it. rosidl_message_type_support_.reset( new rosidl_message_type_support_t{ - rmw_dynamic_typesupport_c__identifier, // typesupport_identifier - ts_impl, // data - get_message_typesupport_handle_function, // func - nullptr // TODO(methylDragon): Populate type hash // type_hash - }, + rmw_dynamic_typesupport_c__identifier, // typesupport_identifier + ts_impl, // data + get_message_typesupport_handle_function, // func + nullptr // TODO(methylDragon): Populate type hash // type_hash + }, [](rosidl_message_type_support_t * ts) -> void { delete static_cast(ts->data); delete ts->type_hash; // Only because we should've allocated it here diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp index f12a75cb8c..d9c22c47c7 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp @@ -12,16 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include #include -#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" -#include "rclcpp/exceptions.hpp" #include "rcutils/logging_macros.h" #include "rmw/dynamic_message_typesupport.h" #include "rmw/ret_types.h" -#include +#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" +#include "rclcpp/exceptions.hpp" + using rclcpp::dynamic_typesupport::DynamicSerializationSupport; diff --git a/rclcpp/src/rclcpp/executor.cpp b/rclcpp/src/rclcpp/executor.cpp index af5069e10e..fdb28c26bb 100644 --- a/rclcpp/src/rclcpp/executor.cpp +++ b/rclcpp/src/rclcpp/executor.cpp @@ -605,7 +605,6 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) message_info.get_rmw_message_info().from_intra_process = false; switch (subscription->get_subscription_type()) { - // Take ROS message case rclcpp::SubscriptionType::ROS_MESSAGE: { @@ -639,10 +638,9 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription) subscription->get_subscription_handle().get(), loaned_msg); if (RCL_RET_OK != ret) { RCLCPP_ERROR( - rclcpp::get_logger( - "rclcpp"), - "rcl_return_loaned_message_from_subscription() failed for subscription on topic '%s':" - " %s", + rclcpp::get_logger("rclcpp"), + "rcl_return_loaned_message_from_subscription() failed for subscription on topic " + "'%s': %s", subscription->get_topic_name(), rcl_get_error_string().str); } loaned_msg = nullptr; diff --git a/rclcpp/src/rclcpp/generic_subscription.cpp b/rclcpp/src/rclcpp/generic_subscription.cpp index 94f08cf017..6e27de81da 100644 --- a/rclcpp/src/rclcpp/generic_subscription.cpp +++ b/rclcpp/src/rclcpp/generic_subscription.cpp @@ -78,28 +78,28 @@ rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr GenericSubscription::get_shared_dynamic_message_type() { throw rclcpp::exceptions::UnimplementedError( - "get_shared_dynamic_message_type is not implemented for GenericSubscription"); + "get_shared_dynamic_message_type is not implemented for GenericSubscription"); } rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr GenericSubscription::get_shared_dynamic_message() { throw rclcpp::exceptions::UnimplementedError( - "get_shared_dynamic_message is not implemented for GenericSubscription"); + "get_shared_dynamic_message is not implemented for GenericSubscription"); } rclcpp::dynamic_typesupport::DynamicSerializationSupport::SharedPtr GenericSubscription::get_shared_dynamic_serialization_support() { throw rclcpp::exceptions::UnimplementedError( - "get_shared_dynamic_serialization_support is not implemented for GenericSubscription"); + "get_shared_dynamic_serialization_support is not implemented for GenericSubscription"); } rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr GenericSubscription::create_dynamic_message() { throw rclcpp::exceptions::UnimplementedError( - "create_dynamic_message is not implemented for GenericSubscription"); + "create_dynamic_message is not implemented for GenericSubscription"); } void @@ -108,7 +108,7 @@ GenericSubscription::return_dynamic_message( { (void) message; throw rclcpp::exceptions::UnimplementedError( - "return_dynamic_message is not implemented for GenericSubscription"); + "return_dynamic_message is not implemented for GenericSubscription"); } void @@ -119,7 +119,7 @@ GenericSubscription::handle_dynamic_message( (void) message; (void) message_info; throw rclcpp::exceptions::UnimplementedError( - "handle_dynamic_message is not implemented for GenericSubscription"); + "handle_dynamic_message is not implemented for GenericSubscription"); } } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/subscription_base.cpp b/rclcpp/src/rclcpp/subscription_base.cpp index 5d89308c4a..f9fcd5628f 100644 --- a/rclcpp/src/rclcpp/subscription_base.cpp +++ b/rclcpp/src/rclcpp/subscription_base.cpp @@ -54,11 +54,12 @@ SubscriptionBase::SubscriptionBase( type_support_(type_support_handle), subscription_type_(subscription_type) { - if (!rmw_feature_supported(RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_MESSAGE) - && subscription_type == rclcpp::SubscriptionType::DYNAMIC_MESSAGE_DIRECT) + if (!rmw_feature_supported(RMW_MIDDLEWARE_CAN_TAKE_DYNAMIC_MESSAGE) && + subscription_type == rclcpp::SubscriptionType::DYNAMIC_MESSAGE_DIRECT) { throw std::runtime_error( - "Cannot set subscription to take dynamic message directly, feature not supported in rmw"); + "Cannot set subscription to take dynamic message directly, feature not supported in rmw" + ); } auto custom_deletor = [node_handle = this->node_handle_](rcl_subscription_t * rcl_subs) diff --git a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp index 49026b14d4..e8f873f693 100644 --- a/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp +++ b/rclcpp/test/rclcpp/node_interfaces/test_node_topics.cpp @@ -85,10 +85,15 @@ class TestSubscription : public rclcpp::SubscriptionBase DynamicMessageType::SharedPtr get_shared_dynamic_message_type() override {return nullptr;} DynamicMessage::SharedPtr get_shared_dynamic_message() override {return nullptr;} - DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() override {return nullptr;} + DynamicSerializationSupport::SharedPtr get_shared_dynamic_serialization_support() override + { + return nullptr; + } DynamicMessage::SharedPtr create_dynamic_message() override {return nullptr;} void return_dynamic_message(DynamicMessage::SharedPtr &) override {} - void handle_dynamic_message(const DynamicMessage::SharedPtr &, const rclcpp::MessageInfo &) override {} + void handle_dynamic_message( + const DynamicMessage::SharedPtr &, + const rclcpp::MessageInfo &) override {} }; class TestNodeTopics : public ::testing::Test From 8571b2866448346a29e9187f84e12811c8f24230 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sat, 1 Apr 2023 19:26:41 -0700 Subject: [PATCH 20/27] Support type hashes Signed-off-by: methylDragon --- .../dynamic_message_type_support.cpp | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index 0ed257efe3..f3430d519e 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -22,6 +22,8 @@ #include #include "rcl/rcl_dynamic_typesupport_c/message_introspection.h" +#include "rcl/type_hash.h" +#include "rcl/types.h" #include "rcutils/logging_macros.h" #include "rmw/dynamic_message_typesupport.h" @@ -108,10 +110,20 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( rosidl_message_type_support_t * ts = nullptr; + auto type_hash = std::make_unique(); + rcutils_ret_t hash_ret = rcl_calculate_type_hash( + // TODO(methylDragon): Swap this out with the conversion function when it is ready + reinterpret_cast(&description), + type_hash.get()); + if (hash_ret != RCL_RET_OK || !type_hash) { + throw std::runtime_error("failed to get type hash"); + } + rmw_ret_t ret = rmw_dynamic_message_typesupport_handle_init( serialization_support->get_rosidl_serialization_support(), rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY), &description, + type_hash.get(), &ts); if (ret != RMW_RET_OK || !ts) { throw std::runtime_error("could not init rosidl message type support"); @@ -137,6 +149,8 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( if (!rosidl_message_type_support_) { throw std::runtime_error("could not init rosidl message type support."); } + + type_hash.release(); } @@ -263,15 +277,14 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( DynamicMessage::SharedPtr dynamic_message, rosidl_runtime_c__type_description__TypeDescription * description) { - bool middleware_supports_type_discovery = - rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY); + bool middleware_supports_type_discovery = rmw_feature_supported( + RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY); if (!middleware_supports_type_discovery && !description) { - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, - "Middleware does not support type discovery! Deferred dynamic type" - "message type support will never be populated! You must provide a type " - "description."); + throw std::runtime_error( + "Middleware does not support type discovery! Deferred dynamic type" + "message type support will never be populated! You must provide a type " + "description."); return; } @@ -282,12 +295,19 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( dynamic_message->get_rosidl_dynamic_data() // dynamic_message }; if (!ts_impl) { - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, - "Could not allocate rmw_dynamic_message_typesupport_impl_t struct"); + throw std::runtime_error("Could not allocate rmw_dynamic_message_typesupport_impl_t struct"); return; } + auto type_hash = std::make_unique(); + rcutils_ret_t hash_ret = rcl_calculate_type_hash( + // TODO(methylDragon): Swap this out with the conversion function when it is ready + reinterpret_cast(description), + type_hash.get()); + if (hash_ret != RCL_RET_OK || !type_hash) { + throw std::runtime_error("failed to get type hash"); + } + // NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members // are managed by the passed in SharedPtr wrapper classes. We just delete it. rosidl_message_type_support_.reset( @@ -295,7 +315,7 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( rmw_dynamic_typesupport_c__identifier, // typesupport_identifier ts_impl, // data get_message_typesupport_handle_function, // func - nullptr // TODO(methylDragon): Populate type hash // type_hash + type_hash.get() // type_hash }, [](rosidl_message_type_support_t * ts) -> void { delete static_cast(ts->data); @@ -304,12 +324,12 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( ); if (!rosidl_message_type_support_) { - RCUTILS_LOG_ERROR_NAMED( - rmw_dynamic_typesupport_c__identifier, - "Could not allocate rosidl_message_type_support_t struct"); + throw std::runtime_error("Could not allocate rosidl_message_type_support_t struct"); delete ts_impl; return; } + + type_hash.release(); } From e7e9a298c0fd862eb85e0eee31ab1e7890c2184c Mon Sep 17 00:00:00 2001 From: methylDragon Date: Sun, 2 Apr 2023 03:14:29 -0700 Subject: [PATCH 21/27] Add initializers for description and source getters Signed-off-by: methylDragon --- .../dynamic_message_type_support.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index f3430d519e..ee67d396cd 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -315,7 +315,17 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( rmw_dynamic_typesupport_c__identifier, // typesupport_identifier ts_impl, // data get_message_typesupport_handle_function, // func - type_hash.get() // type_hash + type_hash.get(), // type_hash + // get_type_description_func + // TODO(methylDragon): Await altering of function signature to return description + []() -> const rosidl_runtime_c__type_description__TypeDescription * { + return nullptr; + }, + // get_type_description_sources_func + []() -> const rosidl_runtime_c__type_description__TypeSource__Sequence * { + static const rosidl_runtime_c__type_description__TypeSource__Sequence sources = {NULL, 0, 0}; + return &sources; + } }, [](rosidl_message_type_support_t * ts) -> void { delete static_cast(ts->data); From ca17caf6c483f51ee022c7f546113d198746c3c9 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Mon, 3 Apr 2023 15:06:51 -0700 Subject: [PATCH 22/27] Support type hashes Signed-off-by: methylDragon --- .../dynamic_message_type.hpp | 2 +- .../dynamic_message_type_builder.hpp | 2 +- .../dynamic_message_type_support.hpp | 8 +-- .../dynamic_message_type_support.cpp | 70 +++++++++---------- .../dynamic_serialization_support.cpp | 2 +- 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index b26df70666..291f74e588 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -52,7 +52,7 @@ class DynamicMessageTypeBuilder; * rosidl_dynamic_typesupport_dynamic_type_builder_t. * * The usual method of obtaining a DynamicMessageType is through construction of - * rosidl_message_type_support_t via rcl_dynamic_message_typesupport_handle_init(), then + * rosidl_message_type_support_t via rcl_dynamic_message_type_support_handle_init(), then * taking ownership of its contents. But DynamicMessageTypeBuilder can also be used to obtain * DynamicMessageType by constructing it bottom-up instead, since it exposes the lower_level * rosidl methods. diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp index d88bba51d7..b14d3d0b5b 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp @@ -50,7 +50,7 @@ class DynamicMessageType; * facilitating the construction of dynamic types bottom-up in the C++ layer. * * The usual method of obtaining a DynamicMessageType is through construction of - * rosidl_message_type_support_t via rcl_dynamic_message_typesupport_handle_init(), then taking + * rosidl_message_type_support_t via rcl_dynamic_message_type_support_handle_init(), then taking * ownership of its contents. But DynamicMessageTypeBuilder can also be used to obtain * DynamicMessageType by constructing it bottom-up instead, since it exposes the lower_level * rosidl methods. diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp index 1450acac01..327f30965d 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -40,10 +40,10 @@ namespace dynamic_typesupport /** * * NOTE: This class is the recommended way to obtain the dynamic message type - * support struct, instead of rcl_dynamic_message_typesupport_handle_init, + * support struct, instead of rcl_dynamic_message_type_support_handle_init, * because this class will manage the lifetimes for you. * - * Do NOT call rcl_dynamic_message_typesupport_handle_fini!! + * Do NOT call rcl_dynamic_message_type_support_handle_fini!! * * This class: * - Manages the lifetime of the raw pointer. @@ -63,7 +63,7 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this(ts->data); + auto ts_impl = static_cast(ts->data); manage_rosidl_message_type_support_(ts); - manage_description_(ts_impl->description); + manage_description_(ts_impl->type_description); serialization_support_ = DynamicSerializationSupport::make_shared(ts_impl->serialization_support); dynamic_message_type_ = DynamicMessageType::make_shared( @@ -119,11 +119,12 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( throw std::runtime_error("failed to get type hash"); } - rmw_ret_t ret = rmw_dynamic_message_typesupport_handle_init( + rmw_ret_t ret = rmw_dynamic_message_type_support_handle_init( serialization_support->get_rosidl_serialization_support(), rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY), - &description, - type_hash.get(), + type_hash.get(), // type_hash + &description, // type_description + nullptr, // type_description_sources (not implemented for dynamic types) &ts); if (ret != RMW_RET_OK || !ts) { throw std::runtime_error("could not init rosidl message type support"); @@ -135,10 +136,10 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( throw std::runtime_error("rosidl message type support is of the wrong type"); } - auto ts_impl = static_cast(ts->data); + auto ts_impl = static_cast(ts->data); manage_rosidl_message_type_support_(ts); - manage_description_(ts_impl->description); + manage_description_(ts_impl->type_description); dynamic_message_type_ = DynamicMessageType::make_shared( get_shared_dynamic_serialization_support(), ts_impl->dynamic_message_type); @@ -245,8 +246,9 @@ DynamicMessageTypeSupport::manage_rosidl_message_type_support_( rosidl_message_type_support_.reset( rosidl_message_type_support, [](rosidl_message_type_support_t * ts) -> void { - delete static_cast(ts->data); - delete ts->type_hash; // Only because we should've allocated it here + auto ts_impl = static_cast(ts->data); + delete ts_impl->type_hash; // Only because we should've allocated it here + delete ts_impl; delete ts; } ); @@ -268,7 +270,7 @@ DynamicMessageTypeSupport::manage_description_( } -// NOTE(methylDragon): This looks like rmw_dynamic_message_typesupport_handle_init, but instead +// NOTE(methylDragon): This looks like rmw_dynamic_message_type_support_handle_init, but instead // just aggregates already initialized objects void DynamicMessageTypeSupport::init_rosidl_message_type_support_( @@ -288,17 +290,6 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( return; } - rmw_dynamic_message_typesupport_impl_t * ts_impl = new rmw_dynamic_message_typesupport_impl_t{ - description, // description - serialization_support->get_rosidl_serialization_support(), // serialization_support - dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_message_type - dynamic_message->get_rosidl_dynamic_data() // dynamic_message - }; - if (!ts_impl) { - throw std::runtime_error("Could not allocate rmw_dynamic_message_typesupport_impl_t struct"); - return; - } - auto type_hash = std::make_unique(); rcutils_ret_t hash_ret = rcl_calculate_type_hash( // TODO(methylDragon): Swap this out with the conversion function when it is ready @@ -308,6 +299,19 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( throw std::runtime_error("failed to get type hash"); } + rmw_dynamic_message_type_support_impl_t * ts_impl = new rmw_dynamic_message_type_support_impl_t{ + type_hash.get(), // type_hash + description, // type_description + nullptr, // NOTE(methylDragon): Not supported for now // type_description_sources + serialization_support->get_rosidl_serialization_support(), // serialization_support + dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_message_type + dynamic_message->get_rosidl_dynamic_data() // dynamic_message + }; + if (!ts_impl) { + throw std::runtime_error("Could not allocate rmw_dynamic_message_type_support_impl_t struct"); + return; + } + // NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members // are managed by the passed in SharedPtr wrapper classes. We just delete it. rosidl_message_type_support_.reset( @@ -315,21 +319,17 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( rmw_dynamic_typesupport_c__identifier, // typesupport_identifier ts_impl, // data get_message_typesupport_handle_function, // func - type_hash.get(), // type_hash + // get_type_hash_func + rmw_dynamic_message_type_support_get_type_hash_function, // get_type_description_func - // TODO(methylDragon): Await altering of function signature to return description - []() -> const rosidl_runtime_c__type_description__TypeDescription * { - return nullptr; - }, + rmw_dynamic_message_type_support_get_type_description_function, // get_type_description_sources_func - []() -> const rosidl_runtime_c__type_description__TypeSource__Sequence * { - static const rosidl_runtime_c__type_description__TypeSource__Sequence sources = {NULL, 0, 0}; - return &sources; - } + rmw_dynamic_message_type_support_get_type_description_sources_function }, [](rosidl_message_type_support_t * ts) -> void { - delete static_cast(ts->data); - delete ts->type_hash; // Only because we should've allocated it here + auto ts_impl = static_cast(ts->data); + delete ts_impl->type_hash; // Only because we should've allocated it here + delete ts_impl; } ); diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp index d9c22c47c7..e887a3a46d 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp @@ -18,7 +18,7 @@ #include #include "rcutils/logging_macros.h" -#include "rmw/dynamic_message_typesupport.h" +#include "rmw/dynamic_message_type_support.h" #include "rmw/ret_types.h" #include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp" From 000f788b65c5bb8917a78cb4deba2f7f9ca147d7 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Mon, 3 Apr 2023 17:01:03 -0700 Subject: [PATCH 23/27] Use dynamic typesupport identifier getter Signed-off-by: methylDragon --- rclcpp/include/rclcpp/dynamic_subscription.hpp | 2 +- .../dynamic_message_type_support.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp index 6db0eeb757..34b05e9050 100644 --- a/rclcpp/include/rclcpp/dynamic_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -80,7 +80,7 @@ class DynamicSubscription : public rclcpp::SubscriptionBase } if (type_support->get_rosidl_message_type_support()->typesupport_identifier != - rmw_dynamic_typesupport_c__identifier) + rmw_get_dynamic_typesupport_identifier()) { throw std::runtime_error( "DynamicSubscription must use dynamic type introspection type support!"); diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index 9c75345812..de8f63875c 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -21,7 +21,7 @@ #include #include -#include "rcl/rcl_dynamic_typesupport_c/message_introspection.h" +#include "rcl/dynamic_message_type_support.h" #include "rcl/type_hash.h" #include "rcl/types.h" #include "rcutils/logging_macros.h" @@ -70,7 +70,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( if (!ts->data) { throw std::runtime_error("could not init rosidl message type support impl"); } - if (ts->typesupport_identifier != rmw_dynamic_typesupport_c__identifier) { + if (ts->typesupport_identifier != rmw_get_dynamic_typesupport_identifier()) { throw std::runtime_error("rosidl message type support is of the wrong type"); } @@ -132,7 +132,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( if (!ts->data) { throw std::runtime_error("could not init rosidl message type support impl"); } - if (ts->typesupport_identifier != rmw_dynamic_typesupport_c__identifier) { + if (ts->typesupport_identifier != rmw_get_dynamic_typesupport_identifier()) { throw std::runtime_error("rosidl message type support is of the wrong type"); } @@ -316,10 +316,10 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( // are managed by the passed in SharedPtr wrapper classes. We just delete it. rosidl_message_type_support_.reset( new rosidl_message_type_support_t{ - rmw_dynamic_typesupport_c__identifier, // typesupport_identifier + rmw_get_dynamic_typesupport_identifier(), // typesupport_identifier ts_impl, // data get_message_typesupport_handle_function, // func - // get_type_hash_func + // get_type_hash_func rmw_dynamic_message_type_support_get_type_hash_function, // get_type_description_func rmw_dynamic_message_type_support_get_type_description_function, From 29577dab24d463629ad8bcdb503b23a0ba49de1e Mon Sep 17 00:00:00 2001 From: methylDragon Date: Tue, 4 Apr 2023 05:09:37 -0700 Subject: [PATCH 24/27] Move dynamic type support struct to rosidl and fix mem issues Signed-off-by: methylDragon --- .../dynamic_message_type_support.hpp | 6 +- .../dynamic_serialization_support.hpp | 9 +- .../dynamic_typesupport/dynamic_message.cpp | 9 +- .../dynamic_message_type.cpp | 9 +- .../dynamic_message_type_builder.cpp | 9 +- .../dynamic_message_type_support.cpp | 84 +++++++++++-------- .../dynamic_serialization_support.cpp | 3 + 7 files changed, 66 insertions(+), 63 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp index 327f30965d..2fa222e068 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -43,7 +43,7 @@ namespace dynamic_typesupport * support struct, instead of rcl_dynamic_message_type_support_handle_init, * because this class will manage the lifetimes for you. * - * Do NOT call rcl_dynamic_message_type_support_handle_fini!! + * Do NOT call rcl_dynamic_message_type_support_handle_destroy!! * * This class: * - Manages the lifetime of the raw pointer. @@ -178,10 +178,6 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this rosidl_serialization_support_; - -private: - RCLCPP_PUBLIC - DynamicSerializationSupport(); }; diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp index e7955fb05a..4b2b601317 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message.cpp @@ -68,8 +68,7 @@ DynamicMessage::DynamicMessage(const DynamicMessageTypeBuilder::SharedPtr dynami rosidl_dynamic_data, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { - rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); - delete rosidl_dynamic_data; + rosidl_dynamic_typesupport_dynamic_data_destroy(rosidl_dynamic_data); }); } @@ -103,8 +102,7 @@ DynamicMessage::DynamicMessage(const DynamicMessageType::SharedPtr dynamic_type) rosidl_dynamic_data, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { - rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); - delete rosidl_dynamic_data; + rosidl_dynamic_typesupport_dynamic_data_destroy(rosidl_dynamic_data); }); } @@ -131,8 +129,7 @@ DynamicMessage::DynamicMessage( rosidl_dynamic_data, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_data_t * rosidl_dynamic_data)->void { - rosidl_dynamic_typesupport_dynamic_data_fini(rosidl_dynamic_data); - delete rosidl_dynamic_data; + rosidl_dynamic_typesupport_dynamic_data_destroy(rosidl_dynamic_data); }); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp index 12719cdf5b..8cb299f054 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp @@ -60,8 +60,7 @@ DynamicMessageType::DynamicMessageType(DynamicMessageTypeBuilder::SharedPtr dyna rosidl_dynamic_type, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { - rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); - delete rosidl_dynamic_type; + rosidl_dynamic_typesupport_dynamic_type_destroy(rosidl_dynamic_type); }); } @@ -85,8 +84,7 @@ DynamicMessageType::DynamicMessageType( rosidl_dynamic_type, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { - rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); - delete rosidl_dynamic_type; + rosidl_dynamic_typesupport_dynamic_type_destroy(rosidl_dynamic_type); }); } @@ -171,8 +169,7 @@ DynamicMessageType::init_from_description( rosidl_dynamic_type, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_t * rosidl_dynamic_type)->void { - rosidl_dynamic_typesupport_dynamic_type_fini(rosidl_dynamic_type); - delete rosidl_dynamic_type; + rosidl_dynamic_typesupport_dynamic_type_destroy(rosidl_dynamic_type); }); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp index c6ec6e4305..ecdec0b453 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp @@ -72,8 +72,7 @@ DynamicMessageTypeBuilder::DynamicMessageTypeBuilder( rosidl_dynamic_type_builder, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { - rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); - delete rosidl_dynamic_type_builder; + rosidl_dynamic_typesupport_dynamic_type_builder_destroy(rosidl_dynamic_type_builder); }); } @@ -165,8 +164,7 @@ DynamicMessageTypeBuilder::init_from_description( rosidl_dynamic_type_builder, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { - rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); - delete rosidl_dynamic_type_builder; + rosidl_dynamic_typesupport_dynamic_type_builder_destroy(rosidl_dynamic_type_builder); }); } @@ -201,8 +199,7 @@ DynamicMessageTypeBuilder::init_from_serialization_support_( rosidl_dynamic_type_builder, // Custom deleter [](rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder)->void { - rosidl_dynamic_typesupport_dynamic_type_builder_fini(rosidl_dynamic_type_builder); - delete rosidl_dynamic_type_builder; + rosidl_dynamic_typesupport_dynamic_type_builder_destroy(rosidl_dynamic_type_builder); }); } diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index de8f63875c..cc558297d8 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -21,6 +21,7 @@ #include #include +#include "rcl/allocator.h" #include "rcl/dynamic_message_type_support.h" #include "rcl/type_hash.h" #include "rcl/types.h" @@ -76,9 +77,24 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( // NOTE(methylDragon): Not technically const correct, but since it's a const void *, // we do it anyway... - auto ts_impl = static_cast(ts->data); + auto ts_impl = static_cast(ts->data); + + // NOTE(methylDragon): We don't destroy the rosidl_message_type_support->data since its members + // are managed by the passed in SharedPtr wrapper classes. We just delete it. + rosidl_message_type_support_.reset( + ts, + [](rosidl_message_type_support_t * ts) -> void { + auto ts_impl = static_cast(ts->data); + auto allocator = rcl_get_default_allocator(); + + // These are all C allocated + allocator.deallocate(ts_impl->type_hash, &allocator.state); + allocator.deallocate( + const_cast(ts_impl), &allocator.state); + allocator.deallocate(ts, &allocator.state); + } + ); - manage_rosidl_message_type_support_(ts); manage_description_(ts_impl->type_description); serialization_support_ = DynamicSerializationSupport::make_shared(ts_impl->serialization_support); @@ -136,9 +152,21 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( throw std::runtime_error("rosidl message type support is of the wrong type"); } - auto ts_impl = static_cast(ts->data); + auto ts_impl = static_cast(ts->data); + + // NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members + // are managed by the passed in SharedPtr wrapper classes. We just delete it. + rosidl_message_type_support_.reset( + ts, + [](rosidl_message_type_support_t * ts) -> void { + auto ts_impl = static_cast(ts->data); - manage_rosidl_message_type_support_(ts); + // These are allocated with new + delete ts_impl->type_hash; // Only because we should've allocated it here + delete ts_impl; + delete ts; + } + ); manage_description_(ts_impl->type_description); dynamic_message_type_ = DynamicMessageType::make_shared( @@ -237,24 +265,6 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( DynamicMessageTypeSupport::~DynamicMessageTypeSupport() {} -void -DynamicMessageTypeSupport::manage_rosidl_message_type_support_( - rosidl_message_type_support_t * rosidl_message_type_support) -{ - // NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members - // are managed by the passed in SharedPtr wrapper classes. We just delete it. - rosidl_message_type_support_.reset( - rosidl_message_type_support, - [](rosidl_message_type_support_t * ts) -> void { - auto ts_impl = static_cast(ts->data); - delete ts_impl->type_hash; // Only because we should've allocated it here - delete ts_impl; - delete ts; - } - ); -} - - void DynamicMessageTypeSupport::manage_description_( rosidl_runtime_c__type_description__TypeDescription * description) @@ -299,16 +309,18 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( throw std::runtime_error("failed to get type hash"); } - rmw_dynamic_message_type_support_impl_t * ts_impl = new rmw_dynamic_message_type_support_impl_t{ - type_hash.get(), // type_hash - description, // type_description - nullptr, // NOTE(methylDragon): Not supported for now // type_description_sources - serialization_support->get_rosidl_serialization_support(), // serialization_support - dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_message_type - dynamic_message->get_rosidl_dynamic_data() // dynamic_message + rosidl_dynamic_message_type_support_impl_t * ts_impl = + new rosidl_dynamic_message_type_support_impl_t { + type_hash.get(), // type_hash + description, // type_description + nullptr, // NOTE(methylDragon): Not supported for now // type_description_sources + serialization_support->get_rosidl_serialization_support(), // serialization_support + dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_message_type + dynamic_message->get_rosidl_dynamic_data() // dynamic_message }; if (!ts_impl) { - throw std::runtime_error("Could not allocate rmw_dynamic_message_type_support_impl_t struct"); + throw std::runtime_error( + "Could not allocate rosidl_dynamic_message_type_support_impl_t struct"); return; } @@ -320,15 +332,17 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( ts_impl, // data get_message_typesupport_handle_function, // func // get_type_hash_func - rmw_dynamic_message_type_support_get_type_hash_function, + rosidl_get_dynamic_message_type_support_type_hash_function, // get_type_description_func - rmw_dynamic_message_type_support_get_type_description_function, + rosidl_get_dynamic_message_type_support_type_description_function, // get_type_description_sources_func - rmw_dynamic_message_type_support_get_type_description_sources_function + rosidl_get_dynamic_message_type_support_type_description_sources_function }, [](rosidl_message_type_support_t * ts) -> void { - auto ts_impl = static_cast(ts->data); - delete ts_impl->type_hash; // Only because we should've allocated it here + auto ts_impl = static_cast(ts->data); + auto allocator = rcl_get_default_allocator(); + // Only because we should've allocated it here (also it's C allocated) + allocator.deallocate(ts_impl->type_hash, &allocator.state); delete ts_impl; } ); diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp index e887a3a46d..72a163daa2 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp @@ -28,6 +28,9 @@ using rclcpp::dynamic_typesupport::DynamicSerializationSupport; // CONSTRUCTION ==================================================================================== +DynamicSerializationSupport::DynamicSerializationSupport() +: DynamicSerializationSupport::DynamicSerializationSupport("") {}; + DynamicSerializationSupport::DynamicSerializationSupport( const std::string & serialization_library_name) : rosidl_serialization_support_(nullptr) From d871af007af0121cedf6e8b48a5fff5da1b9fabe Mon Sep 17 00:00:00 2001 From: methylDragon Date: Thu, 6 Apr 2023 21:13:58 -0700 Subject: [PATCH 25/27] Use create instead of init Signed-off-by: methylDragon --- .../dynamic_message_type.hpp | 37 ++++++++++--------- .../dynamic_message_type_builder.hpp | 31 ++++++++-------- .../dynamic_message_type_support.hpp | 10 ++--- .../dynamic_typesupport/dynamic_message.cpp | 8 ++-- .../dynamic_message_type.cpp | 4 +- .../dynamic_message_type_builder.cpp | 6 +-- .../dynamic_message_type_support.cpp | 10 ++--- .../dynamic_serialization_support.cpp | 2 +- 8 files changed, 55 insertions(+), 53 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp index 291f74e588..316a17fa71 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type.hpp @@ -34,7 +34,7 @@ namespace dynamic_typesupport class DynamicMessage; class DynamicMessageTypeBuilder; -/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_type_t * +/// Utility wrapper class for `rosidl_dynamic_typesupport_dynamic_type_t *` /** * This class: * - Manages the lifetime of the raw pointer. @@ -42,20 +42,21 @@ class DynamicMessageTypeBuilder; * - Exposes the underlying serialization support API * * Ownership: - * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed - * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. - * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer - * must point to the same location in memory as the stored raw pointer! + * - This class borrows the `rosidl_dynamic_typesupport_serialization_support_t` stored in the + * passed `DynamicSerializationSupport`. + * So it cannot outlive the `DynamicSerializationSupport`. + * - The `DynamicSerializationSupport`'s `rosidl_dynamic_typesupport_serialization_support_t` + * pointer must point to the same location in memory as the stored raw pointer! * - * Note: This class is meant to map to the lower level rosidl_dynamic_typesupport_dynamic_type_t, - * which can be constructed via DynamicMessageTypeBuilder, which maps to - * rosidl_dynamic_typesupport_dynamic_type_builder_t. + * This class is meant to map to the lower level `rosidl_dynamic_typesupport_dynamic_type_t`, + * which can be constructed via `DynamicMessageTypeBuilder`, which maps to + * `rosidl_dynamic_typesupport_dynamic_type_builder_t`. * - * The usual method of obtaining a DynamicMessageType is through construction of - * rosidl_message_type_support_t via rcl_dynamic_message_type_support_handle_init(), then - * taking ownership of its contents. But DynamicMessageTypeBuilder can also be used to obtain - * DynamicMessageType by constructing it bottom-up instead, since it exposes the lower_level - * rosidl methods. + * The usual method of obtaining a `DynamicMessageType` is through construction of + * `rosidl_message_type_support_t` via `rcl_dynamic_message_type_support_handle_create()`, then + * taking ownership of its contents. But `DynamicMessageTypeBuilder` can also be used to obtain + * `DynamicMessageType` by constructing it bottom-up instead, since it exposes the lower_level + * rosidl methods. */ class DynamicMessageType : public std::enable_shared_from_this { @@ -63,14 +64,14 @@ class DynamicMessageType : public std::enable_shared_from_this dynamic_type_builder); @@ -111,7 +112,7 @@ class DynamicMessageType : public std::enable_shared_from_this rosidl_dynamic_type_; diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp index b14d3d0b5b..d25382e98c 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp @@ -33,7 +33,7 @@ namespace dynamic_typesupport class DynamicMessage; class DynamicMessageType; -/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_type_builder_t * +/// Utility wrapper class for `rosidl_dynamic_typesupport_dynamic_type_builder_t *` /** * This class: * - Manages the lifetime of the raw pointer. @@ -42,18 +42,19 @@ class DynamicMessageType; * * Ownership: * - This class borrows the rosidl_dynamic_typesupport_serialization_support_t stored in the passed - * DynamicSerializationSupport. So it cannot outlive the DynamicSerializationSupport. - * - The DynamicSerializationSupport's rosidl_dynamic_typesupport_serialization_support_t pointer - * must point to the same location in memory as the stored raw pointer! + * `DynamicSerializationSupport`. + * So it cannot outlive the `DynamicSerializationSupport`. + * - The `DynamicSerializationSupport`'s `rosidl_dynamic_typesupport_serialization_support_t` + * pointer must point to the same location in memory as the stored raw pointer! * - * Note: This class is meant to map to rosidl_dynamic_typesupport_dynamic_type_builder_t, - * facilitating the construction of dynamic types bottom-up in the C++ layer. + * This class is meant to map to rosidl_dynamic_typesupport_dynamic_type_builder_t, facilitating the + * construction of dynamic types bottom-up in the C++ layer. * - * The usual method of obtaining a DynamicMessageType is through construction of - * rosidl_message_type_support_t via rcl_dynamic_message_type_support_handle_init(), then taking - * ownership of its contents. But DynamicMessageTypeBuilder can also be used to obtain - * DynamicMessageType by constructing it bottom-up instead, since it exposes the lower_level - * rosidl methods. + * The usual method of obtaining a `DynamicMessageType` is through construction of + * `rosidl_message_type_support_t` via `rcl_dynamic_message_type_support_handle_create()`, then + * taking ownership of its contents. + * But `DynamicMessageTypeBuilder` can also be used to obtain `DynamicMessageType` by constructing + * it bottom-up instead, since it exposes the lower_level rosidl methods. */ class DynamicMessageTypeBuilder : public std::enable_shared_from_this { @@ -61,14 +62,14 @@ class DynamicMessageTypeBuilder : public std::enable_shared_from_this rosidl_dynamic_type_builder_; diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp index 2fa222e068..52dfde8c6c 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -35,12 +35,12 @@ namespace rclcpp namespace dynamic_typesupport { -/// Utility wrapper class for rosidl_message_type_support_t * containing managed +/// Utility wrapper class for `rosidl_message_type_support_t *` containing managed /// instances of the typesupport handle impl. /** * * NOTE: This class is the recommended way to obtain the dynamic message type - * support struct, instead of rcl_dynamic_message_type_support_handle_init, + * support struct, instead of `rcl_dynamic_message_type_support_handle_create()`, * because this class will manage the lifetimes for you. * * Do NOT call rcl_dynamic_message_type_support_handle_destroy!! @@ -52,7 +52,7 @@ namespace dynamic_typesupport * serialization support API * * Ownership: - * - This class, similarly to the rosidl_dynamic_typesupport_serialization_support_t, must outlive + * - This class, similarly to the `rosidl_dynamic_typesupport_serialization_support_t`, must outlive * all downstream usages of the serialization support. */ class DynamicMessageTypeSupport : public std::enable_shared_from_this @@ -63,7 +63,7 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_thisget_rosidl_serialization_support(), &description, &rosidl_dynamic_type); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type) { throw std::runtime_error("could not create new dynamic type object"); diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp index ecdec0b453..37ed9964d3 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp @@ -40,7 +40,7 @@ using rclcpp::dynamic_typesupport::DynamicSerializationSupport; #endif -// CONSTRUCTION ================================================================================== +// CONSTRUCTION ==================================================================================== DynamicMessageTypeBuilder::DynamicMessageTypeBuilder( DynamicSerializationSupport::SharedPtr serialization_support, const std::string & name) : serialization_support_(serialization_support), rosidl_dynamic_type_builder_(nullptr) @@ -153,7 +153,7 @@ DynamicMessageTypeBuilder::init_from_description( } rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; - rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_init_from_description( + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_create_from_description( serialization_support_->get_rosidl_serialization_support(), &description, &rosidl_dynamic_type_builder); if (ret != RCUTILS_RET_OK || !rosidl_dynamic_type_builder) { @@ -183,7 +183,7 @@ DynamicMessageTypeBuilder::init_from_serialization_support_( rosidl_dynamic_typesupport_dynamic_type_builder_t * rosidl_dynamic_type_builder = nullptr; - rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_init( + rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_create( serialization_support->get_rosidl_serialization_support(), name.c_str(), name.size(), &rosidl_dynamic_type_builder); diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp index cc558297d8..76a438da83 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp @@ -57,9 +57,9 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( rcl_ret_t ret; if (serialization_library_name.empty()) { - ret = rcl_dynamic_message_type_support_handle_init(nullptr, &description, &ts); + ret = rcl_dynamic_message_type_support_handle_create(nullptr, &description, &ts); } else { - ret = rcl_dynamic_message_type_support_handle_init( + ret = rcl_dynamic_message_type_support_handle_create( serialization_library_name.c_str(), &description, &ts); } if (ret != RCL_RET_OK) { @@ -135,7 +135,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( throw std::runtime_error("failed to get type hash"); } - rmw_ret_t ret = rmw_dynamic_message_type_support_handle_init( + rmw_ret_t ret = rmw_dynamic_message_type_support_handle_create( serialization_support->get_rosidl_serialization_support(), rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY), type_hash.get(), // type_hash @@ -280,8 +280,8 @@ DynamicMessageTypeSupport::manage_description_( } -// NOTE(methylDragon): This looks like rmw_dynamic_message_type_support_handle_init, but instead -// just aggregates already initialized objects +// This looks like rmw_`dynamic_message_type_support_handle_create()`, but instead just aggregates +// already initialized objects void DynamicMessageTypeSupport::init_rosidl_message_type_support_( DynamicSerializationSupport::SharedPtr serialization_support, diff --git a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp index 72a163daa2..8ba07a078c 100644 --- a/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp +++ b/rclcpp/src/rclcpp/dynamic_typesupport/dynamic_serialization_support.cpp @@ -29,7 +29,7 @@ using rclcpp::dynamic_typesupport::DynamicSerializationSupport; // CONSTRUCTION ==================================================================================== DynamicSerializationSupport::DynamicSerializationSupport() -: DynamicSerializationSupport::DynamicSerializationSupport("") {}; +: DynamicSerializationSupport::DynamicSerializationSupport("") {} DynamicSerializationSupport::DynamicSerializationSupport( const std::string & serialization_library_name) From 30210a2c024204888606656b0d759002313f3857 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Fri, 7 Apr 2023 15:43:56 -0700 Subject: [PATCH 26/27] Remove print methods Signed-off-by: methylDragon --- .../rclcpp/dynamic_typesupport/dynamic_message.hpp | 4 ---- .../dynamic_message_type_support.hpp | 6 ------ .../rclcpp/dynamic_typesupport/dynamic_message.cpp | 7 ------- .../dynamic_message_type_support.cpp | 11 ----------- 4 files changed, 28 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp index b57fdabb95..4b137d71ec 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message.hpp @@ -230,10 +230,6 @@ class DynamicMessage : public std::enable_shared_from_this void remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index); - RCLCPP_PUBLIC - void - print() const; - RCLCPP_PUBLIC bool serialize(rcl_serialized_message_t * buffer); diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp index 52dfde8c6c..27cfdf43c7 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -158,12 +158,6 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this Date: Fri, 7 Apr 2023 18:03:46 -0700 Subject: [PATCH 27/27] Remove RMW interfaces Signed-off-by: methylDragon --- rclcpp/include/rclcpp/dynamic_subscription.hpp | 4 +++- .../dynamic_message_type_support.hpp | 4 +++- .../dynamic_message_type_support.cpp | 14 ++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/rclcpp/include/rclcpp/dynamic_subscription.hpp b/rclcpp/include/rclcpp/dynamic_subscription.hpp index 34b05e9050..07f6cb90ef 100644 --- a/rclcpp/include/rclcpp/dynamic_subscription.hpp +++ b/rclcpp/include/rclcpp/dynamic_subscription.hpp @@ -15,6 +15,8 @@ #ifndef RCLCPP__DYNAMIC_SUBSCRIPTION_HPP_ #define RCLCPP__DYNAMIC_SUBSCRIPTION_HPP_ +#include + #include #include #include @@ -80,7 +82,7 @@ class DynamicSubscription : public rclcpp::SubscriptionBase } if (type_support->get_rosidl_message_type_support()->typesupport_identifier != - rmw_get_dynamic_typesupport_identifier()) + rosidl_get_dynamic_typesupport_identifier()) { throw std::runtime_error( "DynamicSubscription must use dynamic type introspection type support!"); diff --git a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp index 27cfdf43c7..ea8764fa29 100644 --- a/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp +++ b/rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp @@ -15,6 +15,7 @@ #ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_ #define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_ +#include #include #include #include @@ -71,7 +72,8 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this #include #include #include @@ -26,6 +27,7 @@ #include "rcl/type_hash.h" #include "rcl/types.h" #include "rcutils/logging_macros.h" +#include "rcutils/types/rcutils_ret.h" #include "rmw/dynamic_message_type_support.h" #include "rclcpp/dynamic_typesupport/dynamic_message.hpp" @@ -71,7 +73,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( if (!ts->data) { throw std::runtime_error("could not init rosidl message type support impl"); } - if (ts->typesupport_identifier != rmw_get_dynamic_typesupport_identifier()) { + if (ts->typesupport_identifier != rosidl_get_dynamic_typesupport_identifier()) { throw std::runtime_error("rosidl message type support is of the wrong type"); } @@ -135,20 +137,19 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport( throw std::runtime_error("failed to get type hash"); } - rmw_ret_t ret = rmw_dynamic_message_type_support_handle_create( + rcutils_ret_t ret = rosidl_dynamic_message_type_support_handle_create( serialization_support->get_rosidl_serialization_support(), - rmw_feature_supported(RMW_MIDDLEWARE_SUPPORTS_TYPE_DISCOVERY), type_hash.get(), // type_hash &description, // type_description nullptr, // type_description_sources (not implemented for dynamic types) &ts); - if (ret != RMW_RET_OK || !ts) { + if (ret != RCUTILS_RET_OK || !ts) { throw std::runtime_error("could not init rosidl message type support"); } if (!ts->data) { throw std::runtime_error("could not init rosidl message type support impl"); } - if (ts->typesupport_identifier != rmw_get_dynamic_typesupport_identifier()) { + if (ts->typesupport_identifier != rosidl_get_dynamic_typesupport_identifier()) { throw std::runtime_error("rosidl message type support is of the wrong type"); } @@ -303,6 +304,7 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( auto type_hash = std::make_unique(); rcutils_ret_t hash_ret = rcl_calculate_type_hash( // TODO(methylDragon): Swap this out with the conversion function when it is ready + // from https://github.com/ros2/rcl/pull/1052 reinterpret_cast(description), type_hash.get()); if (hash_ret != RCL_RET_OK || !type_hash) { @@ -328,7 +330,7 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_( // are managed by the passed in SharedPtr wrapper classes. We just delete it. rosidl_message_type_support_.reset( new rosidl_message_type_support_t{ - rmw_get_dynamic_typesupport_identifier(), // typesupport_identifier + rosidl_get_dynamic_typesupport_identifier(), // typesupport_identifier ts_impl, // data get_message_typesupport_handle_function, // func // get_type_hash_func