Loading...
Searching...
No Matches
Port.hpp
1#pragma once
2#include <State/Address.hpp>
3#include <State/Domain.hpp>
4
5#include <Device/Address/AddressSettings.hpp>
6
7#include <Process/Dataflow/PortForward.hpp>
8#include <Process/Dataflow/PortType.hpp>
9
10#include <score/model/IdentifiedObject.hpp>
11#include <score/model/path/Path.hpp>
12#include <score/plugins/SerializableInterface.hpp>
13#include <score/selection/Selectable.hpp>
14#include <score/serialization/VisitorInterface.hpp>
15
16#include <ossia/detail/small_vector.hpp>
17#include <ossia/network/value/value.hpp>
18
19#include <QPointF>
20
21#include <score_lib_process_export.h>
22#include <smallfun.hpp>
23
24#include <verdigris>
25
26#if __cpp_constexpr >= 201907
27#define VIRTUAL_CONSTEXPR constexpr
28#else
29#define VIRTUAL_CONSTEXPR
30#endif
31
32namespace ossia
33{
34struct inlet;
35struct outlet;
36}
37namespace Process
38{
39class Port;
40class Inlet;
41class Outlet;
42class ValueInlet;
43class ValueOutlet;
44class AudioInlet;
45class AudioOutlet;
46class MidiInlet;
47class MidiOutlet;
48class ControlInlet;
49class ControlOutlet;
50}
51UUID_METADATA(
52 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::Inlet,
53 "8884228a-d197-4b0a-b6ca-d1fb15291559")
54UUID_METADATA(
55 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::Outlet,
56 "34e2c5a7-18c4-4759-b6cc-46feaeee06e2")
57UUID_METADATA(
58 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::ValueInlet,
59 "769dd38a-bfb3-4dc6-b52a-b6abb7afe2a3")
60UUID_METADATA(
61 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::ValueOutlet,
62 "cff96158-cc72-46d7-99dc-b6038171375b")
63UUID_METADATA(
64 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::MidiInlet,
65 "c18adc77-e0e0-4ddf-a46c-43cb0719a890")
66UUID_METADATA(
67 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::MidiOutlet,
68 "d8a3ed3d-b9c2-46f2-bdb3-d282a48481c6")
69UUID_METADATA(
70 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::AudioInlet,
71 "a1574bb0-cbd4-4c7d-9417-0c25cfd1187b")
72UUID_METADATA(
73 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::AudioOutlet,
74 "a1d97535-18ac-444a-8417-0cbc1692d897")
75UUID_METADATA(
76 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::ControlInlet,
77 "9a13fb32-269a-47bf-99a9-930188c1f19c")
78UUID_METADATA(
79 SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::ControlOutlet,
80 "3620ea94-5991-41cf-89b3-11f842cc39d0")
81namespace Process
82{
83
84// Used to know where to layout items for a given
85// kind of port.
86static constexpr const qreal default_margin = 5.;
87static constexpr const qreal default_padding = 5.;
88
90{
91 QPointF port{0., 1.};
92 QPointF label{12., 0.};
93 QPointF control{0., 12.};
94 std::optional<Qt::Alignment> labelAlignment{std::nullopt};
95 bool labelVisible{true};
96};
97
98class Cable;
99class SCORE_LIB_PROCESS_EXPORT Port
100 : public IdentifiedObject<Port>
101 , public score::SerializableInterface<Port>
102{
103 W_OBJECT(Port)
104 SCORE_SERIALIZE_FRIENDS
105public:
106 Selectable selection{this};
107 bool hidden{};
108 bool noValueChangeOnMove{};
109
110 void addCable(const Process::Cable& c);
111 void removeCable(const Path<Process::Cable>& c);
112 void takeCables(Process::Port&& c);
113
114 const QString& visualName() const noexcept;
115 const QString& visualDescription() const noexcept;
116
117 const QString& name() const noexcept;
118 const State::AddressAccessor& address() const noexcept;
119 const std::vector<Path<Cable>>& cables() const noexcept;
120 const QString& exposed() const noexcept;
121 const QString& description() const noexcept;
122
123 virtual PortType type() const noexcept = 0;
124
125 virtual Device::FullAddressAccessorSettings settings() const noexcept;
126 virtual void setSettings(const Device::FullAddressAccessorSettings& set) noexcept;
127
128public:
129 void setName(const QString& customData);
130 W_SLOT(setName);
131 void setExposed(const QString& add);
132 W_SLOT(setExposed);
133 void setDescription(const QString& add);
134 W_SLOT(setDescription);
135 void setAddress(const State::AddressAccessor& address);
136 W_SLOT(setAddress);
137
138 void nameChanged(const QString& name)
139 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, nameChanged, name)
140 void exposedChanged(const QString& addr)
141 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, exposedChanged, addr)
142 void descriptionChanged(const QString& txt)
143 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, descriptionChanged, txt)
144 void cablesChanged() E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, cablesChanged)
145 void addressChanged(const State::AddressAccessor& address)
146 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, addressChanged, address)
147 void executionReset() E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, executionReset)
148
149 PROPERTY(
151 address W_READ address W_WRITE setAddress W_NOTIFY addressChanged)
152 PROPERTY(QString, name W_READ name W_WRITE setName W_NOTIFY nameChanged)
153 PROPERTY(Process::PortType, type W_READ type W_CONSTANT W_FINAL)
154
155 virtual QByteArray saveData() const noexcept;
156 virtual void loadData(const QByteArray& arr) noexcept;
157
158protected:
159 Port() = delete;
160 ~Port() override;
161 Port(const Port&) = delete;
162 Port(Id<Port> c, const QString& name, QObject* parent);
163
164 Port(DataStream::Deserializer& vis, QObject* parent);
165 Port(JSONObject::Deserializer& vis, QObject* parent);
166 Port(DataStream::Deserializer&& vis, QObject* parent);
167 Port(JSONObject::Deserializer&& vis, QObject* parent);
168
169private:
170 std::vector<Path<Cable>> m_cables;
171 QString m_name;
172 QString m_exposed;
173 QString m_description;
174 State::AddressAccessor m_address;
175};
176
177class SCORE_LIB_PROCESS_EXPORT Inlet : public Port
178{
179 W_OBJECT(Inlet)
180public:
181 using score_base_type = Inlet;
182 MODEL_METADATA_IMPL_HPP(Inlet)
183
184 ~Inlet() override;
185
186 virtual void setupExecution(ossia::inlet&, QObject* exec_context) const noexcept;
187 virtual void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept;
188 virtual void mapExecution(
189 ossia::inlet&,
190 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept;
191
192protected:
193 Inlet() = delete;
194 Inlet(const Inlet&) = delete;
195 Inlet(Id<Process::Port> c, QObject* parent);
196
197 Inlet(DataStream::Deserializer& vis, QObject* parent);
198 Inlet(JSONObject::Deserializer& vis, QObject* parent);
199 Inlet(DataStream::Deserializer&& vis, QObject* parent);
200 Inlet(JSONObject::Deserializer&& vis, QObject* parent);
201};
202
203class SCORE_LIB_PROCESS_EXPORT ControlInlet : public Inlet
204{
205 W_OBJECT(ControlInlet)
206
207 SCORE_SERIALIZE_FRIENDS
208public:
209 MODEL_METADATA_IMPL_HPP(ControlInlet)
210 ControlInlet() = delete;
211 ~ControlInlet() override;
212 ControlInlet(const ControlInlet&) = delete;
213 ControlInlet(const QString& name, Id<Process::Port> c, QObject* parent);
214 ControlInlet(Id<Process::Port> c, QObject* parent);
215
216 ControlInlet(DataStream::Deserializer& vis, QObject* parent, bool skip_this = false);
217 ControlInlet(JSONObject::Deserializer& vis, QObject* parent, bool skip_this = false);
218 ControlInlet(DataStream::Deserializer&& vis, QObject* parent, bool skip_this = false);
219 ControlInlet(JSONObject::Deserializer&& vis, QObject* parent, bool skip_this = false);
220
221 VIRTUAL_CONSTEXPR PortType type() const noexcept override
222 {
223 return Process::PortType::Message;
224 }
225
226 const ossia::value& value() const noexcept { return m_value; }
227 const ossia::value& init() const noexcept { return m_init; }
228 const State::Domain& domain() const noexcept { return m_domain; }
229
230 QByteArray saveData() const noexcept override;
231 void loadData(const QByteArray& arr) noexcept override;
232
233public:
234 void valueChanged(const ossia::value& v)
235 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, valueChanged, v)
236 void initChanged(const ossia::value& v)
237 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, initChanged, v)
238 void executionValueChanged(const ossia::value& v)
239 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, executionValueChanged, v)
240 void domainChanged(const State::Domain& d)
241 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, domainChanged, d)
242
243public:
244 void setValue(const ossia::value& value);
245 W_SLOT(setValue)
246 void setInit(const ossia::value& value);
247 W_SLOT(setInit)
248
249 inline void setExecutionValue(const ossia::value& value)
250 {
251 executionValueChanged(value);
252 }
253
254 void setDomain(const State::Domain& d)
255 {
256 if(m_domain != d)
257 {
258 m_domain = d;
259 domainChanged(d);
260 }
261 }
262 W_SLOT(setDomain)
263
264 PROPERTY(State::Domain, domain W_READ domain W_WRITE setDomain W_NOTIFY domainChanged)
265 PROPERTY(ossia::value, value W_READ value W_WRITE setValue W_NOTIFY valueChanged)
266 PROPERTY(ossia::value, init W_READ init W_WRITE setInit W_NOTIFY initChanged)
267private:
268 ossia::value m_value;
269 ossia::value m_init;
270 State::Domain m_domain;
271};
272
273class SCORE_LIB_PROCESS_EXPORT Outlet : public Port
274{
275 W_OBJECT(Outlet)
276
277 SCORE_SERIALIZE_FRIENDS
278public:
279 using score_base_type = Outlet;
280 MODEL_METADATA_IMPL_HPP(Outlet)
281
282 ~Outlet() override;
283 virtual void setupExecution(ossia::outlet&, QObject* exec_context) const noexcept;
284 virtual void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept;
285 virtual void mapExecution(
286 ossia::outlet&,
287 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept;
288
289protected:
290 Outlet() = delete;
291 Outlet(const Outlet&) = delete;
292 Outlet(Id<Process::Port> c, QObject* parent);
293
294 Outlet(DataStream::Deserializer& vis, QObject* parent);
295 Outlet(JSONObject::Deserializer& vis, QObject* parent);
296 Outlet(DataStream::Deserializer&& vis, QObject* parent);
297 Outlet(JSONObject::Deserializer&& vis, QObject* parent);
298};
299
300class SCORE_LIB_PROCESS_EXPORT AudioInlet : public Inlet
301{
302 W_OBJECT(AudioInlet)
303
304 SCORE_SERIALIZE_FRIENDS
305public:
306 MODEL_METADATA_IMPL_HPP(AudioInlet)
307 AudioInlet() = delete;
308 ~AudioInlet() override;
309 AudioInlet(const AudioInlet&) = delete;
310 AudioInlet(Id<Process::Port> c, QObject* parent);
311
312 AudioInlet(DataStream::Deserializer& vis, QObject* parent);
313 AudioInlet(JSONObject::Deserializer& vis, QObject* parent);
314 AudioInlet(DataStream::Deserializer&& vis, QObject* parent);
315 AudioInlet(JSONObject::Deserializer&& vis, QObject* parent);
316
317 VIRTUAL_CONSTEXPR PortType type() const noexcept override
318 {
319 return Process::PortType::Audio;
320 }
321};
322
323class SCORE_LIB_PROCESS_EXPORT AudioOutlet : public Outlet
324{
325 W_OBJECT(AudioOutlet)
326
327 SCORE_SERIALIZE_FRIENDS
328public:
329 MODEL_METADATA_IMPL_HPP(AudioOutlet)
330 AudioOutlet() = delete;
331 ~AudioOutlet() override;
332 AudioOutlet(const AudioOutlet&) = delete;
333 AudioOutlet(Id<Process::Port> c, QObject* parent);
334
335 AudioOutlet(DataStream::Deserializer& vis, QObject* parent);
336 AudioOutlet(JSONObject::Deserializer& vis, QObject* parent);
337 AudioOutlet(DataStream::Deserializer&& vis, QObject* parent);
338 AudioOutlet(JSONObject::Deserializer&& vis, QObject* parent);
339
340 VIRTUAL_CONSTEXPR PortType type() const noexcept override
341 {
342 return Process::PortType::Audio;
343 }
344
345 void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept override;
346 void mapExecution(
347 ossia::outlet&,
348 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept override;
349
350 QByteArray saveData() const noexcept override;
351 void loadData(const QByteArray& arr) noexcept override;
352
353 bool propagate() const;
354 void setPropagate(bool propagate);
355 void propagateChanged(bool propagate)
356 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, propagateChanged, propagate)
357
358 double gain() const;
359 void setGain(double g);
360 void gainChanged(double g) E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, gainChanged, g)
361
362 pan_weight pan() const;
363 void setPan(pan_weight g);
364 void panChanged(pan_weight g) E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, panChanged, g)
365
366 std::unique_ptr<Process::ControlInlet> gainInlet;
367 std::unique_ptr<Process::ControlInlet> panInlet;
368
369 PROPERTY(
370 bool, propagate W_READ propagate W_WRITE setPropagate W_NOTIFY propagateChanged)
371 PROPERTY(double, gain W_READ gain W_WRITE setGain W_NOTIFY gainChanged)
372 PROPERTY(pan_weight, pan W_READ pan W_WRITE setPan W_NOTIFY panChanged)
373private:
374 double m_gain{};
375 pan_weight m_pan;
376 bool m_propagate{false};
377};
378
379class SCORE_LIB_PROCESS_EXPORT MidiInlet : public Inlet
380{
381 W_OBJECT(MidiInlet)
382
383 SCORE_SERIALIZE_FRIENDS
384public:
385 MODEL_METADATA_IMPL_HPP(MidiInlet)
386 MidiInlet() = delete;
387 ~MidiInlet() override;
388 MidiInlet(const MidiInlet&) = delete;
389 MidiInlet(Id<Process::Port> c, QObject* parent);
390
391 MidiInlet(DataStream::Deserializer& vis, QObject* parent);
392 MidiInlet(JSONObject::Deserializer& vis, QObject* parent);
393 MidiInlet(DataStream::Deserializer&& vis, QObject* parent);
394 MidiInlet(JSONObject::Deserializer&& vis, QObject* parent);
395
396 VIRTUAL_CONSTEXPR PortType type() const noexcept override
397 {
398 return Process::PortType::Midi;
399 }
400};
401
402class SCORE_LIB_PROCESS_EXPORT MidiOutlet : public Outlet
403{
404 W_OBJECT(MidiOutlet)
405
406 SCORE_SERIALIZE_FRIENDS
407public:
408 MODEL_METADATA_IMPL_HPP(MidiOutlet)
409 MidiOutlet() = delete;
410 ~MidiOutlet() override;
411 MidiOutlet(const MidiOutlet&) = delete;
412 MidiOutlet(Id<Process::Port> c, QObject* parent);
413
414 MidiOutlet(DataStream::Deserializer& vis, QObject* parent);
415 MidiOutlet(JSONObject::Deserializer& vis, QObject* parent);
416 MidiOutlet(DataStream::Deserializer&& vis, QObject* parent);
417 MidiOutlet(JSONObject::Deserializer&& vis, QObject* parent);
418
419 VIRTUAL_CONSTEXPR PortType type() const noexcept override
420 {
421 return Process::PortType::Midi;
422 }
423};
424
425class SCORE_LIB_PROCESS_EXPORT ControlOutlet : public Outlet
426{
427 W_OBJECT(ControlOutlet)
428
429 SCORE_SERIALIZE_FRIENDS
430public:
431 MODEL_METADATA_IMPL_HPP(ControlOutlet)
432 ControlOutlet() = delete;
433 ControlOutlet(const Outlet&) = delete;
434 ControlOutlet(const QString& name, Id<Process::Port> c, QObject* parent);
435 ControlOutlet(Id<Process::Port> c, QObject* parent);
436 ~ControlOutlet() override;
437
438 ControlOutlet(DataStream::Deserializer& vis, QObject* parent);
439 ControlOutlet(JSONObject::Deserializer& vis, QObject* parent);
440 ControlOutlet(DataStream::Deserializer&& vis, QObject* parent);
441 ControlOutlet(JSONObject::Deserializer&& vis, QObject* parent);
442
443 VIRTUAL_CONSTEXPR PortType type() const noexcept override
444 {
445 return Process::PortType::Message;
446 }
447
448 QByteArray saveData() const noexcept override;
449 void loadData(const QByteArray& arr) noexcept override;
450
451 const ossia::value& value() const { return m_value; }
452 const State::Domain& domain() const { return m_domain; }
453
454public:
455 void valueChanged(const ossia::value& v)
456 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, valueChanged, v)
457 void executionValueChanged(const ossia::value& v)
458 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, executionValueChanged, v)
459 void domainChanged(const State::Domain& d)
460 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, domainChanged, d)
461
462public:
463 void setExecutionValue(const ossia::value& value) { executionValueChanged(value); }
464
465 void setValue(const ossia::value& value)
466 {
467 if(value != m_value)
468 {
469 m_value = value;
470 valueChanged(value);
471 }
472 }
473 W_SLOT(setValue)
474
475 void setDomain(const State::Domain& d)
476 {
477 if(m_domain != d)
478 {
479 m_domain = d;
480 domainChanged(d);
481 }
482 }
483 W_SLOT(setDomain)
484
485 PROPERTY(State::Domain, domain W_READ domain W_WRITE setDomain W_NOTIFY domainChanged)
486 PROPERTY(ossia::value, value W_READ value W_WRITE setValue W_NOTIFY valueChanged)
487private:
488 ossia::value m_value;
489 State::Domain m_domain;
490};
491
492class SCORE_LIB_PROCESS_EXPORT ValueInlet : public Inlet
493{
494 W_OBJECT(ValueInlet)
495
496 SCORE_SERIALIZE_FRIENDS
497public:
498 MODEL_METADATA_IMPL_HPP(ValueInlet)
499 ValueInlet() = delete;
500 ~ValueInlet() override;
501 ValueInlet(const ValueInlet&) = delete;
502 ValueInlet(Id<Process::Port> c, QObject* parent);
503
504 ValueInlet(DataStream::Deserializer& vis, QObject* parent);
505 ValueInlet(JSONObject::Deserializer& vis, QObject* parent);
506 ValueInlet(DataStream::Deserializer&& vis, QObject* parent);
507 ValueInlet(JSONObject::Deserializer&& vis, QObject* parent);
508
509 VIRTUAL_CONSTEXPR PortType type() const noexcept override
510 {
511 return Process::PortType::Message;
512 }
513};
514
515class SCORE_LIB_PROCESS_EXPORT ValueOutlet : public Outlet
516{
517 W_OBJECT(ValueOutlet)
518
519 SCORE_SERIALIZE_FRIENDS
520public:
521 MODEL_METADATA_IMPL_HPP(ValueOutlet)
522 ValueOutlet() = delete;
523 ~ValueOutlet() override;
524 ValueOutlet(const ValueOutlet&) = delete;
525 ValueOutlet(Id<Process::Port> c, QObject* parent);
526
527 ValueOutlet(DataStream::Deserializer& vis, QObject* parent);
528 ValueOutlet(JSONObject::Deserializer& vis, QObject* parent);
529 ValueOutlet(DataStream::Deserializer&& vis, QObject* parent);
530 ValueOutlet(JSONObject::Deserializer&& vis, QObject* parent);
531
532 VIRTUAL_CONSTEXPR PortType type() const noexcept override
533 {
534 return Process::PortType::Message;
535 }
536};
537
538SCORE_LIB_PROCESS_EXPORT
539std::unique_ptr<Inlet> make_value_inlet(const Id<Process::Port>& c, QObject* parent);
540SCORE_LIB_PROCESS_EXPORT
541std::unique_ptr<Outlet> make_value_outlet(const Id<Process::Port>& c, QObject* parent);
542
543SCORE_LIB_PROCESS_EXPORT
544std::unique_ptr<MidiInlet> make_midi_inlet(const Id<Process::Port>& c, QObject* parent);
545SCORE_LIB_PROCESS_EXPORT
546std::unique_ptr<MidiOutlet>
547make_midi_outlet(const Id<Process::Port>& c, QObject* parent);
548
549SCORE_LIB_PROCESS_EXPORT
550std::unique_ptr<AudioInlet>
551make_audio_inlet(const Id<Process::Port>& c, QObject* parent);
552SCORE_LIB_PROCESS_EXPORT
553std::unique_ptr<AudioOutlet>
554make_audio_outlet(const Id<Process::Port>& c, QObject* parent);
555
556}
557
558DEFAULT_MODEL_METADATA(Process::Port, "Port")
559
560W_REGISTER_ARGTYPE(Id<Process::Port>)
561W_REGISTER_ARGTYPE(Process::Port)
562
563// Q_DECLARE_METATYPE(Process::pan_weight)
564W_REGISTER_ARGTYPE(Process::pan_weight)
Definition DataStreamVisitor.hpp:202
The IdentifiedObject class.
Definition IdentifiedObject.hpp:19
Definition JSONVisitor.hpp:423
The Path class is a typesafe wrapper around ObjectPath.
Definition Path.hpp:52
Definition Port.hpp:301
Definition Port.hpp:324
Definition Cable.hpp:38
Definition Port.hpp:204
Definition Port.hpp:426
Definition Port.hpp:178
Definition Port.hpp:380
Definition Port.hpp:403
Definition Port.hpp:274
Definition Port.hpp:102
Definition Port.hpp:493
Definition Port.hpp:516
The Selectable class.
Definition Selectable.hpp:14
The id_base_t class.
Definition Identifier.hpp:59
Generic serialization method for abstract classes.
Definition SerializableInterface.hpp:21
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
Definition AddressSettings.hpp:131
Definition Port.hpp:90
Definition PortForward.hpp:31
Definition Address.hpp:108
Definition Domain.hpp:17