diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 9193e3f3f9..18c6c16744 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -1592,12 +1592,14 @@ class Node : public std::enable_shared_from_this rclcpp::node_interfaces::NodeClockInterface::SharedPtr node_clock_; rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters_; rclcpp::node_interfaces::NodeTimeSourceInterface::SharedPtr node_time_source_; - rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr node_type_descriptions_; rclcpp::node_interfaces::NodeWaitablesInterface::SharedPtr node_waitables_; const rclcpp::NodeOptions node_options_; const std::string sub_namespace_; const std::string effective_namespace_; + + class BackportMemberMaps; + static BackportMemberMaps backport_member_maps_; }; } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/node.cpp b/rclcpp/src/rclcpp/node.cpp index 52012439e8..32aab85227 100644 --- a/rclcpp/src/rclcpp/node.cpp +++ b/rclcpp/src/rclcpp/node.cpp @@ -110,6 +110,65 @@ create_effective_namespace(const std::string & node_namespace, const std::string } // namespace +/// \brief Associates new hidden backported members with instances of Node. +class Node::BackportMemberMaps +{ +public: + BackportMemberMaps() = default; + + /// \brief Add all backported members for a new Node. + /** + * \param[in] key Raw pointer to the Node instance that will use new members. + */ + void add(Node * key) + { + // Adding a new instance to the maps requires exclusive access + std::unique_lock lock(map_access_mutex_); + type_descriptions_map_.emplace( + key, + std::make_shared( + key->get_node_base_interface(), + key->get_node_logging_interface(), + key->get_node_parameters_interface(), + key->get_node_services_interface())); + } + + /// \brief Remove the members for an instance of Node + /** + * \param[in] key Raw pointer to the Node + */ + void remove(const Node * key) + { + // Removing an instance from the maps requires exclusive access + std::unique_lock lock(map_access_mutex_); + type_descriptions_map_.erase(key); + } + + /// \brief Retrieve the NodeTypeDescriptionsInterface for a Node. + /** + * \param[in] key Raw pointer to an instance of Node. + * \return A shared ptr to this Node's NodeTypeDescriptionsInterface instance. + */ + rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr + get_node_type_descriptions_interface(const Node * key) const + { + // Multiple threads can retrieve from the maps at the same time + std::shared_lock lock(map_access_mutex_); + return type_descriptions_map_.at(key); + } + +private: + /// \brief Map that stored TypeDescriptionsInterface members + std::unordered_map< + const Node *, rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr + > type_descriptions_map_; + + /// \brief Controls access to all private maps + mutable std::shared_mutex map_access_mutex_; +}; +// Definition of static member declaration +Node::BackportMemberMaps Node::backport_member_maps_; + Node::Node( const std::string & node_name, const NodeOptions & options) @@ -207,17 +266,13 @@ Node::Node( options.clock_qos(), options.use_clock_thread() )), - node_type_descriptions_(new rclcpp::node_interfaces::NodeTypeDescriptions( - node_base_, - node_logging_, - node_parameters_, - node_services_ - )), node_waitables_(new rclcpp::node_interfaces::NodeWaitables(node_base_.get())), node_options_(options), sub_namespace_(""), effective_namespace_(create_effective_namespace(this->get_namespace(), sub_namespace_)) { + backport_member_maps_.add(this); + // we have got what we wanted directly from the overrides, // but declare the parameters anyway so they are visible. rclcpp::detail::declare_qos_parameters( @@ -279,6 +334,7 @@ Node::Node( Node::~Node() { // release sub-interfaces in an order that allows them to consult with node_base during tear-down + backport_member_maps_.remove(this); node_waitables_.reset(); node_time_source_.reset(); node_parameters_.reset(); @@ -601,7 +657,7 @@ Node::get_node_topics_interface() rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr Node::get_node_type_descriptions_interface() { - return node_type_descriptions_; + return backport_member_maps_.get_node_type_descriptions_interface(this); } rclcpp::node_interfaces::NodeServicesInterface::SharedPtr diff --git a/rclcpp/src/rclcpp/node_interfaces/node_base.cpp b/rclcpp/src/rclcpp/node_interfaces/node_base.cpp index 36e1afb932..6544d69214 100644 --- a/rclcpp/src/rclcpp/node_interfaces/node_base.cpp +++ b/rclcpp/src/rclcpp/node_interfaces/node_base.cpp @@ -20,7 +20,6 @@ #include "rclcpp/node_interfaces/node_base.hpp" #include "rcl/arguments.h" -#include "rcl/node_type_cache.h" #include "rclcpp/exceptions.hpp" #include "rcutils/logging_macros.h" #include "rmw/validate_namespace.h" diff --git a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp index d3654ab2b2..72581e2b22 100644 --- a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp +++ b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp @@ -824,6 +824,10 @@ class LifecycleNode : public node_interfaces::LifecycleNodeInterface, rclcpp::node_interfaces::NodeTimeSourceInterface::SharedPtr get_node_time_source_interface(); + /// Return the Node's internal NodeTypeDescriptionsInterface implementation. + /** + * \sa rclcpp::Node::get_node_type_descriptions_interface + */ RCLCPP_LIFECYCLE_PUBLIC rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr get_node_type_descriptions_interface(); @@ -1090,7 +1094,6 @@ class LifecycleNode : public node_interfaces::LifecycleNodeInterface, rclcpp::node_interfaces::NodeClockInterface::SharedPtr node_clock_; rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters_; rclcpp::node_interfaces::NodeTimeSourceInterface::SharedPtr node_time_source_; - rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr node_type_descriptions_; rclcpp::node_interfaces::NodeWaitablesInterface::SharedPtr node_waitables_; const rclcpp::NodeOptions node_options_; diff --git a/rclcpp_lifecycle/src/lifecycle_node.cpp b/rclcpp_lifecycle/src/lifecycle_node.cpp index 94629911a3..71deded6b1 100644 --- a/rclcpp_lifecycle/src/lifecycle_node.cpp +++ b/rclcpp_lifecycle/src/lifecycle_node.cpp @@ -114,15 +114,13 @@ LifecycleNode::LifecycleNode( options.clock_qos(), options.use_clock_thread() )), - node_type_descriptions_(new rclcpp::node_interfaces::NodeTypeDescriptions( + node_waitables_(new rclcpp::node_interfaces::NodeWaitables(node_base_.get())), + node_options_(options), + impl_(new LifecycleNodeInterfaceImpl( node_base_, node_logging_, node_parameters_, - node_services_ - )), - node_waitables_(new rclcpp::node_interfaces::NodeWaitables(node_base_.get())), - node_options_(options), - impl_(new LifecycleNodeInterfaceImpl(node_base_, node_services_)) + node_services_)) { impl_->init(enable_communication_interface); @@ -481,6 +479,12 @@ LifecycleNode::get_node_services_interface() return node_services_; } +rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr +LifecycleNode::get_node_type_descriptions_interface() +{ + return impl_->get_node_type_descriptions_interface(); +} + rclcpp::node_interfaces::NodeParametersInterface::SharedPtr LifecycleNode::get_node_parameters_interface() { diff --git a/rclcpp_lifecycle/src/lifecycle_node_interface_impl.cpp b/rclcpp_lifecycle/src/lifecycle_node_interface_impl.cpp index 5c5f7797e1..8d3855aacf 100644 --- a/rclcpp_lifecycle/src/lifecycle_node_interface_impl.cpp +++ b/rclcpp_lifecycle/src/lifecycle_node_interface_impl.cpp @@ -30,6 +30,7 @@ #include "rclcpp/node_interfaces/node_base_interface.hpp" #include "rclcpp/node_interfaces/node_services_interface.hpp" +#include "rclcpp/node_interfaces/node_type_descriptions.hpp" #include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp" @@ -50,9 +51,16 @@ namespace rclcpp_lifecycle LifecycleNode::LifecycleNodeInterfaceImpl::LifecycleNodeInterfaceImpl( std::shared_ptr node_base_interface, + std::shared_ptr node_logging_interface, + std::shared_ptr node_parameters_interface, std::shared_ptr node_services_interface) : node_base_interface_(node_base_interface), - node_services_interface_(node_services_interface) + node_services_interface_(node_services_interface), + node_type_descriptions_(new rclcpp::node_interfaces::NodeTypeDescriptions( + node_base_interface, + node_logging_interface, + node_parameters_interface, + node_services_interface)) { } @@ -581,4 +589,10 @@ LifecycleNode::LifecycleNodeInterfaceImpl::on_deactivate() const } } +rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr +LifecycleNode::LifecycleNodeInterfaceImpl::get_node_type_descriptions_interface() +{ + return node_type_descriptions_; +} + } // namespace rclcpp_lifecycle diff --git a/rclcpp_lifecycle/src/lifecycle_node_interface_impl.hpp b/rclcpp_lifecycle/src/lifecycle_node_interface_impl.hpp index d09f44831c..5db7c31d99 100644 --- a/rclcpp_lifecycle/src/lifecycle_node_interface_impl.hpp +++ b/rclcpp_lifecycle/src/lifecycle_node_interface_impl.hpp @@ -52,6 +52,8 @@ class LifecycleNode::LifecycleNodeInterfaceImpl final public: LifecycleNodeInterfaceImpl( std::shared_ptr node_base_interface, + std::shared_ptr node_logging_interface, + std::shared_ptr node_parameters_interface, std::shared_ptr node_services_interface); ~LifecycleNodeInterfaceImpl(); @@ -102,6 +104,9 @@ class LifecycleNode::LifecycleNodeInterfaceImpl final void add_timer_handle(std::shared_ptr timer); + rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr + get_node_type_descriptions_interface(); + private: RCLCPP_DISABLE_COPY(LifecycleNodeInterfaceImpl) @@ -172,6 +177,9 @@ class LifecycleNode::LifecycleNodeInterfaceImpl final // to controllable things std::vector> weak_managed_entities_; std::vector> weak_timers_; + + // Backported members hidden in impl + rclcpp::node_interfaces::NodeTypeDescriptionsInterface::SharedPtr node_type_descriptions_; }; } // namespace rclcpp_lifecycle