18 #include <unordered_map>
22 #include "rclcpp/parameter_event_handler.hpp"
23 #include "rcpputils/join.hpp"
28 ParameterEventCallbackHandle::SharedPtr
30 ParameterEventCallbackType callback)
32 std::lock_guard<std::recursive_mutex> lock(callbacks_->mutex_);
33 auto handle = std::make_shared<ParameterEventCallbackHandle>();
34 handle->callback = callback;
35 callbacks_->event_callbacks_.emplace_front(handle);
42 ParameterEventCallbackHandle::SharedPtr callback_handle)
44 std::lock_guard<std::recursive_mutex> lock(callbacks_->mutex_);
45 auto it = std::find_if(
46 callbacks_->event_callbacks_.begin(),
47 callbacks_->event_callbacks_.end(),
48 [callback_handle](
const auto & weak_handle) {
49 return callback_handle.get() == weak_handle.lock().get();
51 if (it != callbacks_->event_callbacks_.end()) {
52 callbacks_->event_callbacks_.erase(it);
54 throw std::runtime_error(
"Callback doesn't exist");
58 ParameterCallbackHandle::SharedPtr
60 const std::string & parameter_name,
61 ParameterCallbackType callback,
62 const std::string & node_name)
64 std::lock_guard<std::recursive_mutex> lock(callbacks_->mutex_);
65 auto full_node_name = resolve_path(node_name);
67 auto handle = std::make_shared<ParameterCallbackHandle>();
68 handle->callback = callback;
69 handle->parameter_name = parameter_name;
70 handle->node_name = full_node_name;
72 callbacks_->parameter_callbacks_[{parameter_name, full_node_name}].emplace_front(handle);
79 ParameterCallbackHandle::SharedPtr callback_handle)
81 std::lock_guard<std::recursive_mutex> lock(callbacks_->mutex_);
82 auto handle = callback_handle.get();
83 auto & container = callbacks_->parameter_callbacks_[{handle->parameter_name, handle->node_name}];
84 auto it = std::find_if(
87 [handle](
const auto & weak_handle) {
88 return handle == weak_handle.lock().get();
90 if (it != container.end()) {
92 if (container.empty()) {
93 callbacks_->parameter_callbacks_.erase({handle->parameter_name, handle->node_name});
96 throw std::runtime_error(
"Callback doesn't exist");
102 const rcl_interfaces::msg::ParameterEvent & event,
104 const std::string & parameter_name,
105 const std::string & node_name)
107 if (event.node != node_name) {
111 for (
auto & new_parameter : event.new_parameters) {
112 if (new_parameter.name == parameter_name) {
118 for (
auto & changed_parameter : event.changed_parameters) {
119 if (changed_parameter.name == parameter_name) {
130 const rcl_interfaces::msg::ParameterEvent & event,
131 const std::string & parameter_name,
132 const std::string & node_name)
136 if (event.node == node_name) {
139 throw std::runtime_error(
140 "The node name '" + node_name +
"' of parameter '" + parameter_name +
141 +
"' doesn't match the node name '" + event.node +
"' in parameter event");
147 std::vector<rclcpp::Parameter>
149 const rcl_interfaces::msg::ParameterEvent & event)
151 std::vector<rclcpp::Parameter> params;
153 for (
auto & new_parameter : event.new_parameters) {
157 for (
auto & changed_parameter : event.changed_parameters) {
167 std::lock_guard<std::recursive_mutex> lock(mutex_);
169 for (
auto it = parameter_callbacks_.begin(); it != parameter_callbacks_.end(); ++it) {
172 for (
auto cb = it->second.begin(); cb != it->second.end(); ++cb) {
173 auto shared_handle = cb->lock();
174 if (
nullptr != shared_handle) {
175 shared_handle->callback(p);
177 cb = it->second.erase(cb);
183 for (
auto event_cb = event_callbacks_.begin(); event_cb != event_callbacks_.end(); ++event_cb) {
184 auto shared_event_handle = event_cb->lock();
185 if (
nullptr != shared_event_handle) {
186 shared_event_handle->callback(event);
188 event_cb = event_callbacks_.erase(event_cb);
194 ParameterEventHandler::resolve_path(
const std::string & path)
196 std::string full_path;
199 full_path = node_base_->get_fully_qualified_name();
202 if (*path.begin() !=
'/') {
203 auto ns = node_base_->get_namespace();
204 const std::vector<std::string> paths{ns, path};
205 full_path = (ns == std::string(
"/")) ? ns + path : rcpputils::join(paths,
"/");
RCLCPP_PUBLIC void remove_parameter_callback(ParameterCallbackHandle::SharedPtr callback_handle)
Remove a parameter callback registered with add_parameter_callback.
static RCLCPP_PUBLIC bool get_parameter_from_event(const rcl_interfaces::msg::ParameterEvent &event, rclcpp::Parameter ¶meter, const std::string ¶meter_name, const std::string &node_name="")
Get an rclcpp::Parameter from a parameter event.
static RCLCPP_PUBLIC std::vector< rclcpp::Parameter > get_parameters_from_event(const rcl_interfaces::msg::ParameterEvent &event)
Get all rclcpp::Parameter values from a parameter event.
RCLCPP_PUBLIC void remove_parameter_event_callback(ParameterEventCallbackHandle::SharedPtr callback_handle)
Remove parameter event callback registered with add_parameter_event_callback.
RCLCPP_PUBLIC RCUTILS_WARN_UNUSED ParameterEventCallbackHandle::SharedPtr add_parameter_event_callback(ParameterEventCallbackType callback)
Set a callback for all parameter events.
RCLCPP_PUBLIC RCUTILS_WARN_UNUSED ParameterCallbackHandle::SharedPtr add_parameter_callback(const std::string ¶meter_name, ParameterCallbackType callback, const std::string &node_name="")
Add a callback for a specified parameter.
Structure to store an arbitrary parameter with templated get/set methods.
static RCLCPP_PUBLIC Parameter from_parameter_msg(const rcl_interfaces::msg::Parameter ¶meter)
Convert a parameter message in a Parameter class object.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC void event_callback(const rcl_interfaces::msg::ParameterEvent &event)
Callback for parameter events subscriptions.