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