Loading...
Searching...
No Matches
ProcessModelPortInit.hpp
1#pragma once
2#include <Process/Dataflow/Port.hpp>
3#include <Process/Dataflow/PortFactory.hpp>
4#include <Process/Process.hpp>
5
6#include <Crousti/Concepts.hpp>
7#include <Media/Sound/Drop/SoundDrop.hpp>
8
9#include <avnd/binding/ossia/port_base.hpp>
10#include <avnd/concepts/all.hpp>
11#if SCORE_PLUGIN_GFX
12#include <Gfx/TexturePort.hpp>
13#endif
14
15namespace oscr
16{
17template <typename Info>
18class ProcessModel;
19}
20
21namespace oscr
22{
23
24template <typename T>
25inline void setupNewPort(Process::Port* obj)
26{
27 //FIXME
28#if !defined(__APPLE__)
29 constexpr auto name = avnd::get_name<T>();
30 obj->setName(fromStringView(name));
31 if constexpr(avnd::has_description<T>)
32 obj->setDescription(fromStringView(avnd::get_description<T>()));
33#else
34 auto name = avnd::get_name<T>();
35 obj->setName(fromStringView(name));
36 if constexpr(avnd::has_description<T>)
37 obj->setDescription(fromStringView(avnd::get_description<T>()));
38#endif
39}
40
41template <std::size_t N, typename T>
42inline void setupNewPort(const avnd::field_reflection<N, T>& spec, Process::Port* obj)
43{
44 setupNewPort<T>(obj);
45}
46
47template <typename T>
48inline void setupNewPort(const T& spec, Process::Port* obj)
49{
50 setupNewPort<T>(obj);
51}
52
53template <typename Node>
55{
57 Process::Inlets& ins;
58 int inlet = 0;
59
60 void operator()(const oscr::ossia_value_port auto& in, auto idx)
61 {
62 auto p = new Process::ValueInlet(Id<Process::Port>(inlet++), &self);
63 setupNewPort(in, p);
64 ins.push_back(p);
65 }
66 void operator()(const oscr::ossia_audio_port auto& in, auto idx)
67 {
68 auto p = new Process::AudioInlet(Id<Process::Port>(inlet++), &self);
69 setupNewPort(in, p);
70 ins.push_back(p);
71 }
72 void operator()(const oscr::ossia_midi_port auto& in, auto idx)
73 {
74 auto p = new Process::MidiInlet(Id<Process::Port>(inlet++), &self);
75 setupNewPort(in, p);
76 ins.push_back(p);
77 }
78
79 void operator()(const avnd::audio_port auto& in, auto idx)
80 {
81 auto p = new Process::AudioInlet(Id<Process::Port>(inlet++), &self);
82 setupNewPort(in, p);
83 ins.push_back(p);
84 }
85 void operator()(const avnd::midi_port auto& in, auto idx)
86 {
87 auto p = new Process::MidiInlet(Id<Process::Port>(inlet++), &self);
88 setupNewPort(in, p);
89 ins.push_back(p);
90 }
91
92 static QString toFilters(const QSet<QString>& exts)
93 {
94 QString res;
95 for(const auto& s : exts)
96 {
97 res += "*.";
98 res += s;
99 res += " ";
100 }
101 if(!res.isEmpty())
102 res.resize(res.size() - 1);
103 return res;
104 }
105
106 template <typename P>
107 static QString getFilters(P& p)
108 {
109 if constexpr(requires { P::filters(); })
110 {
111 using filter = decltype(P::filters());
112 if constexpr(requires { filter::sound; } || requires { filter::audio; })
113 {
114 return QString{"Sound files (%1)"}.arg(
115 toFilters(Media::Sound::DropHandler{}.fileExtensions()));
116 }
117 else if constexpr(requires { filter::video; })
118 {
119 // FIXME refactor supported formats with Video process
120 QSet<QString> files = {"mkv", "mov", "mp4", "h264", "avi", "hap", "mpg",
121 "mpeg", "imf", "mxf", "mts", "m2ts", "mj2", "webm"};
122 return QString{"Videos (%1)"}.arg(toFilters(files));
123 }
124 else if constexpr(requires { filter::image; })
125 {
126 // FIXME refactor supported formats with Image List Chooser
127 return QString{"Images (*.png *.jpg *.jpeg *.gif *.bmp *.tiff)"};
128 }
129 else if constexpr(requires { filter::midi; })
130 {
131 return "MIDI (*.mid)";
132 }
133 else if constexpr(avnd::string_ish<filter>)
134 {
135 static constexpr auto text_filters = P::filters();
136 return fromStringView(P::filters());
137 }
138 else
139 {
140 return "";
141 }
142 }
143 else if constexpr(requires { P::extensions(); })
144 {
145 static constexpr auto text_filters = P::extensions();
146 return fromStringView(text_filters);
147 }
148 else
149 {
150 return "";
151 }
152 }
153
154 template <typename T>
155 requires avnd::soundfile_port<T>
156 void operator()(const T& in, auto idx)
157 {
158 static constexpr auto name = avnd::get_name<T>();
159 Process::FileChooserBase* p{};
160 if constexpr(requires { T::waveform; })
161 {
162 p = new Process::AudioFileChooser{
163 "", getFilters(in), QString::fromUtf8(name.data(), name.size()),
164 Id<Process::Port>(inlet++), &self};
165 }
166 else
167 {
168 p = new Process::FileChooser{
169 "", getFilters(in), QString::fromUtf8(name.data(), name.size()),
170 Id<Process::Port>(inlet++), &self};
171 }
172
173 p->hidden = true;
174 ins.push_back(p);
175
176 if constexpr(avnd::tag_file_watch<T>)
177 {
178 p->enableFileWatch();
179 }
180 }
181
182 template <typename T>
183 requires avnd::midifile_port<T> || avnd::raw_file_port<T>
184 void operator()(const T& in, auto idx)
185 {
186 static constexpr auto name = avnd::get_name<T>();
187
188 auto p = new Process::FileChooser{
189 "", getFilters(in), QString::fromUtf8(name.data(), name.size()),
190 Id<Process::Port>(inlet++), &self};
191 p->hidden = true;
192 ins.push_back(p);
193
194 if constexpr(avnd::tag_file_watch<T>)
195 {
196 p->enableFileWatch();
197 }
198 }
199
200 template <avnd::dynamic_ports_port T, std::size_t N>
201 void operator()(const T& in, avnd::field_index<N> i)
202 {
203 using port_type = typename decltype(in.ports)::value_type;
204 port_type p;
205 (*this)(p, i);
206 }
207
208 template <avnd::parameter T, std::size_t N>
209 requires(!oscr::ossia_port<T>)
210 void operator()(const T& in, avnd::field_index<N>)
211 {
212 if constexpr(avnd::has_widget<T> || avnd::curve_port<T>)
213 {
214 auto p = oscr::make_control_in<Node, T>(
215 avnd::field_index<N>{}, Id<Process::Port>(inlet), &self);
216 if constexpr(!std::is_same_v<std::decay_t<decltype(p)>, std::nullptr_t>)
217 {
218 p->hidden = true;
219 ins.push_back(p);
220 }
221 else
222 {
223 auto vp = new Process::ValueInlet(Id<Process::Port>(inlet), &self);
224 setupNewPort(in, vp);
225 ins.push_back(vp);
226 }
227 }
228 else
229 {
230 auto vp = new Process::ValueInlet(Id<Process::Port>(inlet), &self);
231 setupNewPort(in, vp);
232 ins.push_back(vp);
233 }
234 inlet++;
235 }
236
237#if SCORE_PLUGIN_GFX
238 void operator()(const avnd::texture_port auto& in, auto idx)
239 {
240 auto p = new Gfx::TextureInlet(Id<Process::Port>(inlet++), &self);
241 setupNewPort(in, p);
242 ins.push_back(p);
243 }
244 void operator()(const avnd::geometry_port auto& in, auto idx)
245 {
246 auto p = new Gfx::GeometryInlet(Id<Process::Port>(inlet++), &self);
247 setupNewPort(in, p);
248 ins.push_back(p);
249 }
250#endif
251
252 template <std::size_t Idx, avnd::message T>
253 void operator()(const avnd::field_reflection<Idx, T>& in, auto dummy)
254 {
255 auto p = new Process::ValueInlet(Id<Process::Port>(inlet++), &self);
256 setupNewPort(in, p);
257 ins.push_back(p);
258 }
259
260 template <std::size_t Idx, avnd::unreflectable_message<Node> T>
261 void operator()(const avnd::field_reflection<Idx, T>& in, auto dummy)
262 {
263 auto p = new Process::ValueInlet(Id<Process::Port>(inlet++), &self);
264 setupNewPort(in, p);
265 ins.push_back(p);
266 }
267
268 void operator()(const auto& ctrl, auto idx)
269 {
270 //(avnd::message<std::decay_t<decltype(ctrl)>>);
271 qDebug() << fromStringView(avnd::get_name(ctrl)) << "unhandled";
272 }
273};
274
275template <typename Node>
277{
279 Process::Outlets& outs;
280 int outlet = 0;
281
282 void operator()(const oscr::ossia_value_port auto& out, auto idx)
283 {
284 auto p = new Process::ValueOutlet(Id<Process::Port>(outlet++), &self);
285 setupNewPort(out, p);
286 outs.push_back(p);
287 }
288 void operator()(const oscr::ossia_audio_port auto& out, auto idx)
289 {
290 auto p = new Process::AudioOutlet(Id<Process::Port>(outlet++), &self);
291 setupNewPort(out, p);
292 outs.push_back(p);
293 }
294 void operator()(const oscr::ossia_midi_port auto& out, auto idx)
295 {
296 auto p = new Process::MidiOutlet(Id<Process::Port>(outlet++), &self);
297 setupNewPort(out, p);
298 outs.push_back(p);
299 }
300
301 template <avnd::dynamic_ports_port T, std::size_t N>
302 void operator()(const T& in, avnd::field_index<N> i)
303 {
304 using port_type = typename decltype(in.ports)::value_type;
305 port_type p;
306 (*this)(p, i);
307 }
308
309 void operator()(const avnd::audio_port auto& out, auto idx)
310 {
311 auto p = new Process::AudioOutlet(Id<Process::Port>(outlet++), &self);
312 setupNewPort(out, p);
313 if(outlet == 1)
314 p->setPropagate(true);
315 outs.push_back(p);
316 }
317
318 void operator()(const avnd::midi_port auto& out, auto idx)
319 {
320 auto p = new Process::MidiOutlet(Id<Process::Port>(outlet++), &self);
321 setupNewPort(out, p);
322 outs.push_back(p);
323 }
324
325 template <avnd::parameter T, std::size_t N>
326 requires(!oscr::ossia_port<T>)
327 void operator()(const T& out, avnd::field_index<N>)
328 {
329 if constexpr(avnd::has_widget<T>)
330 {
331 if(auto p = oscr::make_control_out<T>(
332 avnd::field_index<N>{}, Id<Process::Port>(outlet), &self))
333 {
334 p->hidden = true;
335 outs.push_back(p);
336 }
337 else
338 {
339 // FIXME ControlOutlet?
340 auto vp = new Process::ValueOutlet(Id<Process::Port>(outlet), &self);
341 setupNewPort(out, vp);
342 outs.push_back(vp);
343 }
344 }
345 else
346 {
347 auto vp = new Process::ValueOutlet(Id<Process::Port>(outlet), &self);
348 setupNewPort(out, vp);
349 outs.push_back(vp);
350 }
351 outlet++;
352 }
353
354#if SCORE_PLUGIN_GFX
355 void operator()(const avnd::texture_port auto& out, auto idx)
356 {
357 auto p = new Gfx::TextureOutlet(Id<Process::Port>(outlet++), &self);
358 setupNewPort(out, p);
359 outs.push_back(p);
360 }
361 void operator()(const avnd::geometry_port auto& out, auto idx)
362 {
363 auto p = new Gfx::GeometryOutlet(Id<Process::Port>(outlet++), &self);
364 setupNewPort(out, p);
365 outs.push_back(p);
366 }
367#endif
368
369 void operator()(const avnd::curve_port auto& out, auto idx)
370 {
371 auto p = new Process::ValueOutlet(Id<Process::Port>(outlet++), &self);
372 setupNewPort(out, p);
373 outs.push_back(p);
374 }
375
376 template <avnd::callback T, std::size_t N>
377 void operator()(const T& out, avnd::field_index<N>)
378 {
379 if constexpr(avnd::control<T>)
380 {
381 if(auto p = oscr::make_control_out<T>(
382 avnd::field_index<N>{}, Id<Process::Port>(outlet), &self))
383 {
384 p->hidden = true;
385 outs.push_back(p);
386 }
387 else
388 {
389 // FIXME ControlOutlet?
390 auto vp = new Process::ValueOutlet(Id<Process::Port>(outlet), &self);
391 setupNewPort(out, vp);
392 outs.push_back(vp);
393 }
394 }
395 else if constexpr(requires { T::control; })
396 {
397 // FIXME remove this duplication
398 auto p = new Process::ControlOutlet(Id<Process::Port>(outlet), &self);
399 setupNewPort(out, p);
400 outs.push_back(p);
401 }
402 else
403 {
404 auto p = new Process::ValueOutlet(Id<Process::Port>(outlet), &self);
405 setupNewPort(out, p);
406 outs.push_back(p);
407 }
408 outlet++;
409 }
410
411 void operator()(const auto& ctrl, auto idx)
412 {
413 qDebug() << fromStringView(avnd::get_name(ctrl)) << "unhandled";
414 }
415};
416}
Definition TexturePort.hpp:121
Definition TexturePort.hpp:144
The DropHandler class If something with audio mime type is dropped, then we create a box with an audi...
Definition SoundDrop.hpp:26
Definition Port.hpp:300
Definition Port.hpp:323
Definition Port.hpp:425
Definition Port.hpp:379
Definition Port.hpp:402
Definition Port.hpp:102
The Process class.
Definition score-lib-process/Process/Process.hpp:61
Definition Port.hpp:492
Definition Port.hpp:515
The id_base_t class.
Definition Identifier.hpp:57
Definition Factories.hpp:19
Definition PortForward.hpp:23
Definition PortForward.hpp:27
Definition ProcessModelPortInit.hpp:55
Definition ProcessModelPortInit.hpp:277