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
154 virtual QByteArray saveData() const noexcept;
155 virtual void loadData(const QByteArray& arr) noexcept;
156
157protected:
158 Port() = delete;
159 ~Port() override;
160 Port(const Port&) = delete;
161 Port(Id<Port> c, const QString& name, QObject* parent);
162
163 Port(DataStream::Deserializer& vis, QObject* parent);
164 Port(JSONObject::Deserializer& vis, QObject* parent);
165 Port(DataStream::Deserializer&& vis, QObject* parent);
166 Port(JSONObject::Deserializer&& vis, QObject* parent);
167
168private:
169 std::vector<Path<Cable>> m_cables;
170 QString m_name;
171 QString m_exposed;
172 QString m_description;
173 State::AddressAccessor m_address;
174};
175
176class SCORE_LIB_PROCESS_EXPORT Inlet : public Port
177{
178 W_OBJECT(Inlet)
179public:
180 using score_base_type = Inlet;
181 MODEL_METADATA_IMPL_HPP(Inlet)
182
183 ~Inlet() override;
184
185 virtual void setupExecution(ossia::inlet&) const noexcept;
186 virtual void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept;
187 virtual void mapExecution(
188 ossia::inlet&,
189 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept;
190
191protected:
192 Inlet() = delete;
193 Inlet(const Inlet&) = delete;
194 Inlet(Id<Process::Port> c, QObject* parent);
195
196 Inlet(DataStream::Deserializer& vis, QObject* parent);
197 Inlet(JSONObject::Deserializer& vis, QObject* parent);
198 Inlet(DataStream::Deserializer&& vis, QObject* parent);
199 Inlet(JSONObject::Deserializer&& vis, QObject* parent);
200};
201
202class SCORE_LIB_PROCESS_EXPORT ControlInlet : public Inlet
203{
204 W_OBJECT(ControlInlet)
205
206 SCORE_SERIALIZE_FRIENDS
207public:
208 MODEL_METADATA_IMPL_HPP(ControlInlet)
209 ControlInlet() = delete;
210 ~ControlInlet() override;
211 ControlInlet(const ControlInlet&) = delete;
212 ControlInlet(const QString& name, Id<Process::Port> c, QObject* parent);
213 ControlInlet(Id<Process::Port> c, QObject* parent);
214
215 ControlInlet(DataStream::Deserializer& vis, QObject* parent, bool skip_this = false);
216 ControlInlet(JSONObject::Deserializer& vis, QObject* parent, bool skip_this = false);
217 ControlInlet(DataStream::Deserializer&& vis, QObject* parent, bool skip_this = false);
218 ControlInlet(JSONObject::Deserializer&& vis, QObject* parent, bool skip_this = false);
219
220 VIRTUAL_CONSTEXPR PortType type() const noexcept override
221 {
222 return Process::PortType::Message;
223 }
224
225 const ossia::value& value() const noexcept { return m_value; }
226 const ossia::value& init() const noexcept { return m_init; }
227 const State::Domain& domain() const noexcept { return m_domain; }
228
229 QByteArray saveData() const noexcept override;
230 void loadData(const QByteArray& arr) noexcept override;
231
232public:
233 void valueChanged(const ossia::value& v)
234 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, valueChanged, v)
235 void initChanged(const ossia::value& v)
236 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, initChanged, v)
237 void executionValueChanged(const ossia::value& v)
238 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, executionValueChanged, v)
239 void domainChanged(const State::Domain& d)
240 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, domainChanged, d)
241
242public:
243 void setValue(const ossia::value& value);
244 W_SLOT(setValue)
245 void setInit(const ossia::value& value);
246 W_SLOT(setInit)
247
248 inline void setExecutionValue(const ossia::value& value)
249 {
250 executionValueChanged(value);
251 }
252
253 void setDomain(const State::Domain& d)
254 {
255 if(m_domain != d)
256 {
257 m_domain = d;
258 domainChanged(d);
259 }
260 }
261 W_SLOT(setDomain)
262
263 PROPERTY(State::Domain, domain W_READ domain W_WRITE setDomain W_NOTIFY domainChanged)
264 PROPERTY(ossia::value, value W_READ value W_WRITE setValue W_NOTIFY valueChanged)
265 PROPERTY(ossia::value, init W_READ init W_WRITE setInit W_NOTIFY initChanged)
266private:
267 ossia::value m_value;
268 ossia::value m_init;
269 State::Domain m_domain;
270};
271
272class SCORE_LIB_PROCESS_EXPORT Outlet : public Port
273{
274 W_OBJECT(Outlet)
275
276 SCORE_SERIALIZE_FRIENDS
277public:
278 using score_base_type = Outlet;
279 MODEL_METADATA_IMPL_HPP(Outlet)
280
281 ~Outlet() override;
282 virtual void setupExecution(ossia::outlet&) const noexcept;
283 virtual void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept;
284 virtual void mapExecution(
285 ossia::outlet&,
286 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept;
287
288protected:
289 Outlet() = delete;
290 Outlet(const Outlet&) = delete;
291 Outlet(Id<Process::Port> c, QObject* parent);
292
293 Outlet(DataStream::Deserializer& vis, QObject* parent);
294 Outlet(JSONObject::Deserializer& vis, QObject* parent);
295 Outlet(DataStream::Deserializer&& vis, QObject* parent);
296 Outlet(JSONObject::Deserializer&& vis, QObject* parent);
297};
298
299class SCORE_LIB_PROCESS_EXPORT AudioInlet : public Inlet
300{
301 W_OBJECT(AudioInlet)
302
303 SCORE_SERIALIZE_FRIENDS
304public:
305 MODEL_METADATA_IMPL_HPP(AudioInlet)
306 AudioInlet() = delete;
307 ~AudioInlet() override;
308 AudioInlet(const AudioInlet&) = delete;
309 AudioInlet(Id<Process::Port> c, QObject* parent);
310
311 AudioInlet(DataStream::Deserializer& vis, QObject* parent);
312 AudioInlet(JSONObject::Deserializer& vis, QObject* parent);
313 AudioInlet(DataStream::Deserializer&& vis, QObject* parent);
314 AudioInlet(JSONObject::Deserializer&& vis, QObject* parent);
315
316 VIRTUAL_CONSTEXPR PortType type() const noexcept override
317 {
318 return Process::PortType::Audio;
319 }
320};
321
322class SCORE_LIB_PROCESS_EXPORT AudioOutlet : public Outlet
323{
324 W_OBJECT(AudioOutlet)
325
326 SCORE_SERIALIZE_FRIENDS
327public:
328 MODEL_METADATA_IMPL_HPP(AudioOutlet)
329 AudioOutlet() = delete;
330 ~AudioOutlet() override;
331 AudioOutlet(const AudioOutlet&) = delete;
332 AudioOutlet(Id<Process::Port> c, QObject* parent);
333
334 AudioOutlet(DataStream::Deserializer& vis, QObject* parent);
335 AudioOutlet(JSONObject::Deserializer& vis, QObject* parent);
336 AudioOutlet(DataStream::Deserializer&& vis, QObject* parent);
337 AudioOutlet(JSONObject::Deserializer&& vis, QObject* parent);
338
339 VIRTUAL_CONSTEXPR PortType type() const noexcept override
340 {
341 return Process::PortType::Audio;
342 }
343
344 void forChildInlets(const smallfun::function<void(Inlet&)>&) const noexcept override;
345 void mapExecution(
346 ossia::outlet&,
347 const smallfun::function<void(Inlet&, ossia::inlet&)>&) const noexcept override;
348
349 QByteArray saveData() const noexcept override;
350 void loadData(const QByteArray& arr) noexcept override;
351
352 bool propagate() const;
353 void setPropagate(bool propagate);
354 void propagateChanged(bool propagate)
355 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, propagateChanged, propagate)
356
357 double gain() const;
358 void setGain(double g);
359 void gainChanged(double g) E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, gainChanged, g)
360
361 pan_weight pan() const;
362 void setPan(pan_weight g);
363 void panChanged(pan_weight g) E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, panChanged, g)
364
365 std::unique_ptr<Process::ControlInlet> gainInlet;
366 std::unique_ptr<Process::ControlInlet> panInlet;
367
368 PROPERTY(
369 bool, propagate W_READ propagate W_WRITE setPropagate W_NOTIFY propagateChanged)
370 PROPERTY(double, gain W_READ gain W_WRITE setGain W_NOTIFY gainChanged)
371 PROPERTY(pan_weight, pan W_READ pan W_WRITE setPan W_NOTIFY panChanged)
372private:
373 double m_gain{};
374 pan_weight m_pan;
375 bool m_propagate{false};
376};
377
378class SCORE_LIB_PROCESS_EXPORT MidiInlet : public Inlet
379{
380 W_OBJECT(MidiInlet)
381
382 SCORE_SERIALIZE_FRIENDS
383public:
384 MODEL_METADATA_IMPL_HPP(MidiInlet)
385 MidiInlet() = delete;
386 ~MidiInlet() override;
387 MidiInlet(const MidiInlet&) = delete;
388 MidiInlet(Id<Process::Port> c, QObject* parent);
389
390 MidiInlet(DataStream::Deserializer& vis, QObject* parent);
391 MidiInlet(JSONObject::Deserializer& vis, QObject* parent);
392 MidiInlet(DataStream::Deserializer&& vis, QObject* parent);
393 MidiInlet(JSONObject::Deserializer&& vis, QObject* parent);
394
395 VIRTUAL_CONSTEXPR PortType type() const noexcept override
396 {
397 return Process::PortType::Midi;
398 }
399};
400
401class SCORE_LIB_PROCESS_EXPORT MidiOutlet : public Outlet
402{
403 W_OBJECT(MidiOutlet)
404
405 SCORE_SERIALIZE_FRIENDS
406public:
407 MODEL_METADATA_IMPL_HPP(MidiOutlet)
408 MidiOutlet() = delete;
409 ~MidiOutlet() override;
410 MidiOutlet(const MidiOutlet&) = delete;
411 MidiOutlet(Id<Process::Port> c, QObject* parent);
412
413 MidiOutlet(DataStream::Deserializer& vis, QObject* parent);
414 MidiOutlet(JSONObject::Deserializer& vis, QObject* parent);
415 MidiOutlet(DataStream::Deserializer&& vis, QObject* parent);
416 MidiOutlet(JSONObject::Deserializer&& vis, QObject* parent);
417
418 VIRTUAL_CONSTEXPR PortType type() const noexcept override
419 {
420 return Process::PortType::Midi;
421 }
422};
423
424class SCORE_LIB_PROCESS_EXPORT ControlOutlet : public Outlet
425{
426 W_OBJECT(ControlOutlet)
427
428 SCORE_SERIALIZE_FRIENDS
429public:
430 MODEL_METADATA_IMPL_HPP(ControlOutlet)
431 ControlOutlet() = delete;
432 ControlOutlet(const Outlet&) = delete;
433 ControlOutlet(const QString& name, Id<Process::Port> c, QObject* parent);
434 ControlOutlet(Id<Process::Port> c, QObject* parent);
435 ~ControlOutlet() override;
436
437 ControlOutlet(DataStream::Deserializer& vis, QObject* parent);
438 ControlOutlet(JSONObject::Deserializer& vis, QObject* parent);
439 ControlOutlet(DataStream::Deserializer&& vis, QObject* parent);
440 ControlOutlet(JSONObject::Deserializer&& vis, QObject* parent);
441
442 VIRTUAL_CONSTEXPR PortType type() const noexcept override
443 {
444 return Process::PortType::Message;
445 }
446
447 QByteArray saveData() const noexcept override;
448 void loadData(const QByteArray& arr) noexcept override;
449
450 const ossia::value& value() const { return m_value; }
451 const State::Domain& domain() const { return m_domain; }
452
453public:
454 void valueChanged(const ossia::value& v)
455 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, valueChanged, v)
456 void executionValueChanged(const ossia::value& v)
457 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, executionValueChanged, v)
458 void domainChanged(const State::Domain& d)
459 E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, domainChanged, d)
460
461public:
462 void setExecutionValue(const ossia::value& value) { executionValueChanged(value); }
463
464 void setValue(const ossia::value& value)
465 {
466 if(value != m_value)
467 {
468 m_value = value;
469 valueChanged(value);
470 }
471 }
472 W_SLOT(setValue)
473
474 void setDomain(const State::Domain& d)
475 {
476 if(m_domain != d)
477 {
478 m_domain = d;
479 domainChanged(d);
480 }
481 }
482 W_SLOT(setDomain)
483
484 PROPERTY(State::Domain, domain W_READ domain W_WRITE setDomain W_NOTIFY domainChanged)
485 PROPERTY(ossia::value, value W_READ value W_WRITE setValue W_NOTIFY valueChanged)
486private:
487 ossia::value m_value;
488 State::Domain m_domain;
489};
490
491class SCORE_LIB_PROCESS_EXPORT ValueInlet : public Inlet
492{
493 W_OBJECT(ValueInlet)
494
495 SCORE_SERIALIZE_FRIENDS
496public:
497 MODEL_METADATA_IMPL_HPP(ValueInlet)
498 ValueInlet() = delete;
499 ~ValueInlet() override;
500 ValueInlet(const ValueInlet&) = delete;
501 ValueInlet(Id<Process::Port> c, QObject* parent);
502
503 ValueInlet(DataStream::Deserializer& vis, QObject* parent);
504 ValueInlet(JSONObject::Deserializer& vis, QObject* parent);
505 ValueInlet(DataStream::Deserializer&& vis, QObject* parent);
506 ValueInlet(JSONObject::Deserializer&& vis, QObject* parent);
507
508 VIRTUAL_CONSTEXPR PortType type() const noexcept override
509 {
510 return Process::PortType::Message;
511 }
512};
513
514class SCORE_LIB_PROCESS_EXPORT ValueOutlet : public Outlet
515{
516 W_OBJECT(ValueOutlet)
517
518 SCORE_SERIALIZE_FRIENDS
519public:
520 MODEL_METADATA_IMPL_HPP(ValueOutlet)
521 ValueOutlet() = delete;
522 ~ValueOutlet() override;
523 ValueOutlet(const ValueOutlet&) = delete;
524 ValueOutlet(Id<Process::Port> c, QObject* parent);
525
526 ValueOutlet(DataStream::Deserializer& vis, QObject* parent);
527 ValueOutlet(JSONObject::Deserializer& vis, QObject* parent);
528 ValueOutlet(DataStream::Deserializer&& vis, QObject* parent);
529 ValueOutlet(JSONObject::Deserializer&& vis, QObject* parent);
530
531 VIRTUAL_CONSTEXPR PortType type() const noexcept override
532 {
533 return Process::PortType::Message;
534 }
535};
536
537SCORE_LIB_PROCESS_EXPORT
538std::unique_ptr<Inlet> make_value_inlet(const Id<Process::Port>& c, QObject* parent);
539SCORE_LIB_PROCESS_EXPORT
540std::unique_ptr<Outlet> make_value_outlet(const Id<Process::Port>& c, QObject* parent);
541
542SCORE_LIB_PROCESS_EXPORT
543std::unique_ptr<MidiInlet> make_midi_inlet(const Id<Process::Port>& c, QObject* parent);
544SCORE_LIB_PROCESS_EXPORT
545std::unique_ptr<MidiOutlet>
546make_midi_outlet(const Id<Process::Port>& c, QObject* parent);
547
548SCORE_LIB_PROCESS_EXPORT
549std::unique_ptr<AudioInlet>
550make_audio_inlet(const Id<Process::Port>& c, QObject* parent);
551SCORE_LIB_PROCESS_EXPORT
552std::unique_ptr<AudioOutlet>
553make_audio_outlet(const Id<Process::Port>& c, QObject* parent);
554
555}
556
557DEFAULT_MODEL_METADATA(Process::Port, "Port")
558
559W_REGISTER_ARGTYPE(Id<Process::Port>)
560W_REGISTER_ARGTYPE(Process::Port)
561
562// Q_DECLARE_METATYPE(Process::pan_weight)
563W_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:300
Definition Port.hpp:323
Definition Cable.hpp:38
Definition Port.hpp:203
Definition Port.hpp:425
Definition Port.hpp:177
Definition Port.hpp:379
Definition Port.hpp:402
Definition Port.hpp:273
Definition Port.hpp:102
Definition Port.hpp:492
Definition Port.hpp:515
The Selectable class.
Definition Selectable.hpp:14
The id_base_t class.
Definition Identifier.hpp:57
Generic serialization method for abstract classes.
Definition SerializableInterface.hpp:21
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1324
Definition AddressSettings.hpp:131
Definition Port.hpp:90
Definition PortForward.hpp:31
Definition Address.hpp:108
Definition Domain.hpp:17