From b1796db7e5af881bbc99dbf1e6b747a3d3270497 Mon Sep 17 00:00:00 2001 From: methylDragon Date: Wed, 9 Nov 2022 23:59:15 -0800 Subject: [PATCH] Use multiple inheritance in NodeInterfaceHandle Signed-off-by: methylDragon --- rclcpp/include/rclcpp/node.hpp | 51 ++- rclcpp/include/rclcpp/node_impl.hpp | 2 +- .../node_interfaces/node_interface_handle.hpp | 330 ++++++------------ .../node_interface_handle_helpers.hpp | 273 +++++++++++++++ .../rclcpp_lifecycle/lifecycle_node.hpp | 47 ++- .../rclcpp_lifecycle/lifecycle_node_impl.hpp | 2 +- 6 files changed, 455 insertions(+), 250 deletions(-) create mode 100644 rclcpp/include/rclcpp/node_interfaces/node_interface_handle_helpers.hpp diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 2520f4444e..07353c8c8d 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -1451,23 +1451,48 @@ class Node : public std::enable_shared_from_this /// Return a NodeInterfaceHandle bound with the Node's internal node interfaces. /** - * Specify which interfaces you want to bind using the temlplate parameters. Any unbound - * interfaces will be nullptr. - * - * For example: - * - ```node->get_node_handle<>()``` will bind no interfaces. - * - ```node->get_node_handle()``` + * Specify which interfaces you want to bind using the template parameters by specifying + * interface support classes to use. Any unmentioned interfaces will be unavailable to bind. + * + * This method will return a NodeInterfaceHandle with no bound interfaces. You must set them using + * ```NodeInterfaceHandle->set__interface(InterfaceT::SharedPtr interface)``` + * + * You may use any of the available support classes in + * node_interfaces/node_interface_handle_helpers.hpp: + * - Base: Supports NodeBaseInterface + * - Clock: Supports NodeClockInterface + * - Graph: Supports NodeGraphInterface + * - Logging: Supports NodeLoggingInterface + * - Parameters: Supports NodeParametersInterface + * - Services: Supports NodeServicesInterface + * - TimeSource: Supports NodeTimeSourceInterface + * - Timers: Supports NodeTimersInterface + * - Topics: Supports NodeTopicsInterface + * - Waitables: Supports NodeWaitablesInterface + * + * Or you can define your own interface support classes! + * + * Each of the support classes should define: + * - Default constructor + * - Templated constructor taking NodeT + * - get_node__interface() + * - set_node__interface() + * + * Usage example: + * - ```NodeInterfaceHandle(node)``` * will bind just the NodeBaseInterface. - * - ```node->get_node_handle< - * rclcpp::node_interfaces::NodeBaseInterface, - * rclcpp::node_interfaces::NodeClockInterface - * >()``` will bind the base and clock interfaces. - * - * \return a NodeInterfaceHandle bound with the Node's internal node interfaces. + * - ```NodeInterfaceHandle< + * rclcpp::node_interfaces::Base, rclcpp::node_interfaces::Clock>(node)``` + * will bind both the NodeBaseInterface and NodeClockInterface. + * + * \sa rclcpp::node_interfaces::NodeInterfaceHandle + * \param[in] node Node-like object to bind the interfaces of. + * \returns a NodeInterfaceHandle::SharedPtr supporting the stated interfaces, but bound with none + * of them */ template typename rclcpp::node_interfaces::NodeInterfaceHandle::SharedPtr - get_node_handle(); + get_node_interface_handle(); /// Return the sub-namespace, if this is a sub-node, otherwise an empty string. /** diff --git a/rclcpp/include/rclcpp/node_impl.hpp b/rclcpp/include/rclcpp/node_impl.hpp index fb1475379b..142a5d4247 100644 --- a/rclcpp/include/rclcpp/node_impl.hpp +++ b/rclcpp/include/rclcpp/node_impl.hpp @@ -396,7 +396,7 @@ Node::get_parameters( template typename rclcpp::node_interfaces::NodeInterfaceHandle::SharedPtr -Node::get_node_handle() +Node::get_node_interface_handle() { return std::make_shared>(this); } diff --git a/rclcpp/include/rclcpp/node_interfaces/node_interface_handle.hpp b/rclcpp/include/rclcpp/node_interfaces/node_interface_handle.hpp index 1f674af6b8..a1e52387e5 100644 --- a/rclcpp/include/rclcpp/node_interfaces/node_interface_handle.hpp +++ b/rclcpp/include/rclcpp/node_interfaces/node_interface_handle.hpp @@ -38,267 +38,149 @@ namespace node_interfaces template class NodeInterfaceHandle : public std::enable_shared_from_this> { + static_assert(0 != sizeof ...(InterfaceTs), "Template parameters must be populated!") + public: RCLCPP_SMART_PTR_DEFINITIONS(NodeInterfaceHandle) /// Create a new node handle with no bound node interfaces. RCLCPP_PUBLIC NodeInterfaceHandle() - : base_(nullptr), - clock_(nullptr), - graph_(nullptr), - logging_(nullptr), - timers_(nullptr), - topics_(nullptr), - services_(nullptr), - waitables_(nullptr), - parameters_(nullptr), - time_source_(nullptr) - {} + : InterfaceTs()... {} /// Create a new node handle bound with the passed in node-like object's interfaces. /** - * Specify which interfaces you want to bind using the temlplate parameters. Any unbound - * interfaces will be nullptr. + * Specify which interfaces you want to bind using the template parameters by specifying + * interface support classes to use. Any unmentioned interfaces will be unavailable to bind. + * + * You may use any of the available support classes in + * node_interfaces/node_interface_handle_helpers.hpp: + * - Base: Supports NodeBaseInterface + * - Clock: Supports NodeClockInterface + * - Graph: Supports NodeGraphInterface + * - Logging: Supports NodeLoggingInterface + * - Parameters: Supports NodeParametersInterface + * - Services: Supports NodeServicesInterface + * - TimeSource: Supports NodeTimeSourceInterface + * - Timers: Supports NodeTimersInterface + * - Topics: Supports NodeTopicsInterface + * - Waitables: Supports NodeWaitablesInterface + * + * Or you can define your own interface support classes! * - * Additionally, to bind all interfaces, specify AllInterfaces. + * Each of the support classes should define: + * - Default constructor + * - Templated constructor taking NodeT + * - get_node__interface() + * - set_node__interface() * - * For example: - * - ```NodeInterfaceHandle<>(node)``` will bind no interfaces. - * - ```NodeInterfaceHandle(node)``` + * Usage example: + * - ```NodeInterfaceHandle(node)``` * will bind just the NodeBaseInterface. + * - ```NodeInterfaceHandle< + * rclcpp::node_interfaces::Base, rclcpp::node_interfaces::Clock>(node)``` + * will bind both the NodeBaseInterface and NodeClockInterface. * * \param[in] node Node-like object to bind the interfaces of. */ template explicit NodeInterfaceHandle(const NodeT & node) - { - if constexpr (0 == sizeof ...(InterfaceTs)) { - base_ = nullptr; - clock_ = nullptr; - graph_ = nullptr; - logging_ = nullptr; - timers_ = nullptr; - topics_ = nullptr; - services_ = nullptr; - waitables_ = nullptr; - parameters_ = nullptr; - time_source_ = nullptr; - } else { - base_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_base_interface() : nullptr; - clock_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_clock_interface() : nullptr; - graph_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_graph_interface() : nullptr; - logging_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_logging_interface() : nullptr; - timers_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_timers_interface() : nullptr; - topics_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_topics_interface() : nullptr; - services_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_services_interface() : nullptr; - waitables_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_waitables_interface() : nullptr; - parameters_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_parameters_interface() : nullptr; - time_source_ = ( - (std::is_same_v|| ...) || - (std::is_same_v|| ...) - ) ? node->get_node_time_source_interface() : nullptr; - } - } - - - // Getters - - /// Return the bound NodeBaseInterface - inline node_interfaces::NodeBaseInterface::SharedPtr - get_node_base_interface() {return base_;} - - /// Return the bound NodeClockInterface - inline node_interfaces::NodeClockInterface::SharedPtr - get_node_clock_interface() {return clock_;} - - /// Return the bound NodeGraphInterface - inline node_interfaces::NodeGraphInterface::SharedPtr - get_node_graph_interface() {return graph_;} - - /// Return the bound NodeLoggingInterface - inline node_interfaces::NodeLoggingInterface::SharedPtr - get_node_logging_interface() {return logging_;} - - /// Return the bound NodeTimersInterface - inline node_interfaces::NodeTimersInterface::SharedPtr - get_node_timers_interface() {return timers_;} - - /// Return the bound NodeTopicsInterface - inline node_interfaces::NodeTopicsInterface::SharedPtr - get_node_topics_interface() {return topics_;} - - /// Return the bound NodeServicesInterface - inline node_interfaces::NodeServicesInterface::SharedPtr - get_node_services_interface() {return services_;} - - /// Return the bound NodeWaitablesInterface - inline node_interfaces::NodeWaitablesInterface::SharedPtr - get_node_waitables_interface() {return waitables_;} - - /// Return the bound NodeParametersInterface - inline node_interfaces::NodeParametersInterface::SharedPtr - get_node_parameters_interface() {return parameters_;} - - /// Return the bound NodeTimeSourceInterface - inline node_interfaces::NodeTimeSourceInterface::SharedPtr - get_node_time_source_interface() {return time_source_;} - - - // Setters - - /// Set the bound NodeBaseInterface - inline void - set_node_base_interface(node_interfaces::NodeBaseInterface::SharedPtr interface) - { - base_ = interface; - } - - /// Set the bound NodeClockInterface - inline void - set_node_clock_interface(node_interfaces::NodeClockInterface::SharedPtr interface) - { - clock_ = interface; - } - - /// Set the bound NodeGraphInterface - inline void - set_node_graph_interface(node_interfaces::NodeGraphInterface::SharedPtr interface) - { - graph_ = interface; - } - - /// Set the bound NodeLoggingInterface - inline void - set_node_logging_interface(node_interfaces::NodeLoggingInterface::SharedPtr interface) - { - logging_ = interface; - } - - /// Set the bound NodeTimersInterface - inline void - set_node_timers_interface(node_interfaces::NodeTimersInterface::SharedPtr interface) - { - timers_ = interface; - } - - /// Set the bound NodeTopicsInterface - inline void - set_node_topics_interface(node_interfaces::NodeTopicsInterface::SharedPtr interface) - { - topics_ = interface; - } - - /// Set the bound NodeServicesInterface - inline void - set_node_services_interface(node_interfaces::NodeServicesInterface::SharedPtr interface) - { - services_ = interface; - } - - /// Set the bound NodeWaitablesInterface - inline void - set_node_waitables_interface(node_interfaces::NodeWaitablesInterface::SharedPtr interface) - { - waitables_ = interface; - } - - /// Set the bound NodeParametersInterface - inline void - set_node_parameters_interface(node_interfaces::NodeParametersInterface::SharedPtr interface) - { - parameters_ = interface; - } - - /// Set the bound NodeTimeSourceInterface - inline void - set_node_time_source_interface(node_interfaces::NodeTimeSourceInterface::SharedPtr interface) - { - time_source_ = interface; - } - -private: - node_interfaces::NodeBaseInterface::SharedPtr base_; - node_interfaces::NodeClockInterface::SharedPtr clock_; - node_interfaces::NodeGraphInterface::SharedPtr graph_; - node_interfaces::NodeLoggingInterface::SharedPtr logging_; - node_interfaces::NodeTimersInterface::SharedPtr timers_; - node_interfaces::NodeTopicsInterface::SharedPtr topics_; - node_interfaces::NodeServicesInterface::SharedPtr services_; - node_interfaces::NodeWaitablesInterface::SharedPtr waitables_; - node_interfaces::NodeParametersInterface::SharedPtr parameters_; - node_interfaces::NodeTimeSourceInterface::SharedPtr time_source_; + : InterfaceTs(node)... {} }; /// Create a new node handle bound with no node interfaces. -RCLCPP_PUBLIC -inline NodeInterfaceHandle<>::SharedPtr get_node_handle() -{ - return std::make_shared>(); -} - - -/// Create a new node handle bound with the passed in node-like object's interfaces. /** - * This overload binds all interfaces, if you want to bind a subset of interfaces, specify them - * in the template parameters. + * Specify which interfaces you want to bind using the template parameters by specifying + * interface support classes to use. Any unmentioned interfaces will be unavailable to bind. * + * This method will return a NodeInterfaceHandle with no bound interfaces. You must set them using + * ```NodeInterfaceHandle->set__interface(InterfaceT::SharedPtr interface)``` + * + * You may use any of the available support classes in + * node_interfaces/node_interface_handle_helpers.hpp: + * - Base: Supports NodeBaseInterface + * - Clock: Supports NodeClockInterface + * - Graph: Supports NodeGraphInterface + * - Logging: Supports NodeLoggingInterface + * - Parameters: Supports NodeParametersInterface + * - Services: Supports NodeServicesInterface + * - TimeSource: Supports NodeTimeSourceInterface + * - Timers: Supports NodeTimersInterface + * - Topics: Supports NodeTopicsInterface + * - Waitables: Supports NodeWaitablesInterface + * + * Or you can define your own interface support classes! + * + * Each of the support classes should define: + * - Default constructor + * - Templated constructor taking NodeT + * - get_node__interface() + * - set_node__interface() + * + * Usage example: + * - ```NodeInterfaceHandle(node)``` + * will bind just the NodeBaseInterface. + * - ```NodeInterfaceHandle< + * rclcpp::node_interfaces::Base, rclcpp::node_interfaces::Clock>(node)``` + * will bind both the NodeBaseInterface and NodeClockInterface. + * + * \sa rclcpp::node_interfaces::NodeInterfaceHandle * \param[in] node Node-like object to bind the interfaces of. + * \returns a NodeInterfaceHandle::SharedPtr supporting the stated interfaces, but bound with none + * of them */ -template -typename NodeInterfaceHandle<>::SharedPtr -get_node_handle(const NodeT & node) +template +typename NodeInterfaceHandle::SharedPtr +get_node_interface_handle() { - return std::make_shared>(node); + static_assert(0 != sizeof ...(InterfaceTs), "Template parameters must be populated!") + return std::make_shared>(); } - /// Create a new node handle bound with the passed in node-like object's interfaces. /** - * You may specify in the template parameters the interfaces to bind. Any unbound interfaces - * will be nullptr. + * Specify which interfaces you want to bind using the template parameters by specifying + * interface support classes to use. Any unmentioned interfaces will be unavailable to bind. + * + * You may use any of the available support classes in + * node_interfaces/node_interface_handle_helpers.hpp: + * - Base: Supports NodeBaseInterface + * - Clock: Supports NodeClockInterface + * - Graph: Supports NodeGraphInterface + * - Logging: Supports NodeLoggingInterface + * - Parameters: Supports NodeParametersInterface + * - Services: Supports NodeServicesInterface + * - TimeSource: Supports NodeTimeSourceInterface + * - Timers: Supports NodeTimersInterface + * - Topics: Supports NodeTopicsInterface + * - Waitables: Supports NodeWaitablesInterface + * + * Or you can define your own interface support classes! + * + * Each of the support classes should define: + * - Default constructor + * - Templated constructor taking NodeT + * - get_node__interface() + * - set_node__interface() * - * For example: ```NodeInterfaceHandle(node)``` will bind just the NodeBaseInterface. + * Usage example: + * - ```NodeInterfaceHandle(node)``` + * will bind just the NodeBaseInterface. + * - ```NodeInterfaceHandle< + * rclcpp::node_interfaces::Base, rclcpp::node_interfaces::Clock>(node)``` + * will bind both the NodeBaseInterface and NodeClockInterface. * + * \sa rclcpp::node_interfaces::NodeInterfaceHandle * \param[in] node Node-like object to bind the interfaces of. + * \returns a NodeInterfaceHandle::SharedPtr bound with the node-like objects's interfaces */ template typename NodeInterfaceHandle::SharedPtr -get_node_handle(const NodeT & node) +get_node_interface_handle(const NodeT & node) { - if constexpr (0 == sizeof...(InterfaceTs)) { - return get_node_handle(node); - } else { - return std::make_shared>(node); - } + static_assert(0 != sizeof ...(InterfaceTs), "Template parameters must be populated!") + return std::make_shared>(node); } } // namespace node_interfaces diff --git a/rclcpp/include/rclcpp/node_interfaces/node_interface_handle_helpers.hpp b/rclcpp/include/rclcpp/node_interfaces/node_interface_handle_helpers.hpp new file mode 100644 index 0000000000..809055d766 --- /dev/null +++ b/rclcpp/include/rclcpp/node_interfaces/node_interface_handle_helpers.hpp @@ -0,0 +1,273 @@ +// 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__NODE_INTERFACES__NODE_INTERFACE_HANDLE_HELPERS_HPP_ +#define RCLCPP__NODE_INTERFACES__NODE_INTERFACE_HANDLE_HELPERS_HPP_ + +#include +#include + +#include "rclcpp/node_interfaces/node_base_interface.hpp" +#include "rclcpp/node_interfaces/node_clock_interface.hpp" +#include "rclcpp/node_interfaces/node_graph_interface.hpp" +#include "rclcpp/node_interfaces/node_logging_interface.hpp" +#include "rclcpp/node_interfaces/node_parameters_interface.hpp" +#include "rclcpp/node_interfaces/node_services_interface.hpp" +#include "rclcpp/node_interfaces/node_time_source_interface.hpp" +#include "rclcpp/node_interfaces/node_timers_interface.hpp" +#include "rclcpp/node_interfaces/node_topics_interface.hpp" +#include "rclcpp/node_interfaces/node_waitables_interface.hpp" + +namespace rclcpp +{ +namespace node_interfaces +{ + +// Helper classes to be inherited by NodeInterfaceHandle to support node interface aggregation +// via multiple inheritance. + +// These also provide a more terse way to configure the supported interfaces! + + +/// NodeInterfaceHandle support for NodeBaseInterface +class Base +{ +public: + /// Default constructor with no bound NodeBaseInterface + Base() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeBaseInterface + template + Base(const NodeT & node) {impl_ = node.get_node_base_interface();} + + /// Return the bound NodeBaseInterface + inline NodeBaseInterface::SharedPtr get_node_base_interface() {return impl_;} + + /// Set the bound NodeBaseInterface + inline void set_node_base_interface(NodeBaseInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeBaseInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeClockInterface +class Clock +{ +public: + /// Default constructor with no bound NodeClockInterface + Clock() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeClockInterface + template + Clock(const NodeT & node) {impl_ = node.get_node_clock_interface();} + + /// Return the bound NodeClockInterface + inline NodeClockInterface::SharedPtr get_node_clock_interface() {return impl_;} + + /// Set the bound NodeClockInterface + inline void set_node_clock_interface(NodeClockInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeClockInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeGraphInterface +class Graph +{ +public: + /// Default constructor with no bound NodeGraphInterface + Graph() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeGraphInterface + template + Graph(const NodeT & node) {impl_ = node.get_node_graph_interface();} + + /// Return the bound NodeGraphInterface + inline NodeGraphInterface::SharedPtr get_node_graph_interface() {return impl_;} + + /// Set the bound NodeGraphInterface + inline void set_node_graph_interface(NodeGraphInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeGraphInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeLoggingInterface +class Logging +{ +public: + /// Default constructor with no bound NodeLoggingInterface + Logging() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeLoggingInterface + template + Logging(const NodeT & node) {impl_ = node.get_node_logging_interface();} + + /// Return the bound NodeLoggingInterface + inline NodeLoggingInterface::SharedPtr get_node_logging_interface() {return impl_;} + + /// Set the bound NodeLoggingInterface + inline void + set_node_logging_interface(NodeLoggingInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeLoggingInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeParametersInterface +class Parameters +{ +public: + /// Default constructor with no bound NodeParametersInterface + Parameters() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeParametersInterface + template + Parameters(const NodeT & node) {impl_ = node.get_node_parameters_interface();} + + /// Return the bound NodeParametersInterface + inline NodeParametersInterface::SharedPtr get_node_parameters_interface() {return impl_;} + + /// Set the bound NodeParametersInterface + inline void + set_node_parameters_interface(NodeParametersInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeParametersInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeServicesInterface +class Services +{ +public: + /// Default constructor with no bound NodeServicesInterface + Services() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeServicesInterface + template + Services(const NodeT & node) {impl_ = node.get_node_services_interface();} + + /// Return the bound NodeServicesInterface + inline NodeServicesInterface::SharedPtr get_node_services_interface() {return impl_;} + + /// Set the bound NodeServicesInterface + inline void + set_node_services_interface(NodeServicesInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeServicesInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeTimeSourceInterface +class TimeSource +{ +public: + /// Default constructor with no bound NodeTimeSourceInterface + TimeSource() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeTimeSourceInterface + template + TimeSource(const NodeT & node) {impl_ = node.get_node_time_source_interface();} + + /// Return the bound NodeTimeSourceInterface + inline NodeTimeSourceInterface::SharedPtr get_node_time_source_interface() {return impl_;} + + /// Set the bound NodeTimeSourceInterface + inline void + set_node_time_source_interface(NodeTimeSourceInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeTimeSourceInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeTimersInterface +class Timers +{ +public: + /// Default constructor with no bound NodeTimersInterface + Timers() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeTimersInterface + template + Timers(const NodeT & node) {impl_ = node.get_node_timers_interface();} + + /// Return the bound NodeTimersInterface + inline NodeTimersInterface::SharedPtr get_node_timers_interface() {return impl_;} + + /// Set the bound NodeTimersInterface + inline void + set_node_timers_interface(NodeTimersInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeTimersInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeTopicsInterface +class Topics +{ +public: + /// Default constructor with no bound NodeTopicsInterface + Topics() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeTopicsInterface + template + Topics(const NodeT & node) {impl_ = node.get_node_topics_interface();} + + /// Return the bound NodeTopicsInterface + inline NodeTopicsInterface::SharedPtr get_node_topics_interface() {return impl_;} + + /// Set the bound NodeTopicsInterface + inline void + set_node_topics_interface(NodeTopicsInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeTopicsInterface::SharedPtr impl_; +}; + + +/// NodeInterfaceHandle support for NodeWaitablesInterface +class Waitables +{ +public: + /// Default constructor with no bound NodeWaitablesInterface + Waitables() {impl_ = nullptr;} + + /// Bind the passed in node-like object's NodeWaitablesInterface + template + Waitables(const NodeT & node) {impl_ = node.get_node_waitables_interface();} + + /// Return the bound NodeWaitablesInterface + inline NodeWaitablesInterface::SharedPtr get_node_waitables_interface() {return impl_;} + + /// Set the bound NodeWaitablesInterface + inline void + set_node_waitables_interface(NodeWaitablesInterface::SharedPtr interface) {impl_ = interface;} + +private: + NodeWaitablesInterface::SharedPtr impl_; +}; + + +} // namespace node_interfaces +} // namespace rclcpp + +#endif // RCLCPP__NODE_INTERFACES__NODE_INTERFACE_HANDLE_HELPERS_HPP_ diff --git a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp index b421300477..263d22b200 100644 --- a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp +++ b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp @@ -825,23 +825,48 @@ class LifecycleNode : public node_interfaces::LifecycleNodeInterface, /// Return a NodeInterfaceHandle bound with the LifecycleNode's internal node interfaces. /** - * Specify which interfaces you want to bind using the temlplate parameters. Any unbound - * interfaces will be nullptr. + * Specify which interfaces you want to bind using the template parameters by specifying + * interface support classes to use. Any unmentioned interfaces will be unavailable to bind. * - * For example: - * - ```node->get_node_handle<>()``` will bind no interfaces. - * - ```node->get_node_handle()``` + * This method will return a NodeInterfaceHandle with no bound interfaces. You must set them using + * ```NodeInterfaceHandle->set__interface(InterfaceT::SharedPtr interface)``` + * + * You may use any of the available support classes in + * node_interfaces/node_interface_handle_helpers.hpp: + * - Base: Supports NodeBaseInterface + * - Clock: Supports NodeClockInterface + * - Graph: Supports NodeGraphInterface + * - Logging: Supports NodeLoggingInterface + * - Parameters: Supports NodeParametersInterface + * - Services: Supports NodeServicesInterface + * - TimeSource: Supports NodeTimeSourceInterface + * - Timers: Supports NodeTimersInterface + * - Topics: Supports NodeTopicsInterface + * - Waitables: Supports NodeWaitablesInterface + * + * Or you can define your own interface support classes! + * + * Each of the support classes should define: + * - Default constructor + * - Templated constructor taking NodeT + * - get_node__interface() + * - set_node__interface() + * + * Usage example: + * - ```NodeInterfaceHandle(node)``` * will bind just the NodeBaseInterface. - * - ```node->get_node_handle< - * rclcpp::node_interfaces::NodeBaseInterface, - * rclcpp::node_interfaces::NodeClockInterface - * >()``` will bind the base and clock interfaces. + * - ```NodeInterfaceHandle< + * rclcpp::node_interfaces::Base, rclcpp::node_interfaces::Clock>(node)``` + * will bind both the NodeBaseInterface and NodeClockInterface. * - * \return a NodeInterfaceHandle bound with the LifecycleNode's internal node interfaces. + * \sa rclcpp::node_interfaces::NodeInterfaceHandle + * \param[in] node Node-like object to bind the interfaces of. + * \return a NodeInterfaceHandle::SharedPtr supporting the stated interfaces, but bound with none + * of them */ template typename rclcpp::node_interfaces::NodeInterfaceHandle::SharedPtr - get_node_handle(); + get_node_interface_handle(); /// Return the NodeOptions used when creating this node. /** diff --git a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp index a005bc7cb2..75231deb0e 100644 --- a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp +++ b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp @@ -334,7 +334,7 @@ LifecycleNode::get_parameter_or( template typename rclcpp::node_interfaces::NodeInterfaceHandle::SharedPtr -LifecycleNode::get_node_handle() +LifecycleNode::get_node_interface_handle() { return std::make_shared>(this); }