36 dev.on_parameter_created.connect<&device_parameter_index::on_parameter_created>(
38 dev.on_parameter_removing.connect<&device_parameter_index::on_parameter_removing>(
40 dev.on_node_removing.connect<&device_parameter_index::on_node_removing>(*this);
41 dev.on_node_renamed.connect<&device_parameter_index::on_node_renamed>(*this);
43 index_recursively(dev.get_root_node());
54 bool apply(std::string_view address, F&& f)
57 return m_index.visit(normalize(address, buf), [&](
const auto& e) { f(*e.second); })
63 void clear() { m_index.clear(); }
65 std::size_t size()
const {
return m_index.size(); }
70 static std::string_view normalize(std::string_view address, std::string& buf)
72 while(address.size() > 1 && address.back() ==
'/')
73 address.remove_suffix(1);
75 if(!address.empty() && address.front() ==
'/')
78 buf.reserve(address.size() + 1);
88 return ossia::net::osc_parameter_string(node);
93 if(
auto param = node.get_parameter())
94 m_index.insert_or_assign(address_of(node), param);
96 for(
const auto& cld : node.children_copy())
97 index_recursively(*cld);
102 m_index.insert_or_assign(
108 m_index.erase(address_of(param.get_node()));
116 const auto prefix = address_of(node);
118 m_index.erase_if([&prefix](
const auto& e) {
119 const auto& key = e.first;
121 || (key.size() > prefix.size() && key.starts_with(prefix)
122 && key[prefix.size()] ==
'/');
131 index_recursively(m_device.get_root_node());
135 boost::concurrent_flat_map<