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