Compare commits

..

5 Commits

Author SHA1 Message Date
methylDragon
d4b03f9b7f Take ownership of description, add print, and update ser support API
Signed-off-by: methylDragon <methylDragon@gmail.com>
2023-03-23 11:15:58 -07:00
methylDragon
9c1371d2c5 Delete redundant wrapper class definitions
Signed-off-by: methylDragon <methylDragon@gmail.com>
2023-03-22 16:44:10 -07:00
methylDragon
df964aa858 Refine wrappers
Signed-off-by: methylDragon <methylDragon@gmail.com>
2023-03-22 16:44:10 -07:00
methylDragon
d10e6b279e Implement dynamic message type support wrapper
Signed-off-by: methylDragon <methylDragon@gmail.com>
2023-03-22 16:44:10 -07:00
methylDragon
bd9788a948 Implement dynamic typesupport wrappers
Signed-off-by: methylDragon <methylDragon@gmail.com>
2023-03-22 16:44:10 -07:00
35 changed files with 2979 additions and 3670 deletions

View File

@@ -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_message.cpp
src/rclcpp/dynamic_typesupport/dynamic_message_type.cpp
src/rclcpp/dynamic_typesupport/dynamic_message_type_builder.cpp
src/rclcpp/dynamic_typesupport/dynamic_data.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
@@ -100,7 +100,6 @@ set(${PROJECT_NAME}_SRCS
src/rclcpp/qos.cpp
src/rclcpp/event_handler.cpp
src/rclcpp/qos_overriding_options.cpp
src/rclcpp/dynamic_subscription.cpp
src/rclcpp/serialization.cpp
src/rclcpp/serialized_message.cpp
src/rclcpp/service.cpp

View File

@@ -1,176 +0,0 @@
// 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__DYNAMIC_SUBSCRIPTION_HPP_
#define RCLCPP__DYNAMIC_SUBSCRIPTION_HPP_
#include <rosidl_dynamic_typesupport/identifier.h>
#include <functional>
#include <memory>
#include <string>
#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"
#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 DynamicSubscription : public rclcpp::SubscriptionBase
{
public:
// cppcheck-suppress unknownMacro
RCLCPP_SMART_PTR_DEFINITIONS(DynamicSubscription)
template<typename AllocatorT = std::allocator<void>>
DynamicSubscription(
rclcpp::node_interfaces::NodeBaseInterface * node_base,
rclcpp::dynamic_typesupport::DynamicMessageTypeSupport::SharedPtr type_support,
const std::string & topic_name,
const rclcpp::QoS & qos,
std::function<void(
rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr,
const rosidl_runtime_c__type_description__TypeDescription &
)> callback,
const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & options,
bool use_take_dynamic_message = true)
: SubscriptionBase(
node_base,
type_support->get_const_rosidl_message_type_support(),
topic_name,
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
ts_(type_support),
callback_(callback),
serialization_support_(nullptr),
dynamic_message_(nullptr),
dynamic_message_type_(nullptr)
{
if (!type_support) {
throw std::runtime_error("DynamicMessageTypeSupport cannot be nullptr!");
}
if (type_support->get_const_rosidl_message_type_support().typesupport_identifier !=
rosidl_get_dynamic_typesupport_identifier())
{
throw std::runtime_error(
"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):
/// Deferred type description constructor, only usable if the middleware implementation supports
/// type discovery
RCLCPP_PUBLIC
virtual ~DynamicSubscription() = default;
// Same as create_serialized_message() as the subscription is to serialized_messages only
RCLCPP_PUBLIC
std::shared_ptr<void> create_message() override;
RCLCPP_PUBLIC
std::shared_ptr<rclcpp::SerializedMessage> create_serialized_message() override;
/// Cast the message to a rclcpp::SerializedMessage and call the callback.
RCLCPP_PUBLIC
void handle_message(
std::shared_ptr<void> & message, const rclcpp::MessageInfo & message_info) override;
/// Handle dispatching rclcpp::SerializedMessage to user callback.
RCLCPP_PUBLIC
void
handle_serialized_message(
const std::shared_ptr<rclcpp::SerializedMessage> & 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<void> & message) override;
RCLCPP_PUBLIC
void return_serialized_message(std::shared_ptr<rclcpp::SerializedMessage> & message) override;
// DYNAMIC TYPE ==================================================================================
// TODO(methylDragon): Reorder later
RCLCPP_PUBLIC
rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr
get_shared_dynamic_message_type() override;
RCLCPP_PUBLIC
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 & message,
const rclcpp::MessageInfo & message_info) override;
private:
RCLCPP_DISABLE_COPY(DynamicSubscription)
rclcpp::dynamic_typesupport::DynamicMessageTypeSupport::SharedPtr ts_;
std::function<void(
rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr,
const rosidl_runtime_c__type_description__TypeDescription &
)> 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
#endif // RCLCPP__DYNAMIC_SUBSCRIPTION_HPP_

View File

@@ -12,77 +12,76 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_
#include <rosidl_dynamic_typesupport/types.h>
#include <rosidl_dynamic_typesupport/api/dynamic_data.h>
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_
#include <cstdint>
#include <cstddef>
#include <memory>
#include <string>
#include <rosidl_dynamic_typesupport/types.h>
#include <rosidl_dynamic_typesupport/api/dynamic_data.h>
#include "rclcpp/exceptions.hpp"
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_
#include "rclcpp/dynamic_typesupport/dynamic_message.hpp"
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_DATA_HPP_
#include "rclcpp/dynamic_typesupport/dynamic_data.hpp"
#endif
#define __DYNAMIC_MESSAGE_GET_VALUE_BY_ID_FN(ValueT, FunctionT) \
#define __DYNAMIC_DATA_GET_VALUE_BY_ID_FN(ValueT, FunctionT) \
template<> \
ValueT \
DynamicMessage::get_value<ValueT>(rosidl_dynamic_typesupport_member_id_t id) \
DynamicData::get_value<ValueT>(rosidl_dynamic_typesupport_member_id_t id) \
{ \
ValueT out; \
rosidl_dynamic_typesupport_dynamic_data_get_ ## FunctionT ## _value( \
&rosidl_dynamic_data_, id, &out); \
rosidl_dynamic_data_.get(), id, &out); \
return out; \
}
#define __DYNAMIC_MESSAGE_GET_VALUE_BY_NAME_FN(ValueT, FunctionT) \
#define __DYNAMIC_DATA_GET_VALUE_BY_NAME_FN(ValueT, FunctionT) \
template<> \
ValueT \
DynamicMessage::get_value<ValueT>(const std::string & name) \
DynamicData::get_value<ValueT>(const std::string & name) \
{ \
return get_value<ValueT>(get_member_id(name)); \
}
#define __DYNAMIC_MESSAGE_SET_VALUE_BY_ID_FN(ValueT, FunctionT) \
#define __DYNAMIC_DATA_SET_VALUE_BY_ID_FN(ValueT, FunctionT) \
template<> \
void \
DynamicMessage::set_value<ValueT>(rosidl_dynamic_typesupport_member_id_t id, ValueT value) \
DynamicData::set_value<ValueT>(rosidl_dynamic_typesupport_member_id_t id, ValueT value) \
{ \
rosidl_dynamic_typesupport_dynamic_data_set_ ## FunctionT ## _value( \
&rosidl_dynamic_data_, id, value); \
rosidl_dynamic_data_.get(), id, value); \
}
#define __DYNAMIC_MESSAGE_SET_VALUE_BY_NAME_FN(ValueT, FunctionT) \
#define __DYNAMIC_DATA_SET_VALUE_BY_NAME_FN(ValueT, FunctionT) \
template<> \
void \
DynamicMessage::set_value<ValueT>(const std::string & name, ValueT value) \
DynamicData::set_value<ValueT>(const std::string & name, ValueT value) \
{ \
set_value<ValueT>(get_member_id(name), value); \
}
#define __DYNAMIC_MESSAGE_INSERT_VALUE(ValueT, FunctionT) \
#define __DYNAMIC_DATA_INSERT_VALUE(ValueT, FunctionT) \
template<> \
rosidl_dynamic_typesupport_member_id_t \
DynamicMessage::insert_value<ValueT>(ValueT value) \
DynamicData::insert_value<ValueT>(ValueT value) \
{ \
rosidl_dynamic_typesupport_member_id_t out; \
rosidl_dynamic_typesupport_dynamic_data_insert_ ## FunctionT ## _value( \
&rosidl_dynamic_data_, value, &out); \
rosidl_dynamic_data_.get(), value, &out); \
return out; \
}
#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)
#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
@@ -102,21 +101,21 @@ namespace dynamic_typesupport
* - String types: std::string, 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);
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
@@ -124,17 +123,17 @@ DYNAMIC_MESSAGE_DEFINITIONS(uint64_t, uint64);
// BYTE ============================================================================================
template<>
std::byte
DynamicMessage::get_value<std::byte>(rosidl_dynamic_typesupport_member_id_t id)
DynamicData::get_value<std::byte>(rosidl_dynamic_typesupport_member_id_t id)
{
unsigned char out;
rosidl_dynamic_typesupport_dynamic_data_get_byte_value(&get_rosidl_dynamic_data(), id, &out);
rosidl_dynamic_typesupport_dynamic_data_get_byte_value(get_rosidl_dynamic_data(), id, &out);
return static_cast<std::byte>(out);
}
template<>
std::byte
DynamicMessage::get_value<std::byte>(const std::string & name)
DynamicData::get_value<std::byte>(const std::string & name)
{
return get_value<std::byte>(get_member_id(name));
}
@@ -142,17 +141,17 @@ DynamicMessage::get_value<std::byte>(const std::string & name)
template<>
void
DynamicMessage::set_value<std::byte>(
DynamicData::set_value<std::byte>(
rosidl_dynamic_typesupport_member_id_t id, const std::byte value)
{
rosidl_dynamic_typesupport_dynamic_data_set_byte_value(
&rosidl_dynamic_data_, id, static_cast<unsigned char>(value));
rosidl_dynamic_data_.get(), id, static_cast<unsigned char>(value));
}
template<>
void
DynamicMessage::set_value<std::byte>(const std::string & name, const std::byte value)
DynamicData::set_value<std::byte>(const std::string & name, const std::byte value)
{
set_value<std::byte>(get_member_id(name), value);
}
@@ -160,11 +159,11 @@ DynamicMessage::set_value<std::byte>(const std::string & name, const std::byte v
template<>
rosidl_dynamic_typesupport_member_id_t
DynamicMessage::insert_value<std::byte>(const std::byte value)
DynamicData::insert_value<std::byte>(const std::byte value)
{
rosidl_dynamic_typesupport_member_id_t out;
rosidl_dynamic_typesupport_dynamic_data_insert_byte_value(
&rosidl_dynamic_data_, static_cast<unsigned char>(value), &out);
rosidl_dynamic_data_.get(), static_cast<unsigned char>(value), &out);
return out;
}
@@ -172,35 +171,35 @@ DynamicMessage::insert_value<std::byte>(const std::byte value)
// STRINGS =========================================================================================
template<>
std::string
DynamicMessage::get_value<std::string>(rosidl_dynamic_typesupport_member_id_t id)
DynamicData::get_value<std::string>(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);
get_rosidl_dynamic_data(), id, &buf, &buf_length);
auto out = std::string(buf, buf_length);
delete buf;
free(buf);
return out;
}
template<>
std::u16string
DynamicMessage::get_value<std::u16string>(rosidl_dynamic_typesupport_member_id_t id)
DynamicData::get_value<std::u16string>(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);
get_rosidl_dynamic_data(), id, &buf, &buf_length);
auto out = std::u16string(buf, buf_length);
delete buf;
free(buf);
return out;
}
template<>
std::string
DynamicMessage::get_value<std::string>(const std::string & name)
DynamicData::get_value<std::string>(const std::string & name)
{
return get_value<std::string>(get_member_id(name));
}
@@ -208,7 +207,7 @@ DynamicMessage::get_value<std::string>(const std::string & name)
template<>
std::u16string
DynamicMessage::get_value<std::u16string>(const std::string & name)
DynamicData::get_value<std::u16string>(const std::string & name)
{
return get_value<std::u16string>(get_member_id(name));
}
@@ -216,27 +215,27 @@ DynamicMessage::get_value<std::u16string>(const std::string & name)
template<>
void
DynamicMessage::set_value<std::string>(
DynamicData::set_value<std::string>(
rosidl_dynamic_typesupport_member_id_t id, const std::string value)
{
rosidl_dynamic_typesupport_dynamic_data_set_string_value(
&rosidl_dynamic_data_, id, value.c_str(), value.size());
rosidl_dynamic_data_.get(), id, value.c_str(), value.size());
}
template<>
void
DynamicMessage::set_value<std::u16string>(
DynamicData::set_value<std::u16string>(
rosidl_dynamic_typesupport_member_id_t id, const std::u16string value)
{
rosidl_dynamic_typesupport_dynamic_data_set_wstring_value(
&rosidl_dynamic_data_, id, value.c_str(), value.size());
rosidl_dynamic_data_.get(), id, value.c_str(), value.size());
}
template<>
void
DynamicMessage::set_value<std::string>(const std::string & name, const std::string value)
DynamicData::set_value<std::string>(const std::string & name, const std::string value)
{
set_value<std::string>(get_member_id(name), value);
}
@@ -244,7 +243,7 @@ DynamicMessage::set_value<std::string>(const std::string & name, const std::stri
template<>
void
DynamicMessage::set_value<std::u16string>(const std::string & name, const std::u16string value)
DynamicData::set_value<std::u16string>(const std::string & name, const std::u16string value)
{
set_value<std::u16string>(get_member_id(name), value);
}
@@ -252,22 +251,22 @@ DynamicMessage::set_value<std::u16string>(const std::string & name, const std::u
template<>
rosidl_dynamic_typesupport_member_id_t
DynamicMessage::insert_value<std::string>(const std::string value)
DynamicData::insert_value<std::string>(const std::string value)
{
rosidl_dynamic_typesupport_member_id_t out;
rosidl_dynamic_typesupport_dynamic_data_insert_string_value(
&rosidl_dynamic_data_, value.c_str(), value.size(), &out);
rosidl_dynamic_data_.get(), value.c_str(), value.size(), &out);
return out;
}
template<>
rosidl_dynamic_typesupport_member_id_t
DynamicMessage::insert_value<std::u16string>(const std::u16string value)
DynamicData::insert_value<std::u16string>(const std::u16string value)
{
rosidl_dynamic_typesupport_member_id_t out;
rosidl_dynamic_typesupport_dynamic_data_insert_wstring_value(
&rosidl_dynamic_data_, value.c_str(), value.size(), &out);
rosidl_dynamic_data_.get(), value.c_str(), value.size(), &out);
return out;
}
@@ -275,7 +274,7 @@ DynamicMessage::insert_value<std::u16string>(const std::u16string value)
// THROW FOR UNSUPPORTED TYPES =====================================================================
template<typename ValueT>
ValueT
DynamicMessage::get_value(rosidl_dynamic_typesupport_member_id_t id)
DynamicData::get_value(rosidl_dynamic_typesupport_member_id_t id)
{
throw rclcpp::exceptions::UnimplementedError("get_value is not implemented for input type");
}
@@ -283,7 +282,7 @@ DynamicMessage::get_value(rosidl_dynamic_typesupport_member_id_t id)
template<typename ValueT>
ValueT
DynamicMessage::get_value(const std::string & name)
DynamicData::get_value(const std::string & name)
{
throw rclcpp::exceptions::UnimplementedError("get_value is not implemented for input type");
}
@@ -291,7 +290,7 @@ DynamicMessage::get_value(const std::string & name)
template<typename ValueT>
void
DynamicMessage::set_value(
DynamicData::set_value(
rosidl_dynamic_typesupport_member_id_t id, ValueT value)
{
throw rclcpp::exceptions::UnimplementedError("set_value is not implemented for input type");
@@ -300,7 +299,7 @@ DynamicMessage::set_value(
template<typename ValueT>
void
DynamicMessage::set_value(const std::string & name, ValueT value)
DynamicData::set_value(const std::string & name, ValueT value)
{
throw rclcpp::exceptions::UnimplementedError("set_value is not implemented for input type");
}
@@ -308,7 +307,7 @@ DynamicMessage::set_value(const std::string & name, ValueT value)
template<typename ValueT>
rosidl_dynamic_typesupport_member_id_t
DynamicMessage::insert_value(ValueT value)
DynamicData::insert_value(ValueT value)
{
throw rclcpp::exceptions::UnimplementedError("insert_value is not implemented for input type");
}
@@ -317,11 +316,11 @@ DynamicMessage::insert_value(ValueT value)
} // namespace dynamic_typesupport
} // namespace rclcpp
#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
#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_MESSAGE_IMPL_HPP_
#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_DATA_IMPL_HPP_

View File

@@ -1,189 +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__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_
#include <rosidl_dynamic_typesupport/types.h>
#include <rosidl_dynamic_typesupport/api/dynamic_type.h>
#include <cstdint>
#include <cstddef>
#include <memory>
#include <string>
#include "rclcpp/exceptions.hpp"
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_
#include "rclcpp/dynamic_typesupport/dynamic_message_type_builder.hpp"
#endif
#define __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_MEMBER_FN(MemberT, FunctionT) \
template<> \
void \
DynamicMessageTypeBuilder::add_member<MemberT>( \
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_, \
id, name.c_str(), name.size(), default_value.c_str(), default_value.size()); \
}
#define __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_ARRAY_MEMBER_FN(MemberT, FunctionT) \
template<> \
void \
DynamicMessageTypeBuilder::add_array_member<MemberT>( \
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_, \
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(), \
array_length); \
}
#define __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_UNBOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \
template<> \
void \
DynamicMessageTypeBuilder::add_unbounded_sequence_member<MemberT>( \
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_, \
id, name.c_str(), name.size(), default_value.c_str(), default_value.size()); \
}
#define __DYNAMIC_MESSAGE_TYPE_BUILDER_ADD_BOUNDED_SEQUENCE_MEMBER_FN(MemberT, FunctionT) \
template<> \
void \
DynamicMessageTypeBuilder::add_bounded_sequence_member<MemberT>( \
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_, \
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(), \
sequence_bound); \
}
#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
{
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_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<typename MemberT>
void
DynamicMessageTypeBuilder::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");
}
template<typename MemberT>
void
DynamicMessageTypeBuilder::add_array_member(
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");
}
template<typename MemberT>
void
DynamicMessageTypeBuilder::add_unbounded_sequence_member(
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");
}
template<typename MemberT>
void
DynamicMessageTypeBuilder::add_bounded_sequence_member(
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");
}
} // namespace dynamic_typesupport
} // namespace rclcpp
#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_MESSAGE_TYPE_BUILDER_IMPL_HPP_

View File

@@ -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 <cstdint>
#include <cstddef>
#include <memory>
#include <string>
#include <rosidl_dynamic_typesupport/types.h>
#include <rosidl_dynamic_typesupport/api/dynamic_type.h>
#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<MemberT>( \
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<MemberT>( \
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<MemberT>( \
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<MemberT>( \
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<typename MemberT>
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<typename MemberT>
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<typename MemberT>
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<typename MemberT>
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_

View File

@@ -0,0 +1,374 @@
// 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 <memory>
#include <string>
#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp"
#include "rclcpp/macros.hpp"
#include "rclcpp/visibility_control.hpp"
#include <rcl/types.h>
#include <rosidl_dynamic_typesupport/types.h>
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<DynamicData>
{
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<DynamicTypeBuilder> dynamic_type_builder);
/// Construct a new DynamicData with the provided dynamic type
RCLCPP_PUBLIC
explicit DynamicData(std::shared_ptr<DynamicType> 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_typesupport_dynamic_data_t> 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<rosidl_dynamic_typesupport_dynamic_data_t>
get_shared_rosidl_dynamic_data();
RCLCPP_PUBLIC
std::shared_ptr<const rosidl_dynamic_typesupport_dynamic_data_t>
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
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<typename ValueT>
ValueT
get_value(rosidl_dynamic_typesupport_member_id_t id);
template<typename ValueT>
ValueT
get_value(const std::string & name);
template<typename ValueT>
void
set_value(rosidl_dynamic_typesupport_member_id_t id, ValueT value);
template<typename ValueT>
void
set_value(const std::string & name, ValueT value);
template<typename ValueT>
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_typesupport_dynamic_data_t> 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_

View File

@@ -15,416 +15,30 @@
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_HPP_
#include <rcl/allocator.h>
#include <rcl/types.h>
#include <rosidl_dynamic_typesupport/types.h>
#include <memory>
#include <string>
#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/macros.hpp"
#include "rclcpp/visibility_control.hpp"
#include <rosidl_dynamic_typesupport/types.h>
namespace rclcpp
{
namespace dynamic_typesupport
{
class DynamicMessageType;
class DynamicMessageTypeBuilder;
/// Utility wrapper class for rosidl_dynamic_typesupport_dynamic_data_t
/**
* This class:
* - Exposes getter methods for the struct
* - 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<DynamicMessage>
{
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, using its allocator
RCLCPP_PUBLIC
explicit DynamicMessage(std::shared_ptr<DynamicMessageTypeBuilder> dynamic_type_builder);
/// Construct a new DynamicMessage with the provided dynamic type builder and allocator
RCLCPP_PUBLIC
DynamicMessage(
std::shared_ptr<DynamicMessageTypeBuilder> dynamic_type_builder,
rcl_allocator_t allocator);
/// Construct a new DynamicMessage with the provided dynamic type, using its allocator
RCLCPP_PUBLIC
explicit DynamicMessage(std::shared_ptr<DynamicMessageType> dynamic_type);
/// Construct a new DynamicMessage with the provided dynamic type and allocator
RCLCPP_PUBLIC
DynamicMessage(
std::shared_ptr<DynamicMessageType> dynamic_type,
rcl_allocator_t allocator);
/// Assume ownership of struct
RCLCPP_PUBLIC
DynamicMessage(
DynamicSerializationSupport::SharedPtr serialization_support,
rosidl_dynamic_typesupport_dynamic_data_t && rosidl_dynamic_data);
/// Loaning constructor
/// Must only be called with a rosidl dynaimc data object 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
/// Move constructor
RCLCPP_PUBLIC
DynamicMessage(DynamicMessage && other) noexcept;
/// Move assignment
RCLCPP_PUBLIC
DynamicMessage & operator=(DynamicMessage && other) noexcept;
RCLCPP_PUBLIC
virtual ~DynamicMessage();
// GETTERS =======================================================================================
RCLCPP_PUBLIC
const std::string
get_serialization_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
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(rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
DynamicMessage::SharedPtr
clone_shared(rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
DynamicMessage
init_from_type(
DynamicMessageType & type, rcl_allocator_t allocator = rcl_get_default_allocator()) const;
RCLCPP_PUBLIC
DynamicMessage::SharedPtr
init_from_type_shared(
DynamicMessageType & type, rcl_allocator_t allocator = rcl_get_default_allocator()) const;
RCLCPP_PUBLIC
bool
equals(const DynamicMessage & other) const;
RCLCPP_PUBLIC
DynamicMessage::SharedPtr
loan_value(
rosidl_dynamic_typesupport_member_id_t id,
rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
DynamicMessage::SharedPtr
loan_value(
const std::string & name,
rcl_allocator_t allocator = rcl_get_default_allocator());
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
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<typename ValueT>
ValueT
get_value(rosidl_dynamic_typesupport_member_id_t id);
template<typename ValueT>
ValueT
get_value(const std::string & name);
template<typename ValueT>
void
set_value(rosidl_dynamic_typesupport_member_id_t id, ValueT value);
template<typename ValueT>
void
set_value(const std::string & name, ValueT value);
template<typename ValueT>
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,
rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
DynamicMessage
get_complex_value(
const std::string & name,
rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
DynamicMessage::SharedPtr
get_complex_value_shared(
rosidl_dynamic_typesupport_member_id_t id,
rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
DynamicMessage::SharedPtr
get_complex_value_shared(
const std::string & name,
rcl_allocator_t allocator = rcl_get_default_allocator());
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_;
rosidl_dynamic_typesupport_dynamic_data_t rosidl_dynamic_data_;
bool is_loaned_;
// Used for returning the loaned value, and lifetime management
DynamicMessage::SharedPtr parent_data_;
private:
RCLCPP_DISABLE_COPY(DynamicMessage)
RCLCPP_PUBLIC
DynamicMessage();
RCLCPP_PUBLIC
bool
match_serialization_support_(
const DynamicSerializationSupport & serialization_support,
const rosidl_dynamic_typesupport_dynamic_data_t & dynamic_data);
};
// 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;
} // namespace dynamic_typesupport
} // namespace rclcpp

View File

@@ -15,181 +15,29 @@
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_HPP_
#include <rcl/allocator.h>
#include <rosidl_dynamic_typesupport/types.h>
#include <memory>
#include <string>
#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 <rosidl_dynamic_typesupport/types.h>
namespace rclcpp
{
namespace dynamic_typesupport
{
class DynamicMessage;
class DynamicMessageTypeBuilder;
/// Utility wrapper class for `rosidl_dynamic_typesupport_dynamic_type_t`
/**
* This class:
* - Exposes getter methods for the struct
* - 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 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_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<DynamicMessageType>
{
public:
RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageType)
// 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;
// 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,
/// using its allocator
RCLCPP_PUBLIC
explicit DynamicMessageType(std::shared_ptr<DynamicMessageTypeBuilder> dynamic_type_builder);
/// Construct a new `DynamicMessageType` with the provided dynamic type builder and allocator
RCLCPP_PUBLIC
DynamicMessageType(
std::shared_ptr<DynamicMessageTypeBuilder> dynamic_type_builder,
rcl_allocator_t allocator);
/// Assume ownership of struct
RCLCPP_PUBLIC
DynamicMessageType(
DynamicSerializationSupport::SharedPtr serialization_support,
rosidl_dynamic_typesupport_dynamic_type_t && rosidl_dynamic_type);
/// From description
RCLCPP_PUBLIC
DynamicMessageType(
DynamicSerializationSupport::SharedPtr serialization_support,
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator = rcl_get_default_allocator());
/// Move constructor
RCLCPP_PUBLIC
DynamicMessageType(DynamicMessageType && other) noexcept;
/// Move assignment
RCLCPP_PUBLIC
DynamicMessageType & operator=(DynamicMessageType && other) noexcept;
RCLCPP_PUBLIC
virtual ~DynamicMessageType();
/// Swaps the serialization support if `serialization_support` is populated
/**
* The user can call this with another description to reconfigure the type without changing the
* serialization support
*/
RCLCPP_PUBLIC
void
init_from_description(
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator = rcl_get_default_allocator(),
DynamicSerializationSupport::SharedPtr serialization_support = nullptr);
// GETTERS =======================================================================================
RCLCPP_PUBLIC
const std::string
get_serialization_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
DynamicSerializationSupport::SharedPtr
get_shared_dynamic_serialization_support();
RCLCPP_PUBLIC
DynamicSerializationSupport::ConstSharedPtr
get_shared_dynamic_serialization_support() const;
// METHODS =======================================================================================
RCLCPP_PUBLIC
DynamicMessageType
clone(rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
DynamicMessageType::SharedPtr
clone_shared(rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
bool
equals(const DynamicMessageType & other) const;
RCLCPP_PUBLIC
DynamicMessage
build_dynamic_message(rcl_allocator_t allocator = rcl_get_default_allocator());
RCLCPP_PUBLIC
std::shared_ptr<DynamicMessage>
build_dynamic_message_shared(rcl_allocator_t allocator = rcl_get_default_allocator());
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_;
rosidl_dynamic_typesupport_dynamic_type_t rosidl_dynamic_type_;
private:
RCLCPP_DISABLE_COPY(DynamicMessageType)
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
} // namespace rclcpp

View File

@@ -15,45 +15,43 @@
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_
#include <rcl/allocator.h>
#include <rosidl_dynamic_typesupport/dynamic_message_type_support_struct.h>
#include <rosidl_dynamic_typesupport/types.h>
#include <rosidl_runtime_c/message_type_support_struct.h>
#include <rosidl_runtime_c/type_description/type_description__struct.h>
#include <memory>
#include <string>
#include "rclcpp/dynamic_typesupport/dynamic_message.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/macros.hpp"
#include "rclcpp/visibility_control.hpp"
#include <rosidl_dynamic_typesupport/types.h>
#include <rosidl_runtime_c/message_type_support_struct.h>
#include <rosidl_runtime_c/type_description/type_description__struct.h>
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_get_dynamic_message_typesupport_handle,
* 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_typesupport_handle_fini!!
*
* This class:
* - Exposes getter methods for the struct
* - 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
* - 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<DynamicMessageTypeSupport>
@@ -63,39 +61,24 @@ public:
// CONSTRUCTION ==================================================================================
/// From description
/// Does NOT take ownership of the description (copies instead.)
/// Constructs type support top-down (calling `rcl_dynamic_message_type_support_handle_create()`)
RCLCPP_PUBLIC
DynamicMessageTypeSupport(
const rosidl_runtime_c__type_description__TypeDescription & description,
const std::string & serialization_library_name = "",
rcl_allocator_t allocator = rcl_get_default_allocator());
rosidl_runtime_c__type_description__TypeDescription * description,
const std::string & serialization_library_name = "");
/// From description, for provided serialization support
/// Does NOT take ownership of the description (copies instead.)
/// Constructs type support top-down (calling `rosidl_dynamic_message_type_support_handle_init()`)
RCLCPP_PUBLIC
DynamicMessageTypeSupport(
DynamicSerializationSupport::SharedPtr serialization_support,
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator = rcl_get_default_allocator());
rosidl_runtime_c__type_description__TypeDescription * description);
/// Assume ownership of managed types
/// Does NOT take ownership of the description (copies instead.)
///
/// The serialization support used to construct all managed SharedPtrs must match.
/// The structure of the provided `description` must match the `dynamic_message_type`
/// The structure of the provided `dynamic_message_type` must match the `dynamic_message
///
/// In this case, the user would have constructed the type support bototm-up (by creating the
/// respective dynamic members.)
RCLCPP_PUBLIC
DynamicMessageTypeSupport(
DynamicSerializationSupport::SharedPtr serialization_support,
DynamicMessageType::SharedPtr dynamic_message_type,
DynamicMessage::SharedPtr dynamic_message,
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator = rcl_get_default_allocator());
rosidl_runtime_c__type_description__TypeDescription * description = nullptr);
RCLCPP_PUBLIC
virtual ~DynamicMessageTypeSupport();
@@ -104,20 +87,40 @@ public:
// GETTERS =======================================================================================
RCLCPP_PUBLIC
const std::string
get_serialization_library_identifier() const;
get_library_identifier() const;
RCLCPP_PUBLIC
const rosidl_message_type_support_t &
get_const_rosidl_message_type_support();
rosidl_message_type_support_t *
get_rosidl_message_type_support();
RCLCPP_PUBLIC
const rosidl_message_type_support_t &
get_const_rosidl_message_type_support() const;
const rosidl_message_type_support_t *
get_rosidl_message_type_support() const;
RCLCPP_PUBLIC
const rosidl_runtime_c__type_description__TypeDescription &
std::shared_ptr<rosidl_message_type_support_t>
get_shared_rosidl_message_type_support();
RCLCPP_PUBLIC
std::shared_ptr<const rosidl_message_type_support_t>
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<rosidl_runtime_c__type_description__TypeDescription>
get_shared_rosidl_runtime_c_type_description();
RCLCPP_PUBLIC
std::shared_ptr<const rosidl_runtime_c__type_description__TypeDescription>
get_shared_rosidl_runtime_c_type_description() const;
RCLCPP_PUBLIC
DynamicSerializationSupport::SharedPtr
get_shared_dynamic_serialization_support();
@@ -142,24 +145,50 @@ public:
DynamicMessage::ConstSharedPtr
get_shared_dynamic_message() const;
// METHODS =======================================================================================
RCLCPP_PUBLIC
void
print_description() const;
protected:
RCLCPP_DISABLE_COPY(DynamicMessageTypeSupport)
RCLCPP_PUBLIC
rosidl_message_type_support_t &
get_rosidl_message_type_support();
DynamicSerializationSupport::SharedPtr serialization_support_;
DynamicMessageType::SharedPtr dynamic_message_type_;
DynamicMessage::SharedPtr dynamic_message_;
std::shared_ptr<rosidl_runtime_c__type_description__TypeDescription> description_;
std::shared_ptr<rosidl_message_type_support_t> rosidl_message_type_support_;
private:
RCLCPP_PUBLIC
DynamicMessageTypeSupport();
DynamicSerializationSupport::SharedPtr serialization_support_;
DynamicMessageType::SharedPtr dynamic_message_type_;
DynamicMessage::SharedPtr dynamic_message_;
RCLCPP_PUBLIC
void
init_serialization_support_(const std::string & serialization_library_name);
rosidl_message_type_support_t rosidl_message_type_support_;
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,
rosidl_runtime_c__type_description__TypeDescription * description);
};
} // namespace dynamic_typesupport
} // namespace rclcpp

View File

@@ -15,25 +15,25 @@
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_SERIALIZATION_SUPPORT_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_SERIALIZATION_SUPPORT_HPP_
#include <rcl/allocator.h>
#include <rosidl_dynamic_typesupport/api/serialization_support.h>
#include <rosidl_dynamic_typesupport/types.h>
#include <memory>
#include <string>
#include "rclcpp/macros.hpp"
#include "rclcpp/visibility_control.hpp"
#include <rosidl_dynamic_typesupport/types.h>
namespace rclcpp
{
namespace dynamic_typesupport
{
/// Utility wrapper class for rosidl_dynamic_typesupport_serialization_support_t
/// Utility wrapper class for rosidl_dynamic_typesupport_serialization_support_t *
/**
* This class:
* - Exposes getter methods for the struct
* - 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:
@@ -46,19 +46,19 @@ public:
RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicSerializationSupport)
// CONSTRUCTION ==================================================================================
RCLCPP_PUBLIC
explicit DynamicSerializationSupport(rcl_allocator_t allocator = rcl_get_default_allocator());
/// Get the rmw middleware implementation specific serialization support (configured by name)
RCLCPP_PUBLIC
DynamicSerializationSupport(
const std::string & serialization_library_name,
rcl_allocator_t allocator = rcl_get_default_allocator());
explicit DynamicSerializationSupport(const std::string & serialization_library_name = "");
/// Assume ownership of struct
/// Assume ownership of raw pointer
RCLCPP_PUBLIC
explicit DynamicSerializationSupport(
rosidl_dynamic_typesupport_serialization_support_t && rosidl_serialization_support);
rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support);
/// Copy shared pointer
RCLCPP_PUBLIC
DynamicSerializationSupport(
std::shared_ptr<rosidl_dynamic_typesupport_serialization_support_t> serialization_support);
/// Move constructor
RCLCPP_PUBLIC
@@ -75,23 +75,35 @@ public:
// GETTERS =======================================================================================
RCLCPP_PUBLIC
const std::string
get_serialization_library_identifier() const;
get_library_identifier() const;
RCLCPP_PUBLIC
rosidl_dynamic_typesupport_serialization_support_t &
rosidl_dynamic_typesupport_serialization_support_t *
get_rosidl_serialization_support();
RCLCPP_PUBLIC
const rosidl_dynamic_typesupport_serialization_support_t &
const rosidl_dynamic_typesupport_serialization_support_t *
get_rosidl_serialization_support() const;
RCLCPP_PUBLIC
std::shared_ptr<rosidl_dynamic_typesupport_serialization_support_t>
get_shared_rosidl_serialization_support();
RCLCPP_PUBLIC
std::shared_ptr<const rosidl_dynamic_typesupport_serialization_support_t>
get_shared_rosidl_serialization_support() const;
protected:
RCLCPP_DISABLE_COPY(DynamicSerializationSupport)
std::shared_ptr<rosidl_dynamic_typesupport_serialization_support_t> rosidl_serialization_support_;
private:
rosidl_dynamic_typesupport_serialization_support_t rosidl_serialization_support_;
RCLCPP_PUBLIC
DynamicSerializationSupport();
};
} // namespace dynamic_typesupport
} // namespace rclcpp

View File

@@ -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 <memory>
#include <string>
#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp"
#include "rclcpp/macros.hpp"
#include "rclcpp/visibility_control.hpp"
#include <rosidl_dynamic_typesupport/types.h>
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<DynamicType>
{
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<DynamicTypeBuilder> 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_typesupport_dynamic_type_t> 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<rosidl_dynamic_typesupport_dynamic_type_t>
get_shared_rosidl_dynamic_type();
RCLCPP_PUBLIC
std::shared_ptr<const rosidl_dynamic_typesupport_dynamic_type_t>
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<DynamicData>
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_typesupport_dynamic_type_t> 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_

View File

@@ -12,11 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_
#include <rcl/allocator.h>
#include <rosidl_dynamic_typesupport/types.h>
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_
#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_
#include <memory>
#include <string>
@@ -25,15 +22,18 @@
#include "rclcpp/macros.hpp"
#include "rclcpp/visibility_control.hpp"
#include <rosidl_dynamic_typesupport/types.h>
namespace rclcpp
{
namespace dynamic_typesupport
{
class DynamicMessage;
class DynamicMessageType;
class DynamicData;
class DynamicType;
/// 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,102 +42,99 @@ 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!
*
* 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_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.
* 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 DynamicMessageTypeBuilder : public std::enable_shared_from_this<DynamicMessageTypeBuilder>
class DynamicTypeBuilder : public std::enable_shared_from_this<DynamicTypeBuilder>
{
public:
RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicMessageTypeBuilder)
RCLCPP_SMART_PTR_ALIASES_ONLY(DynamicTypeBuilder)
// CONSTRUCTION ==================================================================================
// All constructors require a passed in `DynamicSerializationSupport::SharedPtr`, to extend the
// 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`,
// the builder should be the exact same object managed by the DynamicSerializationSupport,
// otherwise the lifetime management will not work properly.
/// Construct a new `DynamicMessageTypeBuilder` with the provided serialization support using its
/// allocator
/// Construct a new DynamicTypeBuilder with the provided serialization support
RCLCPP_PUBLIC
DynamicMessageTypeBuilder(
DynamicTypeBuilder(
DynamicSerializationSupport::SharedPtr serialization_support,
const std::string & name);
/// Construct a new `DynamicMessageTypeBuilder` with the provided serialization support and
/// allocator
/// Assume ownership of raw pointer
RCLCPP_PUBLIC
DynamicMessageTypeBuilder(
DynamicTypeBuilder(
DynamicSerializationSupport::SharedPtr serialization_support,
const std::string & name,
rcl_allocator_t allocator);
rosidl_dynamic_typesupport_dynamic_type_builder_t * dynamic_type_builder);
/// Assume ownership of struct
/// Copy shared pointer
RCLCPP_PUBLIC
DynamicMessageTypeBuilder(
DynamicTypeBuilder(
DynamicSerializationSupport::SharedPtr serialization_support,
rosidl_dynamic_typesupport_dynamic_type_builder_t && dynamic_type_builder);
std::shared_ptr<rosidl_dynamic_typesupport_dynamic_type_builder_t> dynamic_type_builder);
/// From description
/// Copy constructor
RCLCPP_PUBLIC
DynamicMessageTypeBuilder(
DynamicSerializationSupport::SharedPtr serialization_support,
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator = rcl_get_default_allocator());
DynamicTypeBuilder(const DynamicTypeBuilder & other);
/// Move constructor
RCLCPP_PUBLIC
DynamicMessageTypeBuilder(DynamicMessageTypeBuilder && other) noexcept;
DynamicTypeBuilder(DynamicTypeBuilder && other) noexcept;
/// Copy assignment
RCLCPP_PUBLIC
DynamicTypeBuilder & operator=(const DynamicTypeBuilder & other);
/// Move assignment
RCLCPP_PUBLIC
DynamicMessageTypeBuilder & operator=(DynamicMessageTypeBuilder && other) noexcept;
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 ~DynamicMessageTypeBuilder();
virtual ~DynamicTypeBuilder();
/// Swaps the serialization support if serialization_support is populated
/**
* The user can call this with another description to reconfigure the type without changing the
* serialization support
*/
RCLCPP_PUBLIC
void
init_from_description(
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator = rcl_get_default_allocator(),
const rosidl_runtime_c__type_description__TypeDescription * description,
DynamicSerializationSupport::SharedPtr serialization_support = nullptr);
// GETTERS =======================================================================================
RCLCPP_PUBLIC
const std::string
get_serialization_library_identifier() const;
get_library_identifier() const;
RCLCPP_PUBLIC
const std::string
get_name() const;
RCLCPP_PUBLIC
rosidl_dynamic_typesupport_dynamic_type_builder_t &
rosidl_dynamic_typesupport_dynamic_type_builder_t *
get_rosidl_dynamic_type_builder();
RCLCPP_PUBLIC
const rosidl_dynamic_typesupport_dynamic_type_builder_t &
const rosidl_dynamic_typesupport_dynamic_type_builder_t *
get_rosidl_dynamic_type_builder() const;
RCLCPP_PUBLIC
std::shared_ptr<rosidl_dynamic_typesupport_dynamic_type_builder_t>
get_shared_rosidl_dynamic_type_builder();
RCLCPP_PUBLIC
std::shared_ptr<const rosidl_dynamic_typesupport_dynamic_type_builder_t>
get_shared_rosidl_dynamic_type_builder() const;
RCLCPP_PUBLIC
DynamicSerializationSupport::SharedPtr
get_shared_dynamic_serialization_support();
@@ -153,32 +150,32 @@ public:
set_name(const std::string & name);
RCLCPP_PUBLIC
DynamicMessageTypeBuilder
clone(rcl_allocator_t allocator = rcl_get_default_allocator());
DynamicTypeBuilder
clone() const;
RCLCPP_PUBLIC
DynamicMessageTypeBuilder::SharedPtr
clone_shared(rcl_allocator_t allocator = rcl_get_default_allocator());
DynamicTypeBuilder::SharedPtr
clone_shared() const;
RCLCPP_PUBLIC
void
clear(rcl_allocator_t allocator = rcl_get_default_allocator());
clear();
RCLCPP_PUBLIC
DynamicMessage
build_dynamic_message(rcl_allocator_t allocator = rcl_get_default_allocator());
DynamicData
build_data();
RCLCPP_PUBLIC
DynamicMessage::SharedPtr
build_dynamic_message_shared(rcl_allocator_t allocator = rcl_get_default_allocator());
std::shared_ptr<DynamicData>
build_data_shared();
RCLCPP_PUBLIC
DynamicMessageType
build_dynamic_message_type(rcl_allocator_t allocator = rcl_get_default_allocator());
DynamicType
build_type();
RCLCPP_PUBLIC
DynamicMessageType::SharedPtr
build_dynamic_message_type_shared(rcl_allocator_t allocator = rcl_get_default_allocator());
std::shared_ptr<DynamicType>
build_type_shared();
// ADD MEMBERS TEMPLATES =========================================================================
@@ -196,127 +193,68 @@ public:
template<typename MemberT>
void
add_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
const std::string & default_value = "");
add_member(rosidl_dynamic_typesupport_member_id_t id, const std::string & name);
template<typename MemberT>
void
add_array_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length,
const std::string & default_value = "");
rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t array_length);
template<typename MemberT>
void
add_unbounded_sequence_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
const std::string & default_value = "");
rosidl_dynamic_typesupport_member_id_t id, const std::string & name);
template<typename MemberT>
void
add_bounded_sequence_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t sequence_bound,
const std::string & default_value = "");
// ADD FIXED STRING MEMBERS ======================================================================
RCLCPP_PUBLIC
void
add_fixed_string_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t string_length,
const std::string & default_value = "");
RCLCPP_PUBLIC
void
add_fixed_wstring_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name, size_t wstring_length,
const std::string & default_value = "");
RCLCPP_PUBLIC
void
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 = "");
RCLCPP_PUBLIC
void
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 = "");
RCLCPP_PUBLIC
void
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 = "");
RCLCPP_PUBLIC
void
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 = "");
RCLCPP_PUBLIC
void
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 = "");
RCLCPP_PUBLIC
void
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 = "");
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,
const std::string & default_value = "");
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,
const std::string & default_value = "");
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, const std::string & default_value = "");
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, const std::string & default_value = "");
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,
const std::string & default_value = "");
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,
const std::string & default_value = "");
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, const std::string & default_value = "");
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, const std::string & default_value = "");
size_t wstring_bound, size_t sequence_bound);
// ADD NESTED MEMBERS ============================================================================
@@ -324,52 +262,49 @@ public:
void
add_complex_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageType & nested_type, const std::string & default_value = "");
DynamicType & nested_type);
RCLCPP_PUBLIC
void
add_complex_array_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageType & nested_type, size_t array_length, const std::string & default_value = "");
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,
DynamicMessageType & nested_type, const std::string & default_value = "");
DynamicType & nested_type);
RCLCPP_PUBLIC
void
add_complex_bounded_sequence_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageType & nested_type, size_t sequence_bound,
const std::string & default_value = "");
DynamicType & nested_type, size_t sequence_bound);
RCLCPP_PUBLIC
void
add_complex_member_builder(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageTypeBuilder & nested_type_builder, const std::string & default_value = "");
DynamicTypeBuilder & nested_type_builder);
RCLCPP_PUBLIC
void
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 = "");
DynamicTypeBuilder & nested_type_builder, size_t array_length);
RCLCPP_PUBLIC
void
add_complex_unbounded_sequence_member_builder(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageTypeBuilder & nested_type_builder, const std::string & default_value = "");
DynamicTypeBuilder & nested_type_builder);
RCLCPP_PUBLIC
void
add_complex_bounded_sequence_member_builder(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageTypeBuilder & nested_type_builder, size_t sequence_bound,
const std::string & default_value = "");
DynamicTypeBuilder & nested_type_builder, size_t sequence_bound);
protected:
// NOTE(methylDragon):
@@ -377,23 +312,20 @@ protected:
// 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
DynamicSerializationSupport::SharedPtr serialization_support_;
rosidl_dynamic_typesupport_dynamic_type_builder_t rosidl_dynamic_type_builder_;
std::shared_ptr<rosidl_dynamic_typesupport_dynamic_type_builder_t> rosidl_dynamic_type_builder_;
private:
RCLCPP_DISABLE_COPY(DynamicMessageTypeBuilder)
RCLCPP_PUBLIC
DynamicMessageTypeBuilder();
DynamicTypeBuilder();
RCLCPP_PUBLIC
void
init_from_serialization_support_(
DynamicSerializationSupport::SharedPtr serialization_support,
const std::string & name,
rcl_allocator_t allocator);
const std::string & name);
RCLCPP_PUBLIC
bool
@@ -402,8 +334,9 @@ private:
const rosidl_dynamic_typesupport_dynamic_type_builder_t & dynamic_type_builder);
};
} // namespace dynamic_typesupport
} // namespace rclcpp
#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_BUILDER_HPP_
#endif // RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_TYPE_BUILDER_HPP_

View File

@@ -84,7 +84,7 @@ public:
options.to_rcl_subscription_options(qos),
options.event_callbacks,
options.use_default_callbacks,
SubscriptionType::SERIALIZED_MESSAGE),
true),
callback_(callback),
ts_lib_(ts_lib)
{}
@@ -123,32 +123,6 @@ public:
RCLCPP_PUBLIC
void return_serialized_message(std::shared_ptr<rclcpp::SerializedMessage> & message) override;
// DYNAMIC TYPE ==================================================================================
// TODO(methylDragon): Reorder later
RCLCPP_PUBLIC
rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr get_shared_dynamic_message_type()
override;
RCLCPP_PUBLIC
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 & message,
const rclcpp::MessageInfo & message_info) override;
private:
RCLCPP_DISABLE_COPY(GenericSubscription)

View File

@@ -170,24 +170,6 @@ public:
RCLCPP_PUBLIC
void
set_level(Level level);
/// Get effective level for current logger.
/**
* The effective level is determined as the severity level of
* the logger if it is set, otherwise it is the first specified severity
* level of the logger's ancestors, starting with its closest ancestor.
* The ancestor hierarchy is signified by logger names being separated by dots:
* a logger named `x` is an ancestor of `x.y`, and both `x` and `x.y` are
* ancestors of `x.y.z`, etc.
* If the level has not been set for the logger nor any of its
* ancestors, the default level is used.
*
* \throws rclcpp::exceptions::RCLError if any error happens.
* \return Level for the current logger.
*/
RCLCPP_PUBLIC
Level
get_effective_level() const;
};
} // namespace rclcpp

View File

@@ -118,20 +118,21 @@
* - 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
* - Dynamic subscription
* - rclcpp::DynamicSubscription
* - rclcpp/dynamic_subscription.hpp
* - Generic publisher
* - rclcpp::Node::create_generic_publisher()
* - rclcpp::GenericPublisher
@@ -182,6 +183,4 @@
#include "rclcpp/waitable.hpp"
#include "rclcpp/wait_set.hpp"
#include "rclcpp/dynamic_subscription.hpp"
#endif // RCLCPP__RCLCPP_HPP_

View File

@@ -0,0 +1,56 @@
// Copyright 2015 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.
// Based on: http://the-witness.net/news/2012/11/scopeexit-in-c11/
// But I changed the lambda to include by reference rather than value, see:
// http://the-witness.net/news/2012/11/scopeexit-in-c11/comment-page-1/#comment-86873
#ifndef RCLCPP__SCOPE_EXIT_HPP_
#define RCLCPP__SCOPE_EXIT_HPP_
// TODO(christophebedard) remove this header completely in I-turtle
#warning rclcpp/scope_exit.hpp has been deprecated, please use rcpputils/scope_exit.hpp instead
#include <functional>
#include "rclcpp/macros.hpp"
namespace rclcpp
{
template<typename Callable>
struct ScopeExit
{
explicit ScopeExit(Callable callable)
: callable_(callable) {}
~ScopeExit() {callable_();}
private:
Callable callable_;
};
template<typename Callable>
ScopeExit<Callable>
make_scope_exit(Callable callable)
{
return ScopeExit<Callable>(callable);
}
} // namespace rclcpp
#define RCLCPP_SCOPE_EXIT(code) \
auto RCLCPP_STRING_JOIN(scope_exit_, __LINE__) = rclcpp::make_scope_exit([&]() {code;})
#endif // RCLCPP__SCOPE_EXIT_HPP_

View File

@@ -144,7 +144,7 @@ public:
// NOTE(methylDragon): Passing these args separately is necessary for event binding
options.event_callbacks,
options.use_default_callbacks,
callback.is_serialized_message_callback() ? SubscriptionType::SERIALIZED_MESSAGE : SubscriptionType::ROS_MESSAGE), // NOLINT
callback.is_serialized_message_callback()),
any_callback_(callback),
options_(options),
message_memory_strategy_(message_memory_strategy)
@@ -388,57 +388,6 @@ public:
return any_callback_.use_take_shared_method();
}
// DYNAMIC TYPE ==================================================================================
// TODO(methylDragon): Reorder later
// TODO(methylDragon): Implement later...
rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr
get_shared_dynamic_message_type() override
{
throw rclcpp::exceptions::UnimplementedError(
"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");
}
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");
}
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 & message,
const rclcpp::MessageInfo & message_info) override
{
(void) message;
(void) message_info;
throw rclcpp::exceptions::UnimplementedError(
"handle_dynamic_message is not implemented for Subscription");
}
private:
RCLCPP_DISABLE_COPY(Subscription)

View File

@@ -31,9 +31,6 @@
#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"
@@ -63,14 +60,6 @@ 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<SubscriptionBase>
@@ -87,7 +76,7 @@ public:
* \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] subscription_type Enum flag to change how the message will be received and delivered
* \param[in] is_serialized is true if the message will be delivered still serialized
*/
RCLCPP_PUBLIC
SubscriptionBase(
@@ -97,7 +86,7 @@ public:
const rcl_subscription_options_t & subscription_options,
const SubscriptionEventCallbacks & event_callbacks,
bool use_default_callbacks,
SubscriptionType subscription_type = SubscriptionType::ROS_MESSAGE);
bool is_serialized = false);
/// Destructor.
RCLCPP_PUBLIC
@@ -238,13 +227,13 @@ public:
const rosidl_message_type_support_t &
get_message_type_support_handle() const;
/// Return the type of the subscription.
/// Return if the subscription is serialized
/**
* \return `SubscriptionType`, which adjusts how messages are received and delivered.
* \return `true` if the subscription is serialized, `false` otherwise
*/
RCLCPP_PUBLIC
SubscriptionType
get_subscription_type() const;
bool
is_serialized() const;
/// Get matching publisher count.
/** \return The number of publishers on this topic. */
@@ -546,49 +535,6 @@ public:
rclcpp::ContentFilterOptions
get_content_filter() const;
// DYNAMIC TYPE ==================================================================================
// TODO(methylDragon): Reorder later
RCLCPP_PUBLIC
virtual
rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr
get_shared_dynamic_message_type() = 0;
RCLCPP_PUBLIC
virtual
rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr
get_shared_dynamic_message() = 0;
RCLCPP_PUBLIC
virtual
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 & message,
const rclcpp::MessageInfo & message_info) = 0;
RCLCPP_PUBLIC
bool
take_dynamic_message(
rclcpp::dynamic_typesupport::DynamicMessage & message_out,
rclcpp::MessageInfo & message_info_out);
// ===============================================================================================
protected:
template<typename EventCallbackT>
void
@@ -622,10 +568,6 @@ protected:
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<rcl_node_t> node_handle_;
std::shared_ptr<rcl_subscription_t> subscription_handle_;
std::shared_ptr<rcl_subscription_t> intra_process_subscription_handle_;
@@ -645,7 +587,7 @@ private:
RCLCPP_DISABLE_COPY(SubscriptionBase)
rosidl_message_type_support_t type_support_;
SubscriptionType subscription_type_;
bool is_serialized_;
std::atomic<bool> subscription_in_use_by_wait_set_{false};
std::atomic<bool> intra_process_subscription_waitable_in_use_by_wait_set_{false};

View File

@@ -1,113 +0,0 @@
// 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/dynamic_subscription.hpp"
#include <memory>
#include <string>
#include "rcl/subscription.h"
#include "rclcpp/exceptions.hpp"
namespace rclcpp
{
std::shared_ptr<void> DynamicSubscription::create_message()
{
return create_serialized_message();
}
std::shared_ptr<rclcpp::SerializedMessage> DynamicSubscription::create_serialized_message()
{
return std::make_shared<rclcpp::SerializedMessage>(0);
}
void DynamicSubscription::handle_message(std::shared_ptr<void> &, const rclcpp::MessageInfo &)
{
throw rclcpp::exceptions::UnimplementedError(
"handle_message is not implemented for DynamicSubscription");
}
void DynamicSubscription::handle_serialized_message(
const std::shared_ptr<rclcpp::SerializedMessage> &, const rclcpp::MessageInfo &)
{
throw rclcpp::exceptions::UnimplementedError(
"handle_serialized_message is not implemented for DynamicSubscription");
}
void DynamicSubscription::handle_loaned_message(void *, const rclcpp::MessageInfo &)
{
throw rclcpp::exceptions::UnimplementedError(
"handle_loaned_message is not implemented for DynamicSubscription");
}
void DynamicSubscription::return_message(std::shared_ptr<void> & message)
{
auto typed_message = std::static_pointer_cast<rclcpp::SerializedMessage>(message);
return_serialized_message(typed_message);
}
void DynamicSubscription::return_serialized_message(
std::shared_ptr<rclcpp::SerializedMessage> & message)
{
message.reset();
}
// 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()
{
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,
const rclcpp::MessageInfo & message_info)
{
(void) message_info;
callback_(message, ts_->get_rosidl_runtime_c_type_description());
}
} // namespace rclcpp

View File

@@ -0,0 +1,641 @@
// 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 <memory>
#include <string>
#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 "rcl/types.h"
#include "rcutils/logging_macros.h"
#include <rosidl_dynamic_typesupport/api/dynamic_type.h>
#include <rosidl_dynamic_typesupport/api/dynamic_data.h>
#include <rosidl_dynamic_typesupport/types.h>
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_typesupport_dynamic_data_t> 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<rosidl_dynamic_typesupport_dynamic_data_t>
DynamicData::get_shared_rosidl_dynamic_data()
{
return std::shared_ptr<rosidl_dynamic_typesupport_dynamic_data_t>(
shared_from_this(), rosidl_dynamic_data_.get());
}
std::shared_ptr<const rosidl_dynamic_typesupport_dynamic_data_t>
DynamicData::get_shared_rosidl_dynamic_data() const
{
return std::shared_ptr<rosidl_dynamic_typesupport_dynamic_data_t>(
shared_from_this(), rosidl_dynamic_data_.get());
}
DynamicSerializationSupport::SharedPtr
DynamicData::get_shared_dynamic_serialization_support()
{
return serialization_support_;
}
DynamicSerializationSupport::ConstSharedPtr
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(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)
{
return rosidl_dynamic_typesupport_dynamic_data_deserialize(get_rosidl_dynamic_data(), buffer);
}
// 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;
}

View File

@@ -1,769 +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 <rosidl_dynamic_typesupport/api/dynamic_type.h>
#include <rosidl_dynamic_typesupport/api/dynamic_data.h>
#include <rosidl_dynamic_typesupport/api/serialization_support.h>
#include <rosidl_dynamic_typesupport/types.h>
#include <memory>
#include <string>
#include "rcl/allocator.h"
#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"
using rclcpp::dynamic_typesupport::DynamicMessage;
using rclcpp::dynamic_typesupport::DynamicMessageType;
using rclcpp::dynamic_typesupport::DynamicMessageTypeBuilder;
using rclcpp::dynamic_typesupport::DynamicSerializationSupport;
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_IMPL_HPP_
// Template specialization implementations
#include "rclcpp/dynamic_typesupport/detail/dynamic_message_impl.hpp"
#endif
// CONSTRUCTION ==================================================================================
DynamicMessage::DynamicMessage(const DynamicMessageTypeBuilder::SharedPtr dynamic_type_builder)
: DynamicMessage::DynamicMessage(
dynamic_type_builder, dynamic_type_builder->get_rosidl_dynamic_type_builder().allocator) {}
DynamicMessage::DynamicMessage(
const DynamicMessageTypeBuilder::SharedPtr dynamic_type_builder,
rcl_allocator_t allocator)
: serialization_support_(dynamic_type_builder->get_shared_dynamic_serialization_support()),
rosidl_dynamic_data_(rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data()),
is_loaned_(false),
parent_data_(nullptr)
{
if (!serialization_support_) {
throw std::runtime_error("dynamic message could not bind serialization support!");
}
if (!dynamic_type_builder) {
throw std::runtime_error("dynamic message type builder cannot be nullptr!");
}
rosidl_dynamic_typesupport_dynamic_type_builder_t rosidl_dynamic_type_builder =
dynamic_type_builder->get_rosidl_dynamic_type_builder();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type_builder(
&rosidl_dynamic_type_builder, &allocator, &get_rosidl_dynamic_data());
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error("could not init new dynamic data object from dynamic type builder");
}
}
DynamicMessage::DynamicMessage(const DynamicMessageType::SharedPtr dynamic_type)
: DynamicMessage::DynamicMessage(
dynamic_type, dynamic_type->get_rosidl_dynamic_type().allocator) {}
DynamicMessage::DynamicMessage(
const DynamicMessageType::SharedPtr dynamic_type,
rcl_allocator_t allocator)
: serialization_support_(dynamic_type->get_shared_dynamic_serialization_support()),
rosidl_dynamic_data_(rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data()),
is_loaned_(false),
parent_data_(nullptr)
{
if (!serialization_support_) {
throw std::runtime_error("dynamic type could not bind serialization support!");
}
if (!dynamic_type) {
throw std::runtime_error("dynamic message type cannot be nullptr!");
}
rosidl_dynamic_typesupport_dynamic_type_t rosidl_dynamic_type =
dynamic_type->get_rosidl_dynamic_type();
rosidl_dynamic_typesupport_dynamic_data_t rosidl_dynamic_data =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(
&rosidl_dynamic_type, &allocator, &rosidl_dynamic_data);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not init new dynamic data object from dynamic type") +
rcl_get_error_string().str);
}
}
DynamicMessage::DynamicMessage(
DynamicSerializationSupport::SharedPtr serialization_support,
rosidl_dynamic_typesupport_dynamic_data_t && rosidl_dynamic_data)
: serialization_support_(serialization_support),
rosidl_dynamic_data_(std::move(rosidl_dynamic_data)),
is_loaned_(false),
parent_data_(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!");
}
}
}
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_(std::move(rosidl_loaned_data)),
is_loaned_(true),
parent_data_(nullptr)
{
if (!parent_data) {
throw std::runtime_error("parent 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!");
}
}
parent_data_ = parent_data;
}
DynamicMessage::DynamicMessage(DynamicMessage && other) noexcept
: serialization_support_(std::exchange(other.serialization_support_, nullptr)),
rosidl_dynamic_data_(std::exchange(
other.rosidl_dynamic_data_,
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data())),
is_loaned_(other.is_loaned_),
parent_data_(std::exchange(other.parent_data_, nullptr))
{}
DynamicMessage &
DynamicMessage::operator=(DynamicMessage && 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;
}
DynamicMessage::~DynamicMessage()
{
if (!is_loaned_) {
if (rosidl_dynamic_typesupport_dynamic_data_fini(&get_rosidl_dynamic_data()) !=
RCUTILS_RET_OK)
{
RCUTILS_LOG_ERROR("could not fini rosidl dynamic data");
}
return;
}
// Loaned case
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
DynamicMessage::match_serialization_support_(
const DynamicSerializationSupport & serialization_support,
const rosidl_dynamic_typesupport_dynamic_data_t & rosidl_dynamic_type_data)
{
if (serialization_support.get_serialization_library_identifier() != std::string(
rosidl_dynamic_type_data.serialization_support->serialization_library_identifier))
{
RCUTILS_LOG_ERROR("serialization support library identifier does not match dynamic data's");
return false;
}
return true;
}
// GETTERS =======================================================================================
const std::string
DynamicMessage::get_serialization_library_identifier() const
{
return std::string(
get_rosidl_dynamic_data().serialization_support->serialization_library_identifier);
}
const std::string
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);
}
return std::string(buf, buf_length);
}
rosidl_dynamic_typesupport_dynamic_data_t &
DynamicMessage::get_rosidl_dynamic_data()
{
return rosidl_dynamic_data_;
}
const rosidl_dynamic_typesupport_dynamic_data_t &
DynamicMessage::get_rosidl_dynamic_data() const
{
return rosidl_dynamic_data_;
}
DynamicSerializationSupport::SharedPtr
DynamicMessage::get_shared_dynamic_serialization_support()
{
return serialization_support_;
}
DynamicSerializationSupport::ConstSharedPtr
DynamicMessage::get_shared_dynamic_serialization_support() const
{
return serialization_support_;
}
size_t
DynamicMessage::get_item_count() const
{
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
{
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
{
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
{
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;
}
rosidl_dynamic_typesupport_member_id_t
DynamicMessage::get_array_index(const std::string & name) const
{
return get_array_index(get_member_id(name));
}
// METHODS =======================================================================================
DynamicMessage
DynamicMessage::clone(rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_data_t rosidl_dynamic_data =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_clone(
&get_rosidl_dynamic_data(), &allocator, &rosidl_dynamic_data);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not clone dynamic data: ") + rcl_get_error_string().str);
}
return DynamicMessage(get_shared_dynamic_serialization_support(), std::move(rosidl_dynamic_data));
}
DynamicMessage::SharedPtr
DynamicMessage::clone_shared(rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_data_t rosidl_dynamic_data =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_clone(
&get_rosidl_dynamic_data(), &allocator, &rosidl_dynamic_data);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not clone dynamic data: ") + rcl_get_error_string().str);
}
return DynamicMessage::make_shared(
get_shared_dynamic_serialization_support(), std::move(rosidl_dynamic_data));
}
DynamicMessage
DynamicMessage::init_from_type(DynamicMessageType & type, rcl_allocator_t allocator) const
{
rosidl_dynamic_typesupport_dynamic_data_t rosidl_dynamic_data =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(
&type.get_rosidl_dynamic_type(), &allocator, &rosidl_dynamic_data);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error("could not init new dynamic data object from dynamic type");
}
return DynamicMessage(serialization_support_, std::move(rosidl_dynamic_data));
}
DynamicMessage::SharedPtr
DynamicMessage::init_from_type_shared(DynamicMessageType & type, rcl_allocator_t allocator) const
{
rosidl_dynamic_typesupport_dynamic_data_t rosidl_dynamic_data =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_init_from_dynamic_type(
&type.get_rosidl_dynamic_type(), &allocator, &rosidl_dynamic_data);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error("could not init new dynamic data object from dynamic type");
}
return DynamicMessage::make_shared(serialization_support_, std::move(rosidl_dynamic_data));
}
bool
DynamicMessage::equals(const DynamicMessage & other) const
{
if (get_serialization_library_identifier() != other.get_serialization_library_identifier()) {
throw std::runtime_error("library identifiers don't match");
}
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,
rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_data_t rosidl_dynamic_data =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_loan_value(
&get_rosidl_dynamic_data(), id, &allocator, &rosidl_dynamic_data);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not loan dynamic data: ") + rcl_get_error_string().str);
}
return DynamicMessage::make_shared(shared_from_this(), std::move(rosidl_dynamic_data));
}
DynamicMessage::SharedPtr
DynamicMessage::loan_value(const std::string & name, rcl_allocator_t allocator)
{
return loan_value(get_member_id(name), allocator);
}
void
DynamicMessage::clear_all_values()
{
rosidl_dynamic_typesupport_dynamic_data_clear_all_values(&get_rosidl_dynamic_data());
}
void
DynamicMessage::clear_nonkey_values()
{
rosidl_dynamic_typesupport_dynamic_data_clear_nonkey_values(&get_rosidl_dynamic_data());
}
void
DynamicMessage::clear_value(rosidl_dynamic_typesupport_member_id_t id)
{
rosidl_dynamic_typesupport_dynamic_data_clear_value(&get_rosidl_dynamic_data(), id);
}
void
DynamicMessage::clear_value(const std::string & name)
{
clear_value(get_member_id(name));
}
void
DynamicMessage::clear_sequence()
{
rosidl_dynamic_typesupport_dynamic_data_clear_sequence_data(&get_rosidl_dynamic_data());
}
rosidl_dynamic_typesupport_member_id_t
DynamicMessage::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
DynamicMessage::remove_sequence_data(rosidl_dynamic_typesupport_member_id_t index)
{
rosidl_dynamic_typesupport_dynamic_data_remove_sequence_data(
&get_rosidl_dynamic_data(), index);
}
bool
DynamicMessage::serialize(rcl_serialized_message_t & buffer)
{
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_serialize(
&get_rosidl_dynamic_data(), &buffer);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could serialize loan dynamic data: ") + rcl_get_error_string().str);
}
return true;
}
bool
DynamicMessage::deserialize(rcl_serialized_message_t & buffer)
{
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_data_deserialize(
&get_rosidl_dynamic_data(), &buffer);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could deserialize loan dynamic data: ") + rcl_get_error_string().str);
}
return true;
}
// MEMBER ACCESS ===================================================================================
// Defined in "detail/dynamic_message_impl.hpp"
// FIXED STRING MEMBER ACCESS ======================================================================
const std::string
DynamicMessage::get_fixed_string_value(
rosidl_dynamic_typesupport_member_id_t id, size_t string_length)
{
size_t buf_length;
char * buf = nullptr;
rosidl_dynamic_typesupport_dynamic_data_get_fixed_string_value(
&get_rosidl_dynamic_data(), id, &buf, &buf_length, string_length);
auto out = std::string(buf, buf_length);
delete buf;
return out;
}
const std::string
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
DynamicMessage::get_fixed_wstring_value(
rosidl_dynamic_typesupport_member_id_t id, size_t wstring_length)
{
size_t buf_length;
char16_t * buf = nullptr;
rosidl_dynamic_typesupport_dynamic_data_get_fixed_wstring_value(
&get_rosidl_dynamic_data(), id, &buf, &buf_length, wstring_length);
auto out = std::u16string(buf, buf_length);
delete buf;
return out;
}
const std::u16string
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
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(
&get_rosidl_dynamic_data(), id, value.c_str(), value.size(), string_length);
}
void
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);
}
void
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(
&get_rosidl_dynamic_data(), id, value.c_str(), value.size(), wstring_length);
}
void
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);
}
rosidl_dynamic_typesupport_member_id_t
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(
&get_rosidl_dynamic_data(), value.c_str(), value.size(), string_length, &out);
return out;
}
rosidl_dynamic_typesupport_member_id_t
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(
&get_rosidl_dynamic_data(), value.c_str(), value.size(), wstring_length, &out);
return out;
}
// BOUNDED STRING MEMBER ACCESS ====================================================================
const std::string
DynamicMessage::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);
delete buf;
return out;
}
const std::string
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
DynamicMessage::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);
delete buf;
return out;
}
const std::u16string
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
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(
&get_rosidl_dynamic_data(), id, value.c_str(), value.size(), string_bound);
}
void
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);
}
void
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(
&get_rosidl_dynamic_data(), id, value.c_str(), value.size(), wstring_bound);
}
void
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);
}
rosidl_dynamic_typesupport_member_id_t
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(
&get_rosidl_dynamic_data(), value.c_str(), value.size(), string_bound, &out);
return out;
}
rosidl_dynamic_typesupport_member_id_t
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(
&get_rosidl_dynamic_data(), value.c_str(), value.size(), wstring_bound, &out);
return out;
}
// NESTED MEMBER ACCESS ============================================================================
DynamicMessage
DynamicMessage::get_complex_value(
rosidl_dynamic_typesupport_member_id_t id, rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_data_t out =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data();
rosidl_dynamic_typesupport_dynamic_data_get_complex_value(
&get_rosidl_dynamic_data(), id, &allocator, &out);
return DynamicMessage(get_shared_dynamic_serialization_support(), std::move(out));
}
DynamicMessage
DynamicMessage::get_complex_value(const std::string & name, rcl_allocator_t allocator)
{
return get_complex_value(get_member_id(name), allocator);
}
DynamicMessage::SharedPtr
DynamicMessage::get_complex_value_shared(
rosidl_dynamic_typesupport_member_id_t id, rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_data_t out =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_data();
rosidl_dynamic_typesupport_dynamic_data_get_complex_value(
&get_rosidl_dynamic_data(), id, &allocator, &out);
return DynamicMessage::make_shared(get_shared_dynamic_serialization_support(), std::move(out));
}
DynamicMessage::SharedPtr
DynamicMessage::get_complex_value_shared(const std::string & name, rcl_allocator_t allocator)
{
return get_complex_value_shared(get_member_id(name), allocator);
}
void
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());
}
void
DynamicMessage::set_complex_value(const std::string & name, DynamicMessage & value)
{
set_complex_value(get_member_id(name), value);
}
rosidl_dynamic_typesupport_member_id_t
DynamicMessage::insert_complex_value_copy(const DynamicMessage & 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
DynamicMessage::insert_complex_value(DynamicMessage & 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;
}

View File

@@ -1,281 +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 <rosidl_dynamic_typesupport/api/dynamic_data.h>
#include <rosidl_dynamic_typesupport/api/dynamic_type.h>
#include <rosidl_dynamic_typesupport/api/serialization_support.h>
#include <rosidl_dynamic_typesupport/types.h>
#include <memory>
#include <string>
#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"
using rclcpp::dynamic_typesupport::DynamicMessage;
using rclcpp::dynamic_typesupport::DynamicMessageType;
using rclcpp::dynamic_typesupport::DynamicMessageTypeBuilder;
using rclcpp::dynamic_typesupport::DynamicSerializationSupport;
// CONSTRUCTION ====================================================================================
DynamicMessageType::DynamicMessageType(DynamicMessageTypeBuilder::SharedPtr dynamic_type_builder)
: DynamicMessageType::DynamicMessageType(
dynamic_type_builder, dynamic_type_builder->get_rosidl_dynamic_type_builder().allocator) {}
DynamicMessageType::DynamicMessageType(
DynamicMessageTypeBuilder::SharedPtr dynamic_type_builder,
rcl_allocator_t allocator)
: serialization_support_(dynamic_type_builder->get_shared_dynamic_serialization_support()),
rosidl_dynamic_type_(rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type())
{
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();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_init_from_dynamic_type_builder(
&rosidl_dynamic_type_builder, &allocator, &get_rosidl_dynamic_type());
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error("could not init new dynamic type object");
}
}
DynamicMessageType::DynamicMessageType(
DynamicSerializationSupport::SharedPtr serialization_support,
rosidl_dynamic_typesupport_dynamic_type_t && rosidl_dynamic_type)
: serialization_support_(serialization_support),
rosidl_dynamic_type_(std::move(rosidl_dynamic_type))
{
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!");
}
}
}
DynamicMessageType::DynamicMessageType(
DynamicSerializationSupport::SharedPtr serialization_support,
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator)
: serialization_support_(serialization_support),
rosidl_dynamic_type_(rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type())
{
init_from_description(description, allocator, serialization_support);
}
DynamicMessageType::DynamicMessageType(DynamicMessageType && other) noexcept
: serialization_support_(std::exchange(other.serialization_support_, nullptr)),
rosidl_dynamic_type_(std::exchange(
other.rosidl_dynamic_type_, rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type()))
{}
DynamicMessageType &
DynamicMessageType::operator=(DynamicMessageType && other) noexcept
{
std::swap(serialization_support_, other.serialization_support_);
std::swap(rosidl_dynamic_type_, other.rosidl_dynamic_type_);
return *this;
}
DynamicMessageType::~DynamicMessageType()
{
if (rosidl_dynamic_typesupport_dynamic_type_fini(&get_rosidl_dynamic_type()) != RCUTILS_RET_OK) {
RCUTILS_LOG_ERROR("could not fini rosidl dynamic type");
}
}
void
DynamicMessageType::init_from_description(
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator,
DynamicSerializationSupport::SharedPtr serialization_support)
{
if (serialization_support) {
// Swap serialization support if serialization support is given
serialization_support_ = serialization_support;
}
rosidl_dynamic_typesupport_dynamic_type_t rosidl_dynamic_type =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_init_from_description(
&serialization_support_->get_rosidl_serialization_support(),
&description,
&allocator,
&rosidl_dynamic_type);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error("could not init new dynamic type object");
}
rosidl_dynamic_type_ = std::move(rosidl_dynamic_type);
}
bool
DynamicMessageType::match_serialization_support_(
const DynamicSerializationSupport & serialization_support,
const rosidl_dynamic_typesupport_dynamic_type_t & rosidl_dynamic_type)
{
if (serialization_support.get_serialization_library_identifier() != std::string(
rosidl_dynamic_type.serialization_support->serialization_library_identifier))
{
RCUTILS_LOG_ERROR(
"serialization support library identifier does not match dynamic type's (%s vs %s)",
serialization_support.get_serialization_library_identifier().c_str(),
rosidl_dynamic_type.serialization_support->serialization_library_identifier);
return false;
}
return true;
}
// GETTERS =========================================================================================
const std::string
DynamicMessageType::get_serialization_library_identifier() const
{
return std::string(
get_rosidl_dynamic_type().serialization_support->serialization_library_identifier);
}
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, &buf_length);
return std::string(buf, buf_length);
}
size_t
DynamicMessageType::get_member_count() const
{
size_t out;
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_get_member_count(
&get_rosidl_dynamic_type(), &out);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not get member count: ") + rcl_get_error_string().str);
}
return out;
}
rosidl_dynamic_typesupport_dynamic_type_t &
DynamicMessageType::get_rosidl_dynamic_type()
{
return rosidl_dynamic_type_;
}
const rosidl_dynamic_typesupport_dynamic_type_t &
DynamicMessageType::get_rosidl_dynamic_type() const
{
return rosidl_dynamic_type_;
}
DynamicSerializationSupport::SharedPtr
DynamicMessageType::get_shared_dynamic_serialization_support()
{
return serialization_support_;
}
DynamicSerializationSupport::ConstSharedPtr
DynamicMessageType::get_shared_dynamic_serialization_support() const
{
return serialization_support_;
}
// METHODS =========================================================================================
DynamicMessageType
DynamicMessageType::clone(rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_type_t rosidl_dynamic_type =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_clone(
&get_rosidl_dynamic_type(), &allocator, &rosidl_dynamic_type);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not clone dynamic type: ") + rcl_get_error_string().str);
}
return DynamicMessageType(
get_shared_dynamic_serialization_support(), std::move(rosidl_dynamic_type));
}
DynamicMessageType::SharedPtr
DynamicMessageType::clone_shared(rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_type_t rosidl_dynamic_type =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_clone(
&get_rosidl_dynamic_type(), &allocator, &rosidl_dynamic_type);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not clone dynamic type: ") + rcl_get_error_string().str);
}
return DynamicMessageType::make_shared(
get_shared_dynamic_serialization_support(), std::move(rosidl_dynamic_type));
}
bool
DynamicMessageType::equals(const DynamicMessageType & other) const
{
if (get_serialization_library_identifier() != other.get_serialization_library_identifier()) {
throw std::runtime_error("library identifiers don't match");
}
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;
}
DynamicMessage
DynamicMessageType::build_dynamic_message(rcl_allocator_t allocator)
{
return DynamicMessage(shared_from_this(), allocator);
}
DynamicMessage::SharedPtr
DynamicMessageType::build_dynamic_message_shared(rcl_allocator_t allocator)
{
return DynamicMessage::make_shared(shared_from_this(), allocator);
}

View File

@@ -1,614 +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 <rosidl_dynamic_typesupport/api/dynamic_data.h>
#include <rosidl_dynamic_typesupport/api/dynamic_type.h>
#include <rosidl_dynamic_typesupport/api/serialization_support.h>
#include <rosidl_dynamic_typesupport/types.h>
#include <memory>
#include <string>
#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"
using rclcpp::dynamic_typesupport::DynamicMessage;
using rclcpp::dynamic_typesupport::DynamicMessageType;
using rclcpp::dynamic_typesupport::DynamicMessageTypeBuilder;
using rclcpp::dynamic_typesupport::DynamicSerializationSupport;
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DETAIL__DYNAMIC_MESSAGE_TYPE_BUILDER_IMPL_HPP_
// Template specialization implementations
#include "rclcpp/dynamic_typesupport/detail/dynamic_message_type_builder_impl.hpp"
#endif
// CONSTRUCTION ====================================================================================
DynamicMessageTypeBuilder::DynamicMessageTypeBuilder(
DynamicSerializationSupport::SharedPtr serialization_support, const std::string & name)
: DynamicMessageTypeBuilder::DynamicMessageTypeBuilder(
serialization_support,
name,
serialization_support->get_rosidl_serialization_support().allocator) {}
DynamicMessageTypeBuilder::DynamicMessageTypeBuilder(
DynamicSerializationSupport::SharedPtr serialization_support,
const std::string & name,
rcl_allocator_t allocator)
: serialization_support_(serialization_support),
rosidl_dynamic_type_builder_(
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type_builder())
{
init_from_serialization_support_(serialization_support, name, allocator);
}
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_(
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type_builder())
{
if (!serialization_support) {
throw std::runtime_error("serialization support 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!");
}
}
DynamicMessageTypeBuilder::DynamicMessageTypeBuilder(
DynamicSerializationSupport::SharedPtr serialization_support,
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator)
: serialization_support_(serialization_support),
rosidl_dynamic_type_builder_(
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type_builder())
{
if (!serialization_support) {
throw std::runtime_error("serialization support cannot be nullptr!");
}
init_from_description(description, allocator, serialization_support);
}
DynamicMessageTypeBuilder::DynamicMessageTypeBuilder(DynamicMessageTypeBuilder && other) noexcept
: serialization_support_(std::exchange(other.serialization_support_, nullptr)),
rosidl_dynamic_type_builder_(std::exchange(
other.rosidl_dynamic_type_builder_,
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type_builder())) {}
DynamicMessageTypeBuilder &
DynamicMessageTypeBuilder::operator=(DynamicMessageTypeBuilder && other) noexcept
{
std::swap(serialization_support_, other.serialization_support_);
std::swap(rosidl_dynamic_type_builder_, other.rosidl_dynamic_type_builder_);
return *this;
}
DynamicMessageTypeBuilder::~DynamicMessageTypeBuilder()
{
if (rosidl_dynamic_typesupport_dynamic_type_builder_fini(&get_rosidl_dynamic_type_builder()) !=
RCUTILS_RET_OK)
{
RCUTILS_LOG_ERROR("could not fini rosidl dynamic type builder");
}
}
void
DynamicMessageTypeBuilder::init_from_description(
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator,
DynamicSerializationSupport::SharedPtr serialization_support)
{
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 =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type_builder();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_init_from_description(
&serialization_support_->get_rosidl_serialization_support(),
&description,
&allocator,
&rosidl_dynamic_type_builder);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error("could not init new dynamic type builder object");
}
rosidl_dynamic_type_builder_ = std::move(rosidl_dynamic_type_builder);
}
void
DynamicMessageTypeBuilder::init_from_serialization_support_(
DynamicSerializationSupport::SharedPtr serialization_support,
const std::string & name,
rcl_allocator_t allocator)
{
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 =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type_builder();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_init(
&serialization_support->get_rosidl_serialization_support(),
name.c_str(), name.size(),
&allocator,
&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);
}
}
bool
DynamicMessageTypeBuilder::match_serialization_support_(
const DynamicSerializationSupport & serialization_support,
const rosidl_dynamic_typesupport_dynamic_type_builder_t & rosidl_dynamic_type_builder)
{
if (serialization_support.get_serialization_library_identifier() != std::string(
rosidl_dynamic_type_builder.serialization_support->serialization_library_identifier))
{
RCUTILS_LOG_ERROR(
"serialization support library identifier does not match dynamic type builder's");
return false;
}
return true;
}
// GETTERS =======================================================================================
const std::string
DynamicMessageTypeBuilder::get_serialization_library_identifier() const
{
return std::string(
get_rosidl_dynamic_type_builder().serialization_support->serialization_library_identifier);
}
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, &buf_length);
return std::string(buf, buf_length);
}
rosidl_dynamic_typesupport_dynamic_type_builder_t &
DynamicMessageTypeBuilder::get_rosidl_dynamic_type_builder()
{
return rosidl_dynamic_type_builder_;
}
const rosidl_dynamic_typesupport_dynamic_type_builder_t &
DynamicMessageTypeBuilder::get_rosidl_dynamic_type_builder() const
{
return rosidl_dynamic_type_builder_;
}
DynamicSerializationSupport::SharedPtr
DynamicMessageTypeBuilder::get_shared_dynamic_serialization_support()
{
return serialization_support_;
}
DynamicSerializationSupport::ConstSharedPtr
DynamicMessageTypeBuilder::get_shared_dynamic_serialization_support() const
{
return serialization_support_;
}
// METHODS =======================================================================================
void
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());
}
DynamicMessageTypeBuilder
DynamicMessageTypeBuilder::clone(rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_type_builder_t rosidl_dynamic_type_builder =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type_builder();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_clone(
&get_rosidl_dynamic_type_builder(), &allocator, &rosidl_dynamic_type_builder);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not clone dynamic type builder: ") + rcl_get_error_string().str);
}
return DynamicMessageTypeBuilder(
get_shared_dynamic_serialization_support(), std::move(rosidl_dynamic_type_builder));
}
DynamicMessageTypeBuilder::SharedPtr
DynamicMessageTypeBuilder::clone_shared(rcl_allocator_t allocator)
{
rosidl_dynamic_typesupport_dynamic_type_builder_t rosidl_dynamic_type_builder =
rosidl_dynamic_typesupport_get_zero_initialized_dynamic_type_builder();
rcutils_ret_t ret = rosidl_dynamic_typesupport_dynamic_type_builder_clone(
&get_rosidl_dynamic_type_builder(), &allocator, &rosidl_dynamic_type_builder);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error(
std::string("could not clone dynamic type builder: ") + rcl_get_error_string().str);
}
return DynamicMessageTypeBuilder::make_shared(
get_shared_dynamic_serialization_support(), std::move(rosidl_dynamic_type_builder));
}
void
DynamicMessageTypeBuilder::clear(rcl_allocator_t allocator)
{
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, allocator);
}
DynamicMessage
DynamicMessageTypeBuilder::build_dynamic_message(rcl_allocator_t allocator)
{
return DynamicMessage(shared_from_this(), allocator);
}
DynamicMessage::SharedPtr
DynamicMessageTypeBuilder::build_dynamic_message_shared(rcl_allocator_t allocator)
{
return DynamicMessage::make_shared(shared_from_this(), allocator);
}
DynamicMessageType
DynamicMessageTypeBuilder::build_dynamic_message_type(rcl_allocator_t allocator)
{
return DynamicMessageType(shared_from_this(), allocator);
}
DynamicMessageType::SharedPtr
DynamicMessageTypeBuilder::build_dynamic_message_type_shared(rcl_allocator_t allocator)
{
return DynamicMessageType::make_shared(shared_from_this(), allocator);
}
// ADD MEMBERS =====================================================================================
// Defined in "detail/dynamic_message_type_builder_impl.hpp"
// ADD FIXED STRING MEMBERS ========================================================================
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_fixed_string_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
string_length);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_fixed_wstring_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
wstring_length);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_fixed_string_array_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
string_length, array_length);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_fixed_wstring_array_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
wstring_length, array_length);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_fixed_string_unbounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
string_length);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_fixed_wstring_unbounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
wstring_length);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_fixed_string_bounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
string_length, sequence_bound);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_fixed_wstring_bounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
wstring_length, sequence_bound);
}
// ADD BOUNDED STRING MEMBERS ======================================================================
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_string_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
string_bound);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_wstring_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
wstring_bound);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_string_array_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
string_bound, array_length);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_wstring_array_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
wstring_bound, array_length);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_string_unbounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
string_bound);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_wstring_unbounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
wstring_bound);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_string_bounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
string_bound, sequence_bound);
}
void
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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_bounded_wstring_bounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
wstring_bound, sequence_bound);
}
// ADD NESTED MEMBERS ==============================================================================
void
DynamicMessageTypeBuilder::add_complex_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageType & nested_type, const std::string & default_value)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
&nested_type.get_rosidl_dynamic_type());
}
void
DynamicMessageTypeBuilder::add_complex_array_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
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(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
&nested_type.get_rosidl_dynamic_type(), array_length);
}
void
DynamicMessageTypeBuilder::add_complex_unbounded_sequence_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageType & nested_type, const std::string & default_value)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_unbounded_sequence_member(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
&nested_type.get_rosidl_dynamic_type());
}
void
DynamicMessageTypeBuilder::add_complex_bounded_sequence_member(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
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(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
&nested_type.get_rosidl_dynamic_type(), sequence_bound);
}
void
DynamicMessageTypeBuilder::add_complex_member_builder(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
DynamicMessageTypeBuilder & nested_type_builder, const std::string & default_value)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_member_builder(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
&nested_type_builder.get_rosidl_dynamic_type_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)
{
rosidl_dynamic_typesupport_dynamic_type_builder_add_complex_array_member_builder(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
&nested_type_builder.get_rosidl_dynamic_type_builder(), array_length);
}
void
DynamicMessageTypeBuilder::add_complex_unbounded_sequence_member_builder(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
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(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
&nested_type_builder.get_rosidl_dynamic_type_builder());
}
void
DynamicMessageTypeBuilder::add_complex_bounded_sequence_member_builder(
rosidl_dynamic_typesupport_member_id_t id, const std::string & name,
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(
&get_rosidl_dynamic_type_builder(),
id, name.c_str(), name.size(), default_value.c_str(), default_value.size(),
&nested_type_builder.get_rosidl_dynamic_type_builder(), sequence_bound);
}

View File

@@ -12,306 +12,385 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <rosidl_dynamic_typesupport/identifier.h>
#include <rosidl_dynamic_typesupport/types.h>
#include <rosidl_runtime_c/message_type_support_struct.h>
#include <rosidl_runtime_c/type_description_utils.h>
#include <rosidl_runtime_c/type_description/type_description__functions.h>
#include <rosidl_runtime_c/type_description/type_description__struct.h>
#include <rosidl_runtime_c/type_description/type_source__functions.h>
#include <rosidl_runtime_c/type_description/type_source__struct.h>
#include <memory>
#include <string>
#include "rcl/allocator.h"
#include "rcl/dynamic_message_type_support.h"
#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 "rmw/dynamic_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_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 <rosidl_dynamic_typesupport/types.h>
#include <rosidl_runtime_c/message_type_support_struct.h>
#include "rosidl_runtime_c/type_description_utils.h"
#include <rosidl_runtime_c/type_description/type_description__functions.h>
#include <rosidl_runtime_c/type_description/type_description__struct.h>
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 ====================================================================================
DynamicMessageTypeSupport::DynamicMessageTypeSupport(
const rosidl_runtime_c__type_description__TypeDescription & description,
const std::string & serialization_library_name,
rcl_allocator_t allocator)
rosidl_runtime_c__type_description__TypeDescription * description,
const std::string & serialization_library_name)
: serialization_support_(nullptr),
dynamic_message_type_(nullptr),
dynamic_message_(nullptr),
rosidl_message_type_support_(rosidl_get_zero_initialized_message_type_support_handle())
description_(nullptr),
rosidl_message_type_support_(nullptr)
{
rcl_ret_t ret;
if (serialization_library_name.empty()) {
ret = rcl_dynamic_message_type_support_handle_init(
nullptr, &description, &allocator, &rosidl_message_type_support_);
} else {
ret = rcl_dynamic_message_type_support_handle_init(
serialization_library_name.c_str(), &description, &allocator, &rosidl_message_type_support_);
if (!description) {
throw std::runtime_error("description cannot be nullptr!");
}
if (ret != RCL_RET_OK) {
std::string error_msg =
std::string("error initializing rosidl message type support: ") + rcl_get_error_string().str;
rcl_reset_error();
throw std::runtime_error(error_msg);
}
if (rosidl_message_type_support_.typesupport_identifier !=
rosidl_get_dynamic_typesupport_identifier())
{
throw std::runtime_error("rosidl message type support is of the wrong type");
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!");
}
auto ts_impl = static_cast<rosidl_dynamic_message_type_support_impl_t *>(const_cast<void *>(
rosidl_message_type_support_.data));
init_dynamic_message_type_(serialization_support_, description);
if (!dynamic_message_type_) {
throw std::runtime_error("could not init dynamic message type!");
}
serialization_support_ = DynamicSerializationSupport::make_shared(
std::move(ts_impl->serialization_support));
init_dynamic_message_(dynamic_message_type_);
if (!dynamic_message_) {
throw std::runtime_error("could not init dynamic message!");
}
dynamic_message_type_ = DynamicMessageType::make_shared(
get_shared_dynamic_serialization_support(), std::move(*ts_impl->dynamic_message_type));
dynamic_message_ = DynamicMessage::make_shared(
get_shared_dynamic_serialization_support(), std::move(*ts_impl->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,
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator)
rosidl_runtime_c__type_description__TypeDescription * description)
: serialization_support_(serialization_support),
dynamic_message_type_(nullptr),
dynamic_message_(nullptr),
rosidl_message_type_support_(rosidl_get_zero_initialized_message_type_support_handle())
description_(nullptr),
rosidl_message_type_support_(nullptr)
{
// Check null
if (!serialization_support) {
throw std::runtime_error("serialization_support cannot be nullptr.");
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!");
}
rosidl_type_hash_t type_hash;
rcutils_ret_t hash_ret = rcl_calculate_type_hash(
// TODO(methylDragon): Swap this out with the conversion function when it is ready
reinterpret_cast<const type_description_interfaces__msg__TypeDescription *>(&description),
&type_hash);
if (hash_ret != RCL_RET_OK) {
throw std::runtime_error("failed to get type hash");
init_dynamic_message_(dynamic_message_type_);
if (!dynamic_message_) {
throw std::runtime_error("could not init dynamic message!");
}
rcutils_ret_t ret = rosidl_dynamic_message_type_support_handle_init(
&serialization_support->get_rosidl_serialization_support(),
&type_hash, // type_hash
&description, // type_description
nullptr, // type_description_sources (not implemented for dynamic types)
&allocator,
&rosidl_message_type_support_);
if (ret != RCUTILS_RET_OK) {
throw std::runtime_error("could not init rosidl message type support");
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!");
}
if (rosidl_message_type_support_.typesupport_identifier !=
rosidl_get_dynamic_typesupport_identifier())
{
throw std::runtime_error("rosidl message type support is of the wrong type");
}
auto ts_impl = static_cast<const rosidl_dynamic_message_type_support_impl_t *>(
rosidl_message_type_support_.data);
dynamic_message_type_ = DynamicMessageType::make_shared(
get_shared_dynamic_serialization_support(), std::move(*ts_impl->dynamic_message_type));
dynamic_message_ = DynamicMessage::make_shared(
get_shared_dynamic_serialization_support(), std::move(*ts_impl->dynamic_message));
}
DynamicMessageTypeSupport::DynamicMessageTypeSupport(
DynamicSerializationSupport::SharedPtr serialization_support,
DynamicMessageType::SharedPtr dynamic_message_type,
DynamicMessage::SharedPtr dynamic_message,
const rosidl_runtime_c__type_description__TypeDescription & description,
rcl_allocator_t allocator)
rosidl_runtime_c__type_description__TypeDescription * description)
: serialization_support_(serialization_support),
dynamic_message_type_(dynamic_message_type),
dynamic_message_(dynamic_message),
rosidl_message_type_support_(rosidl_get_zero_initialized_message_type_support_handle())
description_(nullptr),
rosidl_message_type_support_(nullptr)
{
// 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);
});
}
// Check identifiers
if (serialization_support->get_serialization_library_identifier() !=
dynamic_message_type->get_serialization_library_identifier())
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.");
"dynamic message type library identifier!");
}
if (dynamic_message_type->get_serialization_library_identifier() !=
dynamic_message->get_serialization_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!");
}
rosidl_type_hash_t type_hash;
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<const type_description_interfaces__msg__TypeDescription *>(&description),
&type_hash);
if (hash_ret != RCL_RET_OK) {
std::string error_msg = std::string("failed to get type hash: ") + rcl_get_error_string().str;
rcl_reset_error();
throw std::runtime_error(error_msg);
}
auto ts_impl = static_cast<rosidl_dynamic_message_type_support_impl_t *>(
allocator.zero_allocate(1, sizeof(rosidl_dynamic_message_type_support_impl_t), allocator.state)
);
if (!ts_impl) {
throw std::runtime_error("could not allocate rosidl_message_type_support_t");
}
ts_impl->allocator = allocator;
ts_impl->type_hash = type_hash;
if (!rosidl_runtime_c__type_description__TypeDescription__copy(
&description, &ts_impl->type_description))
// 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("could not copy type description");
throw std::runtime_error("serialization support pointer dynamic message type's");
}
// ts_impl->type_description_sources = // Not used
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* */
ts_impl->serialization_support = serialization_support->get_rosidl_serialization_support();
ts_impl->dynamic_message_type = &dynamic_message_type->get_rosidl_dynamic_type();
ts_impl->dynamic_message = &dynamic_message->get_rosidl_dynamic_data();
rosidl_message_type_support_ = {
rosidl_get_dynamic_typesupport_identifier(), // typesupport_identifier
ts_impl, // data
get_message_typesupport_handle_function, // func
// get_type_hash_func
rosidl_get_dynamic_message_type_support_type_hash_function,
// get_type_description_func
rosidl_get_dynamic_message_type_support_type_description_function,
// get_type_description_sources_func
rosidl_get_dynamic_message_type_support_type_description_sources_function
};
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()
{
// These must go first
serialization_support_.reset();
dynamic_message_type_.reset();
dynamic_message_.reset();
// Early return if type support isn't populated to avoid segfaults
if (!rosidl_message_type_support_.data) {
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,
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;
}
// We only partially finalize the rosidl_message_type_support->data since its pointer members are
// managed by their respective SharedPtr wrapper classes.
auto ts_impl = static_cast<rosidl_dynamic_message_type_support_impl_t *>(
const_cast<void *>(rosidl_message_type_support_.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
rosidl_message_type_support_.reset(
new rosidl_message_type_support_t(),
[](rosidl_message_type_support_t * ts) -> void {free(const_cast<void *>(ts->data));}
);
rcutils_allocator_t allocator = ts_impl->allocator;
rosidl_runtime_c__type_description__TypeDescription__fini(&ts_impl->type_description);
rosidl_runtime_c__type_description__TypeSource__Sequence__fini(
&ts_impl->type_description_sources);
allocator.deallocate(static_cast<void *>(ts_impl), allocator.state); // Always C allocated
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();
ts_impl->description = description;
rosidl_message_type_support_->func = get_message_typesupport_handle_function;
}
// GETTERS =========================================================================================
const std::string
DynamicMessageTypeSupport::get_serialization_library_identifier() const
DynamicMessageTypeSupport::get_library_identifier() const
{
return serialization_support_->get_serialization_library_identifier();
return serialization_support_->get_library_identifier();
}
rosidl_message_type_support_t &
rosidl_message_type_support_t *
DynamicMessageTypeSupport::get_rosidl_message_type_support()
{
return rosidl_message_type_support_;
return rosidl_message_type_support_.get();
}
const rosidl_message_type_support_t &
DynamicMessageTypeSupport::get_const_rosidl_message_type_support()
const rosidl_message_type_support_t *
DynamicMessageTypeSupport::get_rosidl_message_type_support() const
{
return rosidl_message_type_support_.get();
}
std::shared_ptr<rosidl_message_type_support_t>
DynamicMessageTypeSupport::get_shared_rosidl_message_type_support()
{
return rosidl_message_type_support_;
}
const rosidl_message_type_support_t &
DynamicMessageTypeSupport::get_const_rosidl_message_type_support() const
std::shared_ptr<const rosidl_message_type_support_t>
DynamicMessageTypeSupport::get_shared_rosidl_message_type_support() const
{
return rosidl_message_type_support_;
}
const rosidl_runtime_c__type_description__TypeDescription &
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
{
auto ts_impl = static_cast<const rosidl_dynamic_message_type_support_impl_t *>(
get_const_rosidl_message_type_support().data
);
return ts_impl->type_description;
return description_.get();
}
std::shared_ptr<rosidl_runtime_c__type_description__TypeDescription>
DynamicMessageTypeSupport::get_shared_rosidl_runtime_c_type_description()
{
return description_;
}
std::shared_ptr<const rosidl_runtime_c__type_description__TypeDescription>
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_;
}
// 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());
}

View File

@@ -12,56 +12,71 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <rcl/allocator.h>
#include <rcutils/logging_macros.h>
#include <rmw/dynamic_message_type_support.h>
#include <rmw/ret_types.h>
#include <rosidl_dynamic_typesupport/api/serialization_support.h>
#include <memory>
#include <string>
#include "rclcpp/dynamic_typesupport/dynamic_serialization_support.hpp"
#include "rclcpp/exceptions.hpp"
#include "rcutils/logging_macros.h"
#include "rmw/dynamic_typesupport.h"
#include <rosidl_dynamic_typesupport/api/serialization_support.h>
using rclcpp::dynamic_typesupport::DynamicSerializationSupport;
// CONSTRUCTION ====================================================================================
DynamicSerializationSupport::DynamicSerializationSupport(rcl_allocator_t allocator)
: DynamicSerializationSupport::DynamicSerializationSupport("", allocator) {}
DynamicSerializationSupport::DynamicSerializationSupport(
const std::string & serialization_library_name,
rcl_allocator_t allocator)
: rosidl_serialization_support_(
rosidl_dynamic_typesupport_get_zero_initialized_serialization_support())
const std::string & serialization_library_name)
: rosidl_serialization_support_(nullptr)
{
rmw_ret_t ret = RMW_RET_ERROR;
rosidl_dynamic_typesupport_serialization_support_t * rosidl_serialization_support = nullptr;
if (serialization_library_name.empty()) {
ret = rmw_serialization_support_init(NULL, &allocator, &rosidl_serialization_support_);
rosidl_serialization_support = rmw_get_serialization_support(NULL);
} else {
ret = rmw_serialization_support_init(
serialization_library_name.c_str(), &allocator, &rosidl_serialization_support_);
rosidl_serialization_support =
rmw_get_serialization_support(serialization_library_name.c_str());
}
if (ret != RCL_RET_OK) {
std::string error_msg =
std::string("could not initialize new serialization support object: ") +
rcl_get_error_string().str;
rcl_reset_error();
throw std::runtime_error(error_msg);
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_destroy(rosidl_serialization_support);
});
}
DynamicSerializationSupport::DynamicSerializationSupport(
rosidl_dynamic_typesupport_serialization_support_t && rosidl_serialization_support)
: rosidl_serialization_support_(std::move(rosidl_serialization_support)) {}
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_destroy(rosidl_serialization_support);
});
}
DynamicSerializationSupport::DynamicSerializationSupport(
std::shared_ptr<rosidl_dynamic_typesupport_serialization_support_t> rosidl_serialization_support)
: rosidl_serialization_support_(rosidl_serialization_support) {}
DynamicSerializationSupport::DynamicSerializationSupport(
DynamicSerializationSupport && other) noexcept
: rosidl_serialization_support_(std::exchange(
other.rosidl_serialization_support_,
rosidl_dynamic_typesupport_get_zero_initialized_serialization_support())) {}
: rosidl_serialization_support_(std::exchange(other.rosidl_serialization_support_, nullptr)) {}
DynamicSerializationSupport &
DynamicSerializationSupport::operator=(DynamicSerializationSupport && other) noexcept
@@ -70,29 +85,45 @@ DynamicSerializationSupport::operator=(DynamicSerializationSupport && other) noe
return *this;
}
DynamicSerializationSupport::~DynamicSerializationSupport()
{
rosidl_dynamic_typesupport_serialization_support_fini(&rosidl_serialization_support_);
}
DynamicSerializationSupport::~DynamicSerializationSupport() {}
// GETTERS =========================================================================================
const std::string
DynamicSerializationSupport::get_serialization_library_identifier() const
DynamicSerializationSupport::get_library_identifier() const
{
return std::string(
rosidl_dynamic_typesupport_serialization_support_get_library_identifier(
&rosidl_serialization_support_));
rosidl_serialization_support_.get()));
}
rosidl_dynamic_typesupport_serialization_support_t &
rosidl_dynamic_typesupport_serialization_support_t *
DynamicSerializationSupport::get_rosidl_serialization_support()
{
return rosidl_serialization_support_;
return rosidl_serialization_support_.get();
}
const rosidl_dynamic_typesupport_serialization_support_t &
const rosidl_dynamic_typesupport_serialization_support_t *
DynamicSerializationSupport::get_rosidl_serialization_support() const
{
return rosidl_serialization_support_;
return rosidl_serialization_support_.get();
}
std::shared_ptr<rosidl_dynamic_typesupport_serialization_support_t>
DynamicSerializationSupport::get_shared_rosidl_serialization_support()
{
return std::shared_ptr<rosidl_dynamic_typesupport_serialization_support_t>(
shared_from_this(), rosidl_serialization_support_.get());
}
std::shared_ptr<const rosidl_dynamic_typesupport_serialization_support_t>
DynamicSerializationSupport::get_shared_rosidl_serialization_support() const
{
return std::shared_ptr<const rosidl_dynamic_typesupport_serialization_support_t>(
shared_from_this(), rosidl_serialization_support_.get());
}

View File

@@ -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 <memory>
#include <string>
#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 <rosidl_dynamic_typesupport/api/dynamic_data.h>
#include <rosidl_dynamic_typesupport/api/dynamic_type.h>
#include <rosidl_dynamic_typesupport/types.h>
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_typesupport_dynamic_type_t> 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<rosidl_dynamic_typesupport_dynamic_type_t>
DynamicType::get_shared_rosidl_dynamic_type()
{
return std::shared_ptr<rosidl_dynamic_typesupport_dynamic_type_t>(
shared_from_this(), rosidl_dynamic_type_.get());
}
std::shared_ptr<const rosidl_dynamic_typesupport_dynamic_type_t>
DynamicType::get_shared_rosidl_dynamic_type() const
{
return std::shared_ptr<rosidl_dynamic_typesupport_dynamic_type_t>(
shared_from_this(), rosidl_dynamic_type_.get());
}
DynamicSerializationSupport::SharedPtr
DynamicType::get_shared_dynamic_serialization_support()
{
return serialization_support_;
}
DynamicSerializationSupport::ConstSharedPtr
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());
}

View File

@@ -0,0 +1,536 @@
// 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 <memory>
#include <string>
#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 <rosidl_dynamic_typesupport/api/dynamic_data.h>
#include <rosidl_dynamic_typesupport/api/dynamic_type.h>
#include <rosidl_dynamic_typesupport/types.h>
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_typesupport_dynamic_type_builder_t> 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<rosidl_dynamic_typesupport_dynamic_type_builder_t>
DynamicTypeBuilder::get_shared_rosidl_dynamic_type_builder()
{
return std::shared_ptr<rosidl_dynamic_typesupport_dynamic_type_builder_t>(
shared_from_this(), rosidl_dynamic_type_builder_.get());
}
std::shared_ptr<const rosidl_dynamic_typesupport_dynamic_type_builder_t>
DynamicTypeBuilder::get_shared_rosidl_dynamic_type_builder() const
{
return std::shared_ptr<rosidl_dynamic_typesupport_dynamic_type_builder_t>(
shared_from_this(), rosidl_dynamic_type_builder_.get());
}
DynamicSerializationSupport::SharedPtr
DynamicTypeBuilder::get_shared_dynamic_serialization_support()
{
return serialization_support_;
}
DynamicSerializationSupport::ConstSharedPtr
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);
}
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);
}

View File

@@ -24,7 +24,6 @@
#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"
@@ -559,14 +558,13 @@ Executor::execute_any_executable(AnyExecutable & any_exec)
}
}
template<typename Taker, typename Handler>
static
void
take_and_do_error_handling(
const char * action_description,
const char * topic_or_service_name,
Taker take_action,
Handler handle_action)
std::function<bool()> take_action,
std::function<void()> handle_action)
{
bool taken = false;
try {
@@ -599,136 +597,70 @@ 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;
switch (subscription->get_subscription_type()) {
// Take ROS message
case rclcpp::SubscriptionType::ROS_MESSAGE:
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<SerializedMessage> 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);},
[&]()
{
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;
}
} else {
// This case is taking a copy of the message data from the middleware via
// inter-process communication.
std::shared_ptr<void> 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->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(),
[&]()
{
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);
}
break;
}
// Take serialized message
case rclcpp::SubscriptionType::SERIALIZED_MESSAGE:
{
// This is the case where a copy of the serialized message is taken from
// the middleware via inter-process communication.
std::shared_ptr<SerializedMessage> 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:
{
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<SerializedMessage> 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;
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;
}
} else {
// This case is taking a copy of the message data from the middleware via
// inter-process communication.
std::shared_ptr<void> 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

View File

@@ -43,7 +43,8 @@ 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<rclcpp::SerializedMessage> & message,
const rclcpp::MessageInfo &)
{
@@ -71,55 +72,4 @@ void GenericSubscription::return_serialized_message(
message.reset();
}
// DYNAMIC TYPE ====================================================================================
// TODO(methylDragon): Reorder later
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");
}
rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr
GenericSubscription::get_shared_dynamic_message()
{
throw rclcpp::exceptions::UnimplementedError(
"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");
}
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 & message,
const rclcpp::MessageInfo & message_info)
{
(void) message;
(void) message_info;
throw rclcpp::exceptions::UnimplementedError(
"handle_dynamic_message is not implemented for GenericSubscription");
}
} // namespace rclcpp

View File

@@ -125,18 +125,4 @@ Logger::set_level(Level level)
}
}
Logger::Level
Logger::get_effective_level() const
{
int logger_level = rcutils_logging_get_logger_effective_level(get_name());
if (logger_level < 0) {
exceptions::throw_from_rcl_error(
RCL_RET_ERROR, "Couldn't get logger level",
rcutils_get_error_state(), rcutils_reset_error);
}
return static_cast<Level>(logger_level);
}
} // namespace rclcpp

View File

@@ -651,7 +651,7 @@ NodeParameters::undeclare_parameter(const std::string & name)
}
if (!parameter_info->second.descriptor.dynamic_typing) {
throw rclcpp::exceptions::InvalidParameterTypeException{
name, "cannot undeclare a statically typed parameter"};
name, "cannot undeclare an statically typed parameter"};
}
parameters_.erase(parameter_info);
@@ -824,7 +824,7 @@ NodeParameters::set_parameters_atomically(const std::vector<rclcpp::Parameter> &
auto it = parameters_.find(parameter.get_name());
if (it != parameters_.end() && rclcpp::PARAMETER_NOT_SET != it->second.value.get_type()) {
if (!it->second.descriptor.dynamic_typing) {
result.reason = "cannot undeclare a statically typed parameter";
result.reason = "cannot undeclare an statically typed parameter";
result.successful = false;
return result;
}

View File

@@ -22,7 +22,6 @@
#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"
@@ -33,8 +32,6 @@
#include "rmw/error_handling.h"
#include "rmw/rmw.h"
#include "rosidl_dynamic_typesupport/types.h"
using rclcpp::SubscriptionBase;
SubscriptionBase::SubscriptionBase(
@@ -44,7 +41,7 @@ SubscriptionBase::SubscriptionBase(
const rcl_subscription_options_t & subscription_options,
const SubscriptionEventCallbacks & event_callbacks,
bool use_default_callbacks,
SubscriptionType subscription_type)
bool is_serialized)
: node_base_(node_base),
node_handle_(node_base_->get_shared_rcl_node_handle()),
node_logger_(rclcpp::get_node_logger(node_handle_.get())),
@@ -52,16 +49,8 @@ SubscriptionBase::SubscriptionBase(
intra_process_subscription_id_(0),
event_callbacks_(event_callbacks),
type_support_(type_support_handle),
subscription_type_(subscription_type)
is_serialized_(is_serialized)
{
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"
);
}
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) {
@@ -266,10 +255,10 @@ SubscriptionBase::get_message_type_support_handle() const
return type_support_;
}
rclcpp::SubscriptionType
SubscriptionBase::get_subscription_type() const
bool
SubscriptionBase::is_serialized() const
{
return subscription_type_;
return is_serialized_;
}
size_t
@@ -453,7 +442,8 @@ SubscriptionBase::set_content_filter(
rcl_subscription_content_filter_options_t options =
rcl_get_zero_initialized_subscription_content_filter_options();
std::vector<const char *> cstrings = get_c_vector_string(expression_parameters);
std::vector<const char *> 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),
@@ -525,24 +515,3 @@ SubscriptionBase::get_content_filter() const
return ret_options;
}
// DYNAMIC TYPE ==================================================================================
// TODO(methylDragon): Reorder later
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;
}

View File

@@ -28,11 +28,6 @@
#include "../../mocking_utils/patch.hpp"
#include "../../utils/rclcpp_gtest_macros.hpp"
using rclcpp::dynamic_typesupport::DynamicMessage;
using rclcpp::dynamic_typesupport::DynamicMessageType;
using rclcpp::dynamic_typesupport::DynamicSerializationSupport;
namespace
{
@@ -82,18 +77,6 @@ public:
const std::shared_ptr<rclcpp::SerializedMessage> &, const rclcpp::MessageInfo &) override {}
void return_message(std::shared_ptr<void> &) override {}
void return_serialized_message(std::shared_ptr<rclcpp::SerializedMessage> &) override {}
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;
}
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

View File

@@ -89,9 +89,9 @@ public:
T2 message;
write_message(data, message);
rclcpp::Serialization<T2> serialization_support;
rclcpp::Serialization<T2> ser;
SerializedMessage result;
serialization_support.serialize_message(&message, &result);
ser.serialize_message(&message, &result);
return result;
}

View File

@@ -160,50 +160,6 @@ TEST(TestLogger, set_level) {
EXPECT_EQ(RCUTILS_RET_OK, rcutils_logging_shutdown());
}
TEST(TestLogger, get_effective_level) {
ASSERT_EQ(RCUTILS_RET_OK, rcutils_logging_initialize());
rclcpp::Logger logger = rclcpp::get_logger("test_logger");
rclcpp::Logger child_logger = rclcpp::get_logger("test_logger.child");
// set child logger level unset to test effective level
child_logger.set_level(rclcpp::Logger::Level::Unset);
// default
EXPECT_EQ(rclcpp::Logger::Level::Info, logger.get_effective_level());
EXPECT_EQ(rclcpp::Logger::Level::Info, child_logger.get_effective_level());
// unset
logger.set_level(rclcpp::Logger::Level::Unset);
EXPECT_EQ(rclcpp::Logger::Level::Info, logger.get_effective_level());
EXPECT_EQ(rclcpp::Logger::Level::Info, child_logger.get_effective_level());
// debug
logger.set_level(rclcpp::Logger::Level::Debug);
EXPECT_EQ(rclcpp::Logger::Level::Debug, logger.get_effective_level());
EXPECT_EQ(rclcpp::Logger::Level::Debug, child_logger.get_effective_level());
// info
logger.set_level(rclcpp::Logger::Level::Info);
EXPECT_EQ(rclcpp::Logger::Level::Info, logger.get_effective_level());
EXPECT_EQ(rclcpp::Logger::Level::Info, child_logger.get_effective_level());
// warn
logger.set_level(rclcpp::Logger::Level::Warn);
EXPECT_EQ(rclcpp::Logger::Level::Warn, logger.get_effective_level());
EXPECT_EQ(rclcpp::Logger::Level::Warn, child_logger.get_effective_level());
// error
logger.set_level(rclcpp::Logger::Level::Error);
EXPECT_EQ(rclcpp::Logger::Level::Error, logger.get_effective_level());
EXPECT_EQ(rclcpp::Logger::Level::Error, child_logger.get_effective_level());
// fatal
logger.set_level(rclcpp::Logger::Level::Fatal);
EXPECT_EQ(rclcpp::Logger::Level::Fatal, logger.get_effective_level());
EXPECT_EQ(rclcpp::Logger::Level::Fatal, child_logger.get_effective_level());
}
TEST(TestLogger, get_logging_directory) {
ASSERT_EQ(true, rcutils_set_env("HOME", "/fake_home_dir"));
ASSERT_EQ(true, rcutils_set_env("USERPROFILE", nullptr));