Loading...
Searching...
No Matches
plugins/score-plugin-avnd/Crousti/Metadata.hpp
1#pragma once
2#include <Process/ProcessMetadata.hpp>
3
4#include <Crousti/Concepts.hpp>
5
6#include <QString>
7
8#include <avnd/binding/ossia/port_base.hpp>
9#include <avnd/concepts/all.hpp>
10#include <avnd/introspection/input.hpp>
11#include <avnd/introspection/output.hpp>
12#include <avnd/wrappers/metadatas.hpp>
13
14#include <string_view>
15
16namespace oscr
17{
18template <typename Info>
19class ProcessModel;
20}
21
22inline QString fromStringView(std::string_view v)
23{
24 return QString::fromUtf8(v.data(), v.size());
25}
26
28namespace oscr
29{
30template <typename Info>
31class ProcessModel;
32}
33template <typename Info>
34 requires avnd::has_name<Info>
35struct Metadata<PrettyName_k, oscr::ProcessModel<Info>>
36{
37 static constexpr const char* get() noexcept { return avnd::get_name<Info>().data(); }
38};
39template <typename Info>
40 requires avnd::has_category<Info>
41struct Metadata<Category_k, oscr::ProcessModel<Info>>
42{
43 static constexpr const char* get() noexcept
44 {
45 return avnd::get_category<Info>().data();
46 }
47};
48template <typename Info>
49 requires(!avnd::has_category<Info>)
51{
52 static constexpr const char* get() noexcept { return ""; }
53};
54
55template <typename Info>
56struct Metadata<Tags_k, oscr::ProcessModel<Info>>
57{
58 static QStringList get() noexcept
59 {
60 QStringList lst;
61 for(std::string_view tag : avnd::get_tags<Info>())
62 lst.push_back(QString::fromUtf8(tag.data(), tag.size()));
63 return lst;
64 }
65};
66
67template <typename T>
68concept has_kind = requires { T::kind(); };
69
70template <typename T>
71auto get_kind()
72{
73 if constexpr(has_kind<T>)
74 return T::kind();
75 else
76 return Process::ProcessCategory::Other;
77}
78
80{
81 std::vector<Process::PortType> port;
82 void audio() { port.push_back(Process::PortType::Audio); }
83 void midi() { port.push_back(Process::PortType::Midi); }
84 void value() { port.push_back(Process::PortType::Message); }
85 void buffer() { port.push_back(Process::PortType::Texture); }
86 void texture() { port.push_back(Process::PortType::Texture); }
87 void geometry() { port.push_back(Process::PortType::Geometry); }
88
89 template <std::size_t N, oscr::ossia_value_port Port>
90 void operator()(const avnd::field_reflection<N, Port>)
91 {
92 this->value();
93 }
94 template <std::size_t N, oscr::ossia_audio_port Port>
95 void operator()(const avnd::field_reflection<N, Port>)
96 {
97 this->audio();
98 }
99
100 template <std::size_t N, oscr::ossia_midi_port Port>
101 void operator()(const avnd::field_reflection<N, Port>)
102 {
103 this->midi();
104 }
105
106 template <std::size_t N, avnd::dynamic_ports_port Port>
107 void operator()(const avnd::field_reflection<N, Port>)
108 {
109 using port_type = typename decltype(std::declval<Port>().ports)::value_type;
110 (*this)(avnd::field_reflection<std::size_t{0}, port_type>{});
111 }
112
113 template <std::size_t N, avnd::audio_port Port>
114 void operator()(const avnd::field_reflection<N, Port>)
115 {
116 this->audio();
117 }
118
119 template <std::size_t N, avnd::midi_port Port>
120 void operator()(const avnd::field_reflection<N, Port>)
121 {
122 this->midi();
123 }
124
125 template <std::size_t N, avnd::parameter Port>
126 requires(!oscr::ossia_port<Port> && !avnd::curve_port<Port>)
127 void operator()(const avnd::field_reflection<N, Port>)
128 {
129 this->value();
130 }
131
132 template <std::size_t N, avnd::file_port Port>
133 void operator()(const avnd::field_reflection<N, Port>)
134 {
135 this->value();
136 }
137
138 template <std::size_t N, avnd::soundfile_port Port>
139 void operator()(const avnd::field_reflection<N, Port>)
140 {
141 this->value();
142 }
143
144 template <std::size_t N, avnd::midifile_port Port>
145 void operator()(const avnd::field_reflection<N, Port>)
146 {
147 this->value();
148 }
149
150 template <std::size_t N, avnd::buffer_port Port>
151 void operator()(const avnd::field_reflection<N, Port>)
152 {
153 this->buffer();
154 }
155
156 template <std::size_t N, avnd::texture_port Port>
157 void operator()(const avnd::field_reflection<N, Port>)
158 {
159 this->texture();
160 }
161
162 template <std::size_t N, avnd::geometry_port Port>
163 void operator()(const avnd::field_reflection<N, Port>)
164 {
165 this->geometry();
166 }
167
168 template <std::size_t N, avnd::curve_port Port>
169 void operator()(const avnd::field_reflection<N, Port>)
170 {
171 this->value();
172 }
173
174 template <std::size_t N, avnd::callback Port>
175 void operator()(const avnd::field_reflection<N, Port>)
176 {
177 this->value();
178 }
179
180 void operator()(auto&&) = delete;
181};
182
183template <typename Info>
184struct Metadata<Process::Descriptor_k, oscr::ProcessModel<Info>>
185{
186 static std::vector<Process::PortType> inletDescription()
187 {
189 avnd::input_introspection<Info>::for_all(vis);
190 return vis.port;
191 }
192 static std::vector<Process::PortType> outletDescription()
193 {
195 avnd::output_introspection<Info>::for_all(vis);
196 return vis.port;
197 }
198 static Process::ProcessCategory kind() noexcept
199 {
200 Process::ProcessCategory cat;
201 if constexpr(has_kind<Info>)
202 cat = Info::kind();
203 else
204 cat = Process::ProcessCategory::Other;
205
206 if constexpr(avnd::tag_deprecated<Info>)
207 cat = Process::ProcessCategory(cat | Process::ProcessCategory::Deprecated);
208 return cat;
209 }
210 static Process::Descriptor get()
211 {
212// literate programming goes brr
213#if defined(_MSC_VER)
214#define if_exists(Expr, Else) \
215 []() noexcept { \
216 if(false) \
217 { \
218 } \
219 Else; \
220 }()
221#define if_attribute(Attr) QString{}
222#else
223#define if_exists(Expr, Else) \
224 []() noexcept { \
225 if constexpr(requires { Expr; }) \
226 return Expr; \
227 Else; \
228 }()
229
230#define if_attribute(Attr) \
231 []() noexcept -> QString { \
232 if constexpr(avnd::has_##Attr<Info>) \
233 return fromStringView(avnd::get_##Attr<Info>()); \
234 else \
235 return QString{}; \
236 }()
237#endif
238 static Process::Descriptor desc{
240 kind(),
241 if_attribute(category),
242 if_attribute(description),
243 if_attribute(author),
245 inletDescription(),
246 outletDescription(),
247 if_attribute(manual_url)};
248 return desc;
249 }
250};
251template <typename Info>
253{
254 static Process::ProcessFlags get() noexcept
255 {
256 if constexpr(requires { Info::flags(); })
257 {
258 return Info::flags();
259 }
260 else
261 {
262 Process::ProcessFlags flags{};
264
265 if constexpr(avnd::tag_temporal<Info>)
267 else
268 flags |= Process::ProcessFlags::SupportsLasting;
269
270 if constexpr(avnd::tag_single_exec<Info>)
272
273 if constexpr(avnd::tag_fully_custom_item<Info>)
275
276 if constexpr(avnd::dynamic_ports_input_introspection<Info>::size > 0)
278
279 if constexpr(avnd::dynamic_ports_output_introspection<Info>::size > 0)
281
282 return flags;
283 }
284 }
285};
286template <typename Info>
287struct Metadata<ObjectKey_k, oscr::ProcessModel<Info>>
288{
289 static constexpr auto get() noexcept { return avnd::get_c_name<Info>().data(); }
290};
291template <typename Info>
292struct Metadata<ConcreteKey_k, oscr::ProcessModel<Info>>
293{
294 static Q_DECL_RELAXED_CONSTEXPR UuidKey<Process::ProcessModel> get()
295 {
296 return oscr::uuid_from_string<Info>();
297 }
298};
Metadata to categorize objects: curves, audio, etc.
Metadata to get the key part of ObjectIdentifier.
Metadata to get the name that will be shown in the user interface.
Metadata to retrieve the ProcessFlags of a process.
Metadata to associate tags to objects.
Definition UuidKey.hpp:345
Definition score-plugin-avnd/Crousti/ProcessModel.hpp:86
Definition plugins/score-plugin-avnd/Crousti/Metadata.hpp:68
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
ProcessFlags
Various settings for processes.
Definition ProcessFlags.hpp:17
@ ControlSurface
The process supports being exposed to the ControlSurface.
Definition ProcessFlags.hpp:37
@ SupportsState
Can be loaded in a state.
Definition ProcessFlags.hpp:25
@ SupportsTemporal
Can be loaded as a process of an interval.
Definition ProcessFlags.hpp:19
@ DynamicPorts
The process has a variable structure, e.g. its ports can change dynamically.
Definition ProcessFlags.hpp:59
@ FullyCustomItem
The process's item handles all the decoration (won't be title, etc)
Definition ProcessFlags.hpp:40
Definition Factories.hpp:19
Static metadata implementation.
Definition lib/score/tools/Metadata.hpp:36
Definition score-lib-process/Process/ProcessMetadata.hpp:37
Definition plugins/score-plugin-avnd/Crousti/Metadata.hpp:80