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 using port_ptr_type = std::decay_t<decltype(p)>;
217 if constexpr(!std::is_same_v<port_ptr_type, std::nullptr_t>)
218 {
219 if constexpr(
220 !std::is_same_v<port_ptr_type, Process::ControlInlet*>
221 && !std::is_same_v<port_ptr_type, Process::ValueInlet*>)
222 p->hidden = true;
223 ins.push_back(p);
224 }
225 else
226 {
227 auto vp = new Process::ValueInlet(Id<Process::Port>(inlet), &self);
228 setupNewPort(in, vp);
229 ins.push_back(vp);
230 }
231 }
232 else
233 {
234 auto vp = new Process::ValueInlet(Id<Process::Port>(inlet), &self);
235 setupNewPort(in, vp);
236 ins.push_back(vp);
237 }
238 inlet++;
239 }
240
241#if SCORE_PLUGIN_GFX
242 void operator()(const avnd::texture_port auto& in, auto idx)
243 {
244 auto p = new Gfx::TextureInlet(Id<Process::Port>(inlet++), &self);
245 setupNewPort(in, p);
246 ins.push_back(p);
247 }
248 void operator()(const avnd::geometry_port auto& in, auto idx)
249 {
250 auto p = new Gfx::GeometryInlet(Id<Process::Port>(inlet++), &self);
251 setupNewPort(in, p);
252 ins.push_back(p);
253 }
254#endif
255
256 template <std::size_t Idx, avnd::message T>
257 void operator()(const avnd::field_reflection<Idx, T>& in, auto dummy)
258 {
259 auto p = new Process::ValueInlet(Id<Process::Port>(inlet++), &self);
260 setupNewPort(in, p);
261 ins.push_back(p);
262 }
263
264 template <std::size_t Idx, avnd::unreflectable_message<Node> T>
265 void operator()(const avnd::field_reflection<Idx, T>& in, auto dummy)
266 {
267 auto p = new Process::ValueInlet(Id<Process::Port>(inlet++), &self);
268 setupNewPort(in, p);
269 ins.push_back(p);
270 }
271
272 void operator()(const auto& ctrl, auto idx)
273 {
274 //(avnd::message<std::decay_t<decltype(ctrl)>>);
275 qDebug() << fromStringView(avnd::get_name(ctrl)) << "unhandled";
276 }
277};
278
279template <typename Node>
281{
283 Process::Outlets& outs;
284 int outlet = 0;
285
286 void operator()(const oscr::ossia_value_port auto& out, auto idx)
287 {
288 auto p = new Process::ValueOutlet(Id<Process::Port>(outlet++), &self);
289 setupNewPort(out, p);
290 outs.push_back(p);
291 }
292 void operator()(const oscr::ossia_audio_port auto& out, auto idx)
293 {
294 auto p = new Process::AudioOutlet(Id<Process::Port>(outlet++), &self);
295 setupNewPort(out, p);
296 outs.push_back(p);
297 }
298 void operator()(const oscr::ossia_midi_port auto& out, auto idx)
299 {
300 auto p = new Process::MidiOutlet(Id<Process::Port>(outlet++), &self);
301 setupNewPort(out, p);
302 outs.push_back(p);
303 }
304
305 template <avnd::dynamic_ports_port T, std::size_t N>
306 void operator()(const T& in, avnd::field_index<N> i)
307 {
308 using port_type = typename decltype(in.ports)::value_type;
309 port_type p;
310 (*this)(p, i);
311 }
312
313 void operator()(const avnd::audio_port auto& out, auto idx)
314 {
315 auto p = new Process::AudioOutlet(Id<Process::Port>(outlet++), &self);
316 setupNewPort(out, p);
317 if(outlet == 1)
318 p->setPropagate(true);
319 outs.push_back(p);
320 }
321
322 void operator()(const avnd::midi_port auto& out, auto idx)
323 {
324 auto p = new Process::MidiOutlet(Id<Process::Port>(outlet++), &self);
325 setupNewPort(out, p);
326 outs.push_back(p);
327 }
328
329 template <avnd::parameter T, std::size_t N>
330 requires(!oscr::ossia_port<T>)
331 void operator()(const T& out, avnd::field_index<N>)
332 {
333 if constexpr(avnd::has_widget<T>)
334 {
335 if(auto p = oscr::make_control_out<T>(
336 avnd::field_index<N>{}, Id<Process::Port>(outlet), &self))
337 {
338 p->hidden = true;
339 outs.push_back(p);
340 }
341 else
342 {
343 // FIXME ControlOutlet?
344 auto vp = new Process::ValueOutlet(Id<Process::Port>(outlet), &self);
345 setupNewPort(out, vp);
346 outs.push_back(vp);
347 }
348 }
349 else
350 {
351 auto vp = new Process::ValueOutlet(Id<Process::Port>(outlet), &self);
352 setupNewPort(out, vp);
353 outs.push_back(vp);
354 }
355 outlet++;
356 }
357
358#if SCORE_PLUGIN_GFX
359 void operator()(const avnd::texture_port auto& out, auto idx)
360 {
361 auto p = new Gfx::TextureOutlet(Id<Process::Port>(outlet++), &self);
362 setupNewPort(out, p);
363 outs.push_back(p);
364 }
365 void operator()(const avnd::geometry_port auto& out, auto idx)
366 {
367 auto p = new Gfx::GeometryOutlet(Id<Process::Port>(outlet++), &self);
368 setupNewPort(out, p);
369 outs.push_back(p);
370 }
371#endif
372
373 void operator()(const avnd::curve_port auto& out, auto idx)
374 {
375 auto p = new Process::ValueOutlet(Id<Process::Port>(outlet++), &self);
376 setupNewPort(out, p);
377 outs.push_back(p);
378 }
379
380 template <avnd::callback T, std::size_t N>
381 void operator()(const T& out, avnd::field_index<N>)
382 {
383 if constexpr(avnd::control<T>)
384 {
385 if(auto p = oscr::make_control_out<T>(
386 avnd::field_index<N>{}, Id<Process::Port>(outlet), &self))
387 {
388 p->hidden = true;
389 outs.push_back(p);
390 }
391 else
392 {
393 // FIXME ControlOutlet?
394 auto vp = new Process::ValueOutlet(Id<Process::Port>(outlet), &self);
395 setupNewPort(out, vp);
396 outs.push_back(vp);
397 }
398 }
399 else if constexpr(requires { T::control; })
400 {
401 // FIXME remove this duplication
402 auto p = new Process::ControlOutlet(Id<Process::Port>(outlet), &self);
403 setupNewPort(out, p);
404 outs.push_back(p);
405 }
406 else
407 {
408 auto p = new Process::ValueOutlet(Id<Process::Port>(outlet), &self);
409 setupNewPort(out, p);
410 outs.push_back(p);
411 }
412 outlet++;
413 }
414
415 void operator()(const auto& ctrl, auto idx)
416 {
417 qDebug() << fromStringView(avnd::get_name(ctrl)) << "unhandled";
418 }
419};
420}
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: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:59
Definition Factories.hpp:19
Definition PortForward.hpp:23
Definition PortForward.hpp:27
Definition ProcessModelPortInit.hpp:55
Definition ProcessModelPortInit.hpp:281