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 Qt::Alignment labelAlignment{};
95 Qt::Alignment controlAlignment{};
96 bool labelVisible{true};
97};
98
99class Cable;
100class SCORE_LIB_PROCESS_EXPORT Port
101 : public IdentifiedObject<Port>
102 , public score::SerializableInterface<Port>
103{
104 W_OBJECT(Port)
105 SCORE_SERIALIZE_FRIENDS
106public:
107 Selectable selection{this};
108 bool displayHandledExplicitly{};
109 bool noValueChangeOnMove{};
110
111 void addCable(const Process::Cable& c);
112 void removeCable(const Path<Process::Cable>& c);
113 void takeCables(Process::Port&& c);
114
115 const QString& visualName() const noexcept;
116 const QString& visualDescription() const noexcept;
117
118 const QString& name() const noexcept;
119 const State::AddressAccessor& address() const noexcept;
120 const std::vector<Path<Cable>>& cables() const noexcept;
121 const QString& exposed() const noexcept;
122 const QString& description() const noexcept;
123
124 virtual PortType type() const noexcept = 0;
125
126 virtual Device::FullAddressAccessorSettings settings() const noexcept;
127 virtual void setSettings(const Device::FullAddressAccessorSettings& set) noexcept;
128
129public:
130 void setName(const QString& customData);
131 W_SLOT(setName);
132 void setExposed(const QString& add);
133 W_SLOT(setExposed);
134 void setDescription(const QString& add);
135 W_SLOT(setDescription);
136 void setAddress(const State::AddressAccessor& address);
137 W_SLOT(setAddress);
138
139 void nameChanged(const QString& name)
140 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, nameChanged, name)
141 void exposedChanged(const QString& addr)
142 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, exposedChanged, addr)
143 void descriptionChanged(const QString& txt)
144 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, descriptionChanged, txt)
145 void cablesChanged() E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, cablesChanged)
146 void addressChanged(const State::AddressAccessor& address)
147 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, addressChanged, address)
148 void executionReset() E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, executionReset)
149
150 PROPERTY(
152 address W_READ address W_WRITE setAddress W_NOTIFY addressChanged)
153 PROPERTY(QString, name W_READ name W_WRITE setName W_NOTIFY nameChanged)
154 PROPERTY(Process::PortType, type W_READ type W_CONSTANT W_FINAL)
155
156 virtual QByteArray saveData() const noexcept;
157
158 virtual void loadData(const QByteArray& arr, PortLoadDataFlags = {}) noexcept;
159
160protected:
161 Port() = delete;
162 ~Port() override;
163 Port(const Port&) = delete;
164 Port(Id<Port> c, const QString& name, QObject* parent);
165
166 Port(DataStream::Deserializer& vis, QObject* parent);
167 Port(JSONObject::Deserializer& vis, QObject* parent);
168 Port(DataStream::Deserializer&& vis, QObject* parent);
169 Port(JSONObject::Deserializer&& vis, QObject* parent);
170
171private:
172 std::vector<Path<Cable>> m_cables;
173 QString m_name;
174 QString m_exposed;
175 QString m_description;
176 State::AddressAccessor m_address;
177};
178
179class SCORE_LIB_PROCESS_EXPORT Inlet : public Port
180{
181 W_OBJECT(Inlet)
182public:
183 using score_base_type = Inlet;
184 MODEL_METADATA_IMPL_HPP(Inlet)
185
186 ~Inlet() override;
187
188 virtual void setupExecution(ossia::inlet&, QObject* exec_context) const noexcept;
189 virtual void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept;
190 virtual void mapExecution(
191 ossia::inlet&,
192 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept;
193
194protected:
195 Inlet() = delete;
196 Inlet(const Inlet&) = delete;
197 Inlet(const QString& name, Id<Process::Port> c, QObject* parent);
198
199 Inlet(DataStream::Deserializer& vis, QObject* parent);
200 Inlet(JSONObject::Deserializer& vis, QObject* parent);
201 Inlet(DataStream::Deserializer&& vis, QObject* parent);
202 Inlet(JSONObject::Deserializer&& vis, QObject* parent);
203};
204
205class SCORE_LIB_PROCESS_EXPORT ControlInlet : public Inlet
206{
207 W_OBJECT(ControlInlet)
208
209 SCORE_SERIALIZE_FRIENDS
210public:
211 MODEL_METADATA_IMPL_HPP(ControlInlet)
212 ControlInlet() = delete;
213 ~ControlInlet() override;
214 ControlInlet(const ControlInlet&) = delete;
215 ControlInlet(const QString& name, Id<Process::Port> c, QObject* parent);
216
217 ControlInlet(DataStream::Deserializer& vis, QObject* parent, bool skip_this = false);
218 ControlInlet(JSONObject::Deserializer& vis, QObject* parent, bool skip_this = false);
219 ControlInlet(DataStream::Deserializer&& vis, QObject* parent, bool skip_this = false);
220 ControlInlet(JSONObject::Deserializer&& vis, QObject* parent, bool skip_this = false);
221
222 VIRTUAL_CONSTEXPR PortType type() const noexcept override
223 {
224 return Process::PortType::Message;
225 }
226
227 const ossia::value& value() const noexcept { return m_value; }
228 const ossia::value& init() const noexcept { return m_init; }
229 const State::Domain& domain() const noexcept { return m_domain; }
230
231 QByteArray saveData() const noexcept override;
232 void loadData(const QByteArray& arr, PortLoadDataFlags = {}) noexcept override;
233
234public:
235 void valueChanged(const ossia::value& v)
236 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, valueChanged, v)
237 void initChanged(const ossia::value& v)
238 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, initChanged, v)
239 void executionValueChanged(const ossia::value& v)
240 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, executionValueChanged, v)
241 void domainChanged(const State::Domain& d)
242 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, domainChanged, d)
243
244public:
245 void setValue(const ossia::value& value);
246 W_SLOT(setValue)
247 void setInit(const ossia::value& value);
248 W_SLOT(setInit)
249
250 inline void setExecutionValue(const ossia::value& value)
251 {
252 executionValueChanged(value);
253 }
254
255 void setDomain(const State::Domain& d)
256 {
257 if(m_domain != d)
258 {
259 m_domain = d;
260 domainChanged(d);
261 }
262 }
263 W_SLOT(setDomain)
264
265 PROPERTY(State::Domain, domain W_READ domain W_WRITE setDomain W_NOTIFY domainChanged)
266 PROPERTY(ossia::value, value W_READ value W_WRITE setValue W_NOTIFY valueChanged)
267 PROPERTY(ossia::value, init W_READ init W_WRITE setInit W_NOTIFY initChanged)
268private:
269 ossia::value m_value;
270 ossia::value m_init;
271 State::Domain m_domain;
272};
273
274class SCORE_LIB_PROCESS_EXPORT Outlet : public Port
275{
276 W_OBJECT(Outlet)
277
278 SCORE_SERIALIZE_FRIENDS
279public:
280 using score_base_type = Outlet;
281 MODEL_METADATA_IMPL_HPP(Outlet)
282
283 ~Outlet() override;
284 virtual void setupExecution(ossia::outlet&, QObject* exec_context) const noexcept;
285 virtual void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept;
286 virtual void mapExecution(
287 ossia::outlet&,
288 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept;
289
290protected:
291 Outlet() = delete;
292 Outlet(const Outlet&) = delete;
293 Outlet(const QString& name, Id<Process::Port> c, QObject* parent);
294
295 Outlet(DataStream::Deserializer& vis, QObject* parent);
296 Outlet(JSONObject::Deserializer& vis, QObject* parent);
297 Outlet(DataStream::Deserializer&& vis, QObject* parent);
298 Outlet(JSONObject::Deserializer&& vis, QObject* parent);
299};
300
301class SCORE_LIB_PROCESS_EXPORT AudioInlet : public Inlet
302{
303 W_OBJECT(AudioInlet)
304
305 SCORE_SERIALIZE_FRIENDS
306public:
307 MODEL_METADATA_IMPL_HPP(AudioInlet)
308 AudioInlet() = delete;
309 ~AudioInlet() override;
310 AudioInlet(const AudioInlet&) = delete;
311 AudioInlet(const QString& name, Id<Process::Port> c, QObject* parent);
312
313 AudioInlet(DataStream::Deserializer& vis, QObject* parent);
314 AudioInlet(JSONObject::Deserializer& vis, QObject* parent);
315 AudioInlet(DataStream::Deserializer&& vis, QObject* parent);
316 AudioInlet(JSONObject::Deserializer&& vis, QObject* parent);
317
318 VIRTUAL_CONSTEXPR PortType type() const noexcept override
319 {
320 return Process::PortType::Audio;
321 }
322};
323
324class SCORE_LIB_PROCESS_EXPORT AudioOutlet : public Outlet
325{
326 W_OBJECT(AudioOutlet)
327
328 SCORE_SERIALIZE_FRIENDS
329public:
330 MODEL_METADATA_IMPL_HPP(AudioOutlet)
331 AudioOutlet() = delete;
332 ~AudioOutlet() override;
333 AudioOutlet(const AudioOutlet&) = delete;
334 AudioOutlet(const QString& name, Id<Process::Port> c, QObject* parent);
335
336 AudioOutlet(DataStream::Deserializer& vis, QObject* parent);
337 AudioOutlet(JSONObject::Deserializer& vis, QObject* parent);
338 AudioOutlet(DataStream::Deserializer&& vis, QObject* parent);
339 AudioOutlet(JSONObject::Deserializer&& vis, QObject* parent);
340
341 VIRTUAL_CONSTEXPR PortType type() const noexcept override
342 {
343 return Process::PortType::Audio;
344 }
345
346 void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept override;
347 void mapExecution(
348 ossia::outlet&,
349 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept override;
350
351 QByteArray saveData() const noexcept override;
352 void loadData(const QByteArray& arr, PortLoadDataFlags = {}) noexcept override;
353
354 bool propagate() const;
355 void setPropagate(bool propagate);
356 void propagateChanged(bool propagate)
357 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, propagateChanged, propagate)
358
359 double gain() const;
360 void setGain(double g);
361 void gainChanged(double g) E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, gainChanged, g)
362
363 pan_weight pan() const;
364 void setPan(pan_weight g);
365 void panChanged(pan_weight g) E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, panChanged, g)
366
367 std::unique_ptr<Process::ControlInlet> gainInlet;
368 std::unique_ptr<Process::ControlInlet> panInlet;
369
370 PROPERTY(
371 bool, propagate W_READ propagate W_WRITE setPropagate W_NOTIFY propagateChanged)
372 PROPERTY(double, gain W_READ gain W_WRITE setGain W_NOTIFY gainChanged)
373 PROPERTY(pan_weight, pan W_READ pan W_WRITE setPan W_NOTIFY panChanged)
374private:
375 double m_gain{};
376 pan_weight m_pan;
377 bool m_propagate{false};
378};
379
380class SCORE_LIB_PROCESS_EXPORT MidiInlet : public Inlet
381{
382 W_OBJECT(MidiInlet)
383
384 SCORE_SERIALIZE_FRIENDS
385public:
386 MODEL_METADATA_IMPL_HPP(MidiInlet)
387 MidiInlet() = delete;
388 ~MidiInlet() override;
389 MidiInlet(const MidiInlet&) = delete;
390 MidiInlet(const QString& name, Id<Process::Port> c, QObject* parent);
391
392 MidiInlet(DataStream::Deserializer& vis, QObject* parent);
393 MidiInlet(JSONObject::Deserializer& vis, QObject* parent);
394 MidiInlet(DataStream::Deserializer&& vis, QObject* parent);
395 MidiInlet(JSONObject::Deserializer&& vis, QObject* parent);
396
397 VIRTUAL_CONSTEXPR PortType type() const noexcept override
398 {
399 return Process::PortType::Midi;
400 }
401};
402
403class SCORE_LIB_PROCESS_EXPORT MidiOutlet : public Outlet
404{
405 W_OBJECT(MidiOutlet)
406
407 SCORE_SERIALIZE_FRIENDS
408public:
409 MODEL_METADATA_IMPL_HPP(MidiOutlet)
410 MidiOutlet() = delete;
411 ~MidiOutlet() override;
412 MidiOutlet(const MidiOutlet&) = delete;
413 MidiOutlet(const QString& name, Id<Process::Port> c, QObject* parent);
414
415 MidiOutlet(DataStream::Deserializer& vis, QObject* parent);
416 MidiOutlet(JSONObject::Deserializer& vis, QObject* parent);
417 MidiOutlet(DataStream::Deserializer&& vis, QObject* parent);
418 MidiOutlet(JSONObject::Deserializer&& vis, QObject* parent);
419
420 VIRTUAL_CONSTEXPR PortType type() const noexcept override
421 {
422 return Process::PortType::Midi;
423 }
424};
425
426class SCORE_LIB_PROCESS_EXPORT ControlOutlet : public Outlet
427{
428 W_OBJECT(ControlOutlet)
429
430 SCORE_SERIALIZE_FRIENDS
431public:
432 MODEL_METADATA_IMPL_HPP(ControlOutlet)
433 ControlOutlet() = delete;
434 ControlOutlet(const Outlet&) = delete;
435 ControlOutlet(const QString& name, 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, PortLoadDataFlags = {}) 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(const QString& name, 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(const QString& name, 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
538}
539
540DEFAULT_MODEL_METADATA(Process::Port, "Port")
541
542W_REGISTER_ARGTYPE(Id<Process::Port>)
543W_REGISTER_ARGTYPE(Process::Port)
544W_REGISTER_ARGTYPE(Process::Inlet)
545W_REGISTER_ARGTYPE(Process::Outlet)
546W_REGISTER_ARGTYPE(Process::ControlInlet)
547W_REGISTER_ARGTYPE(Process::ControlOutlet)
548W_REGISTER_ARGTYPE(Process::ValueInlet)
549W_REGISTER_ARGTYPE(Process::ValueOutlet)
550W_REGISTER_ARGTYPE(Process::MidiInlet)
551W_REGISTER_ARGTYPE(Process::MidiOutlet)
552W_REGISTER_ARGTYPE(Process::AudioInlet)
553W_REGISTER_ARGTYPE(Process::AudioOutlet)
554
555W_REGISTER_ARGTYPE(Process::Port*)
556W_REGISTER_ARGTYPE(Process::Inlet*)
557W_REGISTER_ARGTYPE(Process::Outlet*)
558W_REGISTER_ARGTYPE(Process::ControlInlet*)
559W_REGISTER_ARGTYPE(Process::ControlOutlet*)
560W_REGISTER_ARGTYPE(Process::ValueInlet*)
561W_REGISTER_ARGTYPE(Process::ValueOutlet*)
562W_REGISTER_ARGTYPE(Process::MidiInlet*)
563W_REGISTER_ARGTYPE(Process::MidiOutlet*)
564W_REGISTER_ARGTYPE(Process::AudioInlet*)
565W_REGISTER_ARGTYPE(Process::AudioOutlet*)
566// Q_DECLARE_METATYPE(Process::pan_weight)
567W_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:302
Definition Port.hpp:325
Definition Cable.hpp:38
Definition Port.hpp:206
Definition Port.hpp:427
Definition Port.hpp:180
Definition Port.hpp:381
Definition Port.hpp:404
Definition Port.hpp:275
Definition Port.hpp:103
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