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 
32 namespace ossia
33 {
34 struct inlet;
35 struct outlet;
36 }
37 namespace Process
38 {
39 class Port;
40 class Inlet;
41 class Outlet;
42 class ValueInlet;
43 class ValueOutlet;
44 class AudioInlet;
45 class AudioOutlet;
46 class MidiInlet;
47 class MidiOutlet;
48 class ControlInlet;
49 class ControlOutlet;
50 }
51 UUID_METADATA(
52  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::Inlet,
53  "8884228a-d197-4b0a-b6ca-d1fb15291559")
54 UUID_METADATA(
55  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::Outlet,
56  "34e2c5a7-18c4-4759-b6cc-46feaeee06e2")
57 UUID_METADATA(
58  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::ValueInlet,
59  "769dd38a-bfb3-4dc6-b52a-b6abb7afe2a3")
60 UUID_METADATA(
61  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::ValueOutlet,
62  "cff96158-cc72-46d7-99dc-b6038171375b")
63 UUID_METADATA(
64  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::MidiInlet,
65  "c18adc77-e0e0-4ddf-a46c-43cb0719a890")
66 UUID_METADATA(
67  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::MidiOutlet,
68  "d8a3ed3d-b9c2-46f2-bdb3-d282a48481c6")
69 UUID_METADATA(
70  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::AudioInlet,
71  "a1574bb0-cbd4-4c7d-9417-0c25cfd1187b")
72 UUID_METADATA(
73  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::AudioOutlet,
74  "a1d97535-18ac-444a-8417-0cbc1692d897")
75 UUID_METADATA(
76  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::ControlInlet,
77  "9a13fb32-269a-47bf-99a9-930188c1f19c")
78 UUID_METADATA(
79  SCORE_LIB_PROCESS_EXPORT, Process::Port, Process::ControlOutlet,
80  "3620ea94-5991-41cf-89b3-11f842cc39d0")
81 namespace Process
82 {
83 
84 // Used to know where to layout items for a given
85 // kind of port.
86 static constexpr const qreal default_margin = 5.;
87 static 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 
98 class Cable;
99 class SCORE_LIB_PROCESS_EXPORT Port
100  : public IdentifiedObject<Port>
101  , public score::SerializableInterface<Port>
102 {
103  W_OBJECT(Port)
104  SCORE_SERIALIZE_FRIENDS
105 public:
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 
128 public:
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 
157 protected:
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 
168 private:
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 
176 class SCORE_LIB_PROCESS_EXPORT Inlet : public Port
177 {
178  W_OBJECT(Inlet)
179 public:
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 
191 protected:
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 
202 class SCORE_LIB_PROCESS_EXPORT ControlInlet : public Inlet
203 {
204  W_OBJECT(ControlInlet)
205 
206  SCORE_SERIALIZE_FRIENDS
207 public:
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);
216  ControlInlet(JSONObject::Deserializer& vis, QObject* parent);
217  ControlInlet(DataStream::Deserializer&& vis, QObject* parent);
218  ControlInlet(JSONObject::Deserializer&& vis, QObject* parent);
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 
232 public:
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 
242 public:
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)
266 private:
267  ossia::value m_value;
268  ossia::value m_init;
269  State::Domain m_domain;
270 };
271 
272 class SCORE_LIB_PROCESS_EXPORT Outlet : public Port
273 {
274  W_OBJECT(Outlet)
275 
276  SCORE_SERIALIZE_FRIENDS
277 public:
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 
288 protected:
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 
299 class SCORE_LIB_PROCESS_EXPORT AudioInlet : public Inlet
300 {
301  W_OBJECT(AudioInlet)
302 
303  SCORE_SERIALIZE_FRIENDS
304 public:
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 
322 class SCORE_LIB_PROCESS_EXPORT AudioOutlet : public Outlet
323 {
324  W_OBJECT(AudioOutlet)
325 
326  SCORE_SERIALIZE_FRIENDS
327 public:
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)
372 private:
373  double m_gain{};
374  pan_weight m_pan;
375  bool m_propagate{false};
376 };
377 
378 class SCORE_LIB_PROCESS_EXPORT MidiInlet : public Inlet
379 {
380  W_OBJECT(MidiInlet)
381 
382  SCORE_SERIALIZE_FRIENDS
383 public:
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 
401 class SCORE_LIB_PROCESS_EXPORT MidiOutlet : public Outlet
402 {
403  W_OBJECT(MidiOutlet)
404 
405  SCORE_SERIALIZE_FRIENDS
406 public:
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 
424 class SCORE_LIB_PROCESS_EXPORT ControlOutlet : public Outlet
425 {
426  W_OBJECT(ControlOutlet)
427 
428  SCORE_SERIALIZE_FRIENDS
429 public:
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 
453 public:
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 
461 public:
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)
486 private:
487  ossia::value m_value;
488  State::Domain m_domain;
489 };
490 
491 class SCORE_LIB_PROCESS_EXPORT ValueInlet : public Inlet
492 {
493  W_OBJECT(ValueInlet)
494 
495  SCORE_SERIALIZE_FRIENDS
496 public:
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 
514 class SCORE_LIB_PROCESS_EXPORT ValueOutlet : public Outlet
515 {
516  W_OBJECT(ValueOutlet)
517 
518  SCORE_SERIALIZE_FRIENDS
519 public:
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 
537 SCORE_LIB_PROCESS_EXPORT
538 std::unique_ptr<Inlet> make_value_inlet(const Id<Process::Port>& c, QObject* parent);
539 SCORE_LIB_PROCESS_EXPORT
540 std::unique_ptr<Outlet> make_value_outlet(const Id<Process::Port>& c, QObject* parent);
541 
542 SCORE_LIB_PROCESS_EXPORT
543 std::unique_ptr<MidiInlet> make_midi_inlet(const Id<Process::Port>& c, QObject* parent);
544 SCORE_LIB_PROCESS_EXPORT
545 std::unique_ptr<MidiOutlet>
546 make_midi_outlet(const Id<Process::Port>& c, QObject* parent);
547 
548 SCORE_LIB_PROCESS_EXPORT
549 std::unique_ptr<AudioInlet>
550 make_audio_inlet(const Id<Process::Port>& c, QObject* parent);
551 SCORE_LIB_PROCESS_EXPORT
552 std::unique_ptr<AudioOutlet>
553 make_audio_outlet(const Id<Process::Port>& c, QObject* parent);
554 
555 }
556 
557 DEFAULT_MODEL_METADATA(Process::Port, "Port")
558 
559 W_REGISTER_ARGTYPE(Id<Process::Port>)
560 W_REGISTER_ARGTYPE(Process::Port)
561 
562 // Q_DECLARE_METATYPE(Process::pan_weight)
563 W_REGISTER_ARGTYPE(Process::pan_weight)
Definition: QmlObjects.hpp:406
Definition: QmlObjects.hpp:433
Definition: QmlObjects.hpp:114
Definition: DataStreamVisitor.hpp:202
The IdentifiedObject class.
Definition: IdentifiedObject.hpp:19
Definition: JSONVisitor.hpp:423
Definition: QmlObjects.hpp:464
Definition: QmlObjects.hpp:500
Definition: QmlObjects.hpp:51
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
Definition: QmlObjects.hpp:82
Definition: QmlObjects.hpp:376
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