OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
path.hpp
1#pragma once
2#include <ossia/detail/hash.hpp>
3#include <ossia/detail/optional.hpp>
4#include <ossia/detail/regex_fwd.hpp>
5#include <ossia/network/base/address_scope.hpp>
6#include <ossia/network/base/name_validation.hpp>
7
8#include <smallfun.hpp>
9
10#include <iosfwd>
11#include <string>
12
13namespace ossia
14{
15namespace net
16{
17
18class node_base;
19}
34namespace regex_path
35{
39struct OSSIA_EXPORT path_element
40{
41 std::string address;
42 path_element(std::string s)
43 : address{std::move(s)}
44 {
45 }
46
47 template <int N>
48 path_element(const char (&s)[N])
49 : address(s, N - 1)
50 {
51 }
52
53 operator std::string() const { return address; }
54};
55
56OSSIA_EXPORT
57std::ostream& operator<<(std::ostream& s, const path_element& p);
58
60struct OSSIA_EXPORT device : public path_element
61{
62 explicit device(std::string s)
63 : path_element{"^" + std::move(s) + ":"}
64 {
65 }
66};
67
69struct OSSIA_EXPORT any_instance : public path_element
70{
71 static std::string instance_regex()
72 {
73 static const auto str
74 = "(\\.[" + std::string(ossia::net::name_characters_no_instance()) + "]+)?";
75 return str;
76 }
77 explicit any_instance(std::string s)
78 : path_element{std::move(s) + instance_regex()}
79 {
80 }
81};
82
85struct OSSIA_EXPORT any_between : public path_element
86{
87 any_between(std::string s)
88 : path_element{std::move(s)}
89 {
90 }
91
92 any_between(std::initializer_list<std::string> args)
93 : path_element{""}
94 {
95 const auto N = args.size();
96 if(N > 0)
97 {
98 address += '(';
99
100 auto it = args.begin();
101 address += *it;
102
103 for(std::size_t i = 1; i < N; i++)
104 {
105 ++it;
106 address += '|';
107 address += *it;
108 }
109
110 address += ')';
111 }
112 }
113};
114
116struct OSSIA_EXPORT any_node
117{
118};
119
121struct OSSIA_EXPORT any_path
122{
123};
124
126struct OSSIA_EXPORT stop
127{
128};
129
130inline path_element operator/(const path_element& lhs, const path_element& rhs)
131{
132 return path_element{lhs.address + "\\/" + rhs.address};
133}
134
135inline path_element operator/(const path_element& lhs, const any_instance& rhs)
136{
137 return path_element{lhs.address + "\\/" + rhs.address};
138}
139
140inline path_element operator/(const path_element& lhs, const any_node&)
141{
142 return path_element{
143 lhs.address + "\\/[" + std::string(ossia::net::name_characters()) + "]*"};
144}
145
146inline path_element operator/(const path_element& lhs, const any_path&)
147{
148 return path_element{
149 lhs.address + "(\\/[" + std::string(ossia::net::name_characters()) + "]*)+"};
150}
151
152inline path_element operator/(const any_path&, const path_element& rhs)
153{
154 const std::string sub = std::string(ossia::net::name_characters());
155 std::string sub2 = "^([";
156 sub2 += sub;
157 sub2 += "]*:)(\\/?[";
158 sub2 += sub;
159 sub2 += "]*)+\\/";
160 sub2 += rhs.address;
161 return path_element{std::move(sub2)};
162}
163
164inline path_element operator/(const path_element& lhs, const stop& rhs)
165{
166 return path_element{lhs.address + "$"};
167}
168}
169
207namespace traversal
208{
209struct OSSIA_EXPORT path
210{
211 // Used for hashing
212 std::string pattern;
213 ossia::net::address_scope scope;
214
218 using child_function = smallfun::function<
219 void(std::vector<ossia::net::node_base*>&), 32 + sizeof(void*)>;
220 std::vector<child_function> child_functions;
221
222 friend bool operator==(const path& lhs, const path& rhs)
223 {
224 return lhs.pattern == rhs.pattern;
225 }
226 friend bool operator!=(const path& lhs, const path& rhs)
227 {
228 return lhs.pattern != rhs.pattern;
229 }
230};
231
233OSSIA_EXPORT bool is_pattern(std::string_view address);
234
238OSSIA_EXPORT std::optional<path> make_path(std::string_view address);
239
248OSSIA_EXPORT void apply(const path& p, std::vector<ossia::net::node_base*>& nodes);
249
251OSSIA_EXPORT bool match(const path& p, const ossia::net::node_base& node);
252
254OSSIA_EXPORT bool
255match(const path& p, const ossia::net::node_base& node, ossia::net::node_base& root);
256
258OSSIA_EXPORT std::string substitute_characters(const std::string& path);
259
261OSSIA_EXPORT bool match(std::string_view address, const regex_path::path_element& e);
262
263}
264}
265
266namespace std
267{
268template <>
269struct hash<ossia::traversal::path>
270{
271 std::size_t operator()(const ossia::traversal::path& p) const
272 {
273 return ossia::hash<std::string>{}(p.pattern);
274 }
275};
276}
The node_base class.
Definition node.hpp:48
Definition git_info.h:7
Utilities to construct regexes to validate paths.
Utilities to construct classes that will perform an action for nodes matching a path.
Definition path.hpp:86
Can match nodes that are instances : foo:/bar, foo:/bar.1, etc.
Definition path.hpp:70
Can match any node : foo:/bar, foo:/baz.1234, etc.
Definition path.hpp:117
Can match any subpath : foo:/bar/baz, foo:/bar/bo.12/baz, etc.
Definition path.hpp:122
Represents a device in a path, e.g. "foo:".
Definition path.hpp:61
Base class for our paths.
Definition path.hpp:40
Matches the end of a parameter.
Definition path.hpp:127