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