OSSIA
Open Scenario System for Interactive Application
port.hpp
1 #pragma once
2 #include <ossia/dataflow/audio_port.hpp>
3 #include <ossia/dataflow/dataflow_fwd.hpp>
4 #include <ossia/dataflow/geometry_port.hpp>
5 #include <ossia/dataflow/midi_port.hpp>
6 #include <ossia/dataflow/value_port.hpp>
8 #include <ossia/network/common/path.hpp>
9 
10 namespace ossia
11 {
12 struct OSSIA_EXPORT port
13 {
14  enum scope_t : uint8_t
15  {
16  none = 1 << 0,
17  local = 1 << 1,
18  global = 1 << 2,
19  both = local | global
20  };
21 
22  scope_t scope{scope_t::both};
23 
24 protected:
25  port() = default;
26  port(const port&) = delete;
27  port(port&&) = delete;
28  port& operator=(const port&) = delete;
29  port& operator=(port&&) = delete;
30 };
31 
32 struct value_inlet;
33 struct OSSIA_EXPORT inlet : public port
34 {
35 protected:
36  inlet() noexcept = default;
37 
38  inlet(destination_t dest) noexcept
39  : address{std::move(dest)}
40  {
41  }
42 
43  inlet(ossia::net::parameter_base& addr) noexcept
44  : address{&addr}
45  {
46  }
47 
48  inlet(graph_edge& edge) noexcept { sources.push_back(&edge); }
49 
50 public:
51  virtual ~inlet();
52 
53  void connect(graph_edge* e) noexcept
54  {
55  auto it = ossia::find(sources, e);
56  if(it == sources.end())
57  sources.push_back(e);
58  }
59 
60  void disconnect(graph_edge* e) noexcept { ossia::remove_erase(sources, e); }
61 
62  [[nodiscard]] virtual std::size_t which() const noexcept = 0;
63 
64  template <typename T>
65  T* target() noexcept;
66  template <typename T>
67  const T* target() const noexcept;
68  template <typename T>
69  T& cast() noexcept;
70  template <typename T>
71  const T& cast() const noexcept;
72  template <typename T>
73  auto visit(const T& t);
74  template <typename T>
75  auto visit(const T& t) const;
76 
77  auto& cables() noexcept { return sources; }
78  [[nodiscard]] auto& cables() const noexcept { return sources; }
79 
80  virtual void pre_process();
81  virtual void post_process();
82 
83  destination_t address;
84  ossia::small_vector<graph_edge*, 2> sources;
85  ossia::small_vector<value_inlet*, 2> child_inlets;
86 
87  friend struct audio_inlet;
88  friend struct value_inlet;
89  friend struct midi_inlet;
90 };
91 
92 struct OSSIA_EXPORT outlet : public port
93 {
94 protected:
95  outlet() noexcept = default;
96  outlet(destination_t dest) noexcept
97  : address{std::move(dest)}
98  {
99  }
100 
101  outlet(ossia::net::parameter_base& addr) noexcept
102  : address{&addr}
103  {
104  }
105 
106  outlet(graph_edge& edge) noexcept { targets.push_back(&edge); }
107 
108 public:
109  virtual ~outlet();
110 
111  void connect(graph_edge* e) noexcept
112  {
113  auto it = ossia::find(targets, e);
114  if(it == targets.end())
115  targets.push_back(e);
116  }
117 
118  void disconnect(graph_edge* e) noexcept { ossia::remove_erase(targets, e); }
119 
120  void write(execution_state& e);
121 
122  [[nodiscard]] virtual std::size_t which() const noexcept = 0;
123 
124  template <typename T>
125  T* target() noexcept;
126  template <typename T>
127  const T* target() const noexcept;
128  template <typename T>
129  T& cast() noexcept;
130  template <typename T>
131  const T& cast() const noexcept;
132  template <typename T>
133  auto visit(const T& t);
134  template <typename T>
135  auto visit(const T& t) const;
136 
137  virtual void pre_process();
138  virtual void post_process();
139 
140  auto& cables() noexcept { return targets; }
141  [[nodiscard]] auto& cables() const noexcept { return targets; }
142 
143  destination_t address;
144  ossia::small_vector<graph_edge*, 2> targets;
145  ossia::small_vector<value_inlet*, 2> child_inlets;
146 
147  friend struct audio_outlet;
148  friend struct value_outlet;
149  friend struct midi_outlet;
150 };
151 
152 struct OSSIA_EXPORT audio_inlet : public ossia::inlet
153 {
154  audio_inlet() noexcept = default;
155 
156  audio_inlet(destination_t dest) noexcept
157  : inlet{std::move(dest)}
158  {
159  }
160 
161  audio_inlet(ossia::net::parameter_base& addr) noexcept
162  : inlet{&addr}
163  {
164  }
165 
166  audio_inlet(graph_edge& edge) noexcept { sources.push_back(&edge); }
167 
168  ~audio_inlet();
169 
170  const ossia::audio_port& operator*() const noexcept { return data; }
171  const ossia::audio_port* operator->() const noexcept { return &data; }
172  ossia::audio_port& operator*() noexcept { return data; }
173  ossia::audio_port* operator->() noexcept { return &data; }
174 
175  [[nodiscard]] std::size_t which() const noexcept final override
176  {
177  return audio_port::which;
178  }
179 
180  ossia::audio_port data;
181 };
182 
183 struct OSSIA_EXPORT midi_inlet : public ossia::inlet
184 {
185  midi_inlet() noexcept = default;
186 
187  midi_inlet(destination_t dest) noexcept
188  : inlet{std::move(dest)}
189  {
190  }
191 
192  midi_inlet(ossia::net::parameter_base& addr) noexcept
193  : inlet{&addr}
194  {
195  }
196 
197  midi_inlet(graph_edge& edge) noexcept { sources.push_back(&edge); }
198 
199  ~midi_inlet();
200 
201  const ossia::midi_port& operator*() const noexcept { return data; }
202  const ossia::midi_port* operator->() const noexcept { return &data; }
203  ossia::midi_port& operator*() noexcept { return data; }
204  ossia::midi_port* operator->() noexcept { return &data; }
205 
206  [[nodiscard]] std::size_t which() const noexcept final override
207  {
208  return midi_port::which;
209  }
210 
211  ossia::midi_port data;
212 };
213 
214 struct OSSIA_EXPORT value_inlet : public ossia::inlet
215 {
216  value_inlet() noexcept = default;
217 
218  value_inlet(destination_t dest) noexcept
219  : inlet{std::move(dest)}
220  {
221  }
222 
223  value_inlet(ossia::net::parameter_base& addr) noexcept
224  : inlet{&addr}
225  {
226  }
227 
228  value_inlet(graph_edge& edge) noexcept { sources.push_back(&edge); }
229 
230  ~value_inlet();
231 
232  const ossia::value_port& operator*() const noexcept { return data; }
233  const ossia::value_port* operator->() const noexcept { return &data; }
234  ossia::value_port& operator*() noexcept { return data; }
235  ossia::value_port* operator->() noexcept { return &data; }
236 
237  [[nodiscard]] std::size_t which() const noexcept final override
238  {
239  return value_port::which;
240  }
241 
242  ossia::value_port data;
243 };
244 
245 struct audio_outlet;
246 
247 OSSIA_EXPORT
248 void process_audio_out_mono(ossia::audio_outlet& audio_out);
249 
250 OSSIA_EXPORT
251 void process_audio_out_general(ossia::audio_outlet& audio_out);
252 
253 OSSIA_EXPORT
254 void process_audio_out_mono(ossia::audio_port& i, ossia::audio_outlet& audio_out);
255 
256 OSSIA_EXPORT
257 void process_audio_out_general(ossia::audio_port& i, ossia::audio_outlet& audio_out);
258 
259 struct OSSIA_EXPORT audio_outlet : public ossia::outlet
260 {
261  audio_outlet() noexcept { init(); }
262 
263  audio_outlet(destination_t dest) noexcept
264  : outlet{std::move(dest)}
265  {
266  init();
267  }
268 
269  audio_outlet(ossia::net::parameter_base& addr) noexcept
270  : outlet{&addr}
271  {
272  init();
273  }
274 
275  audio_outlet(graph_edge& edge) noexcept
276  {
277  targets.push_back(&edge);
278  init();
279  }
280 
281  ~audio_outlet();
282 
283  const ossia::audio_port& operator*() const noexcept { return data; }
284  const ossia::audio_port* operator->() const noexcept { return &data; }
285  ossia::audio_port& operator*() noexcept { return data; }
286  ossia::audio_port* operator->() noexcept { return &data; }
287 
288  [[nodiscard]] std::size_t which() const noexcept final override
289  {
290  return audio_port::which;
291  }
292 
293  void post_process() override;
294 
295  double gain{1.};
296  pan_weight pan{1., 1.};
297 
298  ossia::value_inlet gain_inlet;
299  ossia::value_inlet pan_inlet;
300 
301  ossia::audio_port data;
302  bool has_gain{};
303 
304 private:
305  void init() noexcept
306  {
307  this->child_inlets.resize(2);
308  this->child_inlets[0] = &gain_inlet;
309  this->child_inlets[1] = &pan_inlet;
310  }
311 };
312 
313 #if BOOST_VERSION >= 107200
314 static_assert(noexcept(pan_weight{}));
315 static_assert(noexcept(value_inlet{}));
316 static_assert(noexcept(std::allocator<ossia::outlet>{}));
317 static_assert(noexcept(audio_outlet{}));
318 #endif
319 
320 struct OSSIA_EXPORT midi_outlet : public ossia::outlet
321 {
322  midi_outlet() noexcept = default;
323 
324  midi_outlet(destination_t dest) noexcept
325  : outlet{std::move(dest)}
326  {
327  }
328 
329  midi_outlet(ossia::net::parameter_base& addr) noexcept
330  : outlet{&addr}
331  {
332  }
333 
334  midi_outlet(graph_edge& edge) noexcept { targets.push_back(&edge); }
335  ~midi_outlet();
336 
337  const ossia::midi_port& operator*() const noexcept { return data; }
338  const ossia::midi_port* operator->() const noexcept { return &data; }
339  ossia::midi_port& operator*() noexcept { return data; }
340  ossia::midi_port* operator->() noexcept { return &data; }
341 
342  [[nodiscard]] std::size_t which() const noexcept final override
343  {
344  return midi_port::which;
345  }
346 
347  ossia::midi_port data;
348 };
349 
350 struct OSSIA_EXPORT value_outlet : public ossia::outlet
351 {
352  value_outlet() noexcept = default;
353 
354  value_outlet(destination_t dest) noexcept
355  : outlet{std::move(dest)}
356  {
357  }
358 
359  value_outlet(ossia::net::parameter_base& addr) noexcept
360  : outlet{&addr}
361  {
362  }
363 
364  value_outlet(graph_edge& edge) noexcept { targets.push_back(&edge); }
365  ~value_outlet();
366 
367  const ossia::value_port& operator*() const noexcept { return data; }
368  const ossia::value_port* operator->() const noexcept { return &data; }
369  ossia::value_port& operator*() noexcept { return data; }
370  ossia::value_port* operator->() noexcept { return &data; }
371 
372  [[nodiscard]] std::size_t which() const noexcept final override
373  {
374  return value_port::which;
375  }
376 
377  ossia::value_port data;
378 };
379 
380 struct texture_port
381 {
382  static const constexpr int which = 3;
383 };
384 
385 struct OSSIA_EXPORT texture_inlet : public ossia::inlet
386 {
387  texture_inlet() noexcept = default;
388 
389  texture_inlet(destination_t dest) noexcept
390  : inlet{std::move(dest)}
391  {
392  }
393 
394  texture_inlet(ossia::net::parameter_base& addr) noexcept
395  : inlet{&addr}
396  {
397  }
398 
399  texture_inlet(graph_edge& edge) noexcept { sources.push_back(&edge); }
400 
401  ~texture_inlet();
402 
403  [[nodiscard]] std::size_t which() const noexcept final override
404  {
405  return texture_port::which;
406  }
407 };
408 
409 struct OSSIA_EXPORT texture_outlet : public ossia::outlet
410 {
411  texture_outlet() noexcept = default;
412 
413  texture_outlet(destination_t dest) noexcept
414  : outlet{std::move(dest)}
415  {
416  }
417 
418  texture_outlet(ossia::net::parameter_base& addr) noexcept
419  : outlet{&addr}
420  {
421  }
422 
423  texture_outlet(graph_edge& edge) noexcept { targets.push_back(&edge); }
424  ~texture_outlet();
425 
426  [[nodiscard]] std::size_t which() const noexcept final override
427  {
428  return texture_port::which;
429  }
430 };
431 
432 struct OSSIA_EXPORT geometry_inlet : public ossia::inlet
433 {
434  geometry_inlet() noexcept = default;
435 
436  geometry_inlet(destination_t dest) noexcept
437  : inlet{std::move(dest)}
438  {
439  }
440 
441  geometry_inlet(ossia::net::parameter_base& addr) noexcept
442  : inlet{&addr}
443  {
444  }
445 
446  geometry_inlet(graph_edge& edge) noexcept { sources.push_back(&edge); }
447 
448  ~geometry_inlet();
449 
450  [[nodiscard]] std::size_t which() const noexcept final override
451  {
452  return geometry_port::which;
453  }
454 
455  geometry_port data;
456 };
457 
458 struct OSSIA_EXPORT geometry_outlet : public ossia::outlet
459 {
460  geometry_outlet() noexcept = default;
461 
462  geometry_outlet(destination_t dest) noexcept
463  : outlet{std::move(dest)}
464  {
465  }
466 
467  geometry_outlet(ossia::net::parameter_base& addr) noexcept
468  : outlet{&addr}
469  {
470  }
471 
472  geometry_outlet(graph_edge& edge) noexcept { targets.push_back(&edge); }
473  ~geometry_outlet();
474 
475  [[nodiscard]] std::size_t which() const noexcept final override
476  {
477  return geometry_port::which;
478  }
479 
480  geometry_port data;
481 };
482 
483 template <typename T>
484 inline T* inlet::target() noexcept
485 {
486  if constexpr(std::is_same_v<T, audio_port>)
487  {
488  if(which() == 0)
489  {
490  return &static_cast<audio_inlet*>(this)->data;
491  }
492  else
493  {
494  return (audio_port*)nullptr;
495  }
496  }
497  else if constexpr(std::is_same_v<T, midi_port>)
498  {
499  if(which() == 1)
500  {
501  return &static_cast<midi_inlet*>(this)->data;
502  }
503  else
504  {
505  return (midi_port*)nullptr;
506  }
507  }
508  else if constexpr(std::is_same_v<T, value_port>)
509  {
510  if(which() == 2)
511  {
512  return &static_cast<value_inlet*>(this)->data;
513  }
514  else
515  {
516  return (value_port*)nullptr;
517  }
518  }
519  else if constexpr(std::is_same_v<T, texture_inlet>)
520  {
521  if(which() == 3)
522  {
523  return static_cast<texture_inlet*>(this);
524  }
525  else
526  {
527  return (texture_inlet*)nullptr;
528  }
529  }
530  else if constexpr(std::is_same_v<T, geometry_port>)
531  {
532  if(which() == 4)
533  {
534  return static_cast<geometry_inlet*>(this)->data;
535  }
536  else
537  {
538  return (geometry_port*)nullptr;
539  }
540  }
541  else
542  {
543  static_assert(std::is_same_v<T, struct _>, "Invalid type requested");
544  }
545 }
546 
547 template <typename T>
548 inline T* outlet::target() noexcept
549 {
550  if constexpr(std::is_same_v<T, audio_port>)
551  {
552  if(which() == 0)
553  {
554  return &static_cast<audio_outlet*>(this)->data;
555  }
556  else
557  {
558  return (audio_port*)nullptr;
559  }
560  }
561  else if constexpr(std::is_same_v<T, midi_port>)
562  {
563  if(which() == 1)
564  {
565  return &static_cast<midi_outlet*>(this)->data;
566  }
567  else
568  {
569  return (midi_port*)nullptr;
570  }
571  }
572  else if constexpr(std::is_same_v<T, value_port>)
573  {
574  if(which() == 2)
575  {
576  return &static_cast<value_outlet*>(this)->data;
577  }
578  else
579  {
580  return (value_port*)nullptr;
581  }
582  }
583  else if constexpr(std::is_same_v<T, texture_outlet>)
584  {
585  if(which() == 3)
586  {
587  return static_cast<texture_outlet*>(this);
588  }
589  else
590  {
591  return (texture_outlet*)nullptr;
592  }
593  }
594  else if constexpr(std::is_same_v<T, geometry_port>)
595  {
596  if(which() == 4)
597  {
598  return static_cast<geometry_outlet*>(this)->data;
599  }
600  else
601  {
602  return (geometry_port*)nullptr;
603  }
604  }
605  else
606  {
607  static_assert(std::is_same_v<T, struct _>, "Invalid type requested");
608  }
609 }
610 template <typename T>
611 inline const T* inlet::target() const noexcept
612 {
613  if constexpr(std::is_same_v<T, audio_port>)
614  {
615  if(which() == 0)
616  {
617  return &static_cast<const audio_inlet*>(this)->data;
618  }
619  else
620  {
621  return (const audio_port*)nullptr;
622  }
623  }
624  else if constexpr(std::is_same_v<T, midi_port>)
625  {
626  if(which() == 1)
627  {
628  return &static_cast<const midi_inlet*>(this)->data;
629  }
630  else
631  {
632  return (const midi_port*)nullptr;
633  }
634  }
635  else if constexpr(std::is_same_v<T, value_port>)
636  {
637  if(which() == 2)
638  {
639  return &static_cast<const value_inlet*>(this)->data;
640  }
641  else
642  {
643  return (const value_port*)nullptr;
644  }
645  }
646  else if constexpr(std::is_same_v<T, texture_inlet>)
647  {
648  if(which() == 3)
649  {
650  return static_cast<const texture_inlet*>(this);
651  }
652  else
653  {
654  return (const texture_inlet*)nullptr;
655  }
656  }
657  else if constexpr(std::is_same_v<T, geometry_port>)
658  {
659  if(which() == 4)
660  {
661  return &static_cast<const geometry_inlet*>(this)->data;
662  }
663  else
664  {
665  return (const geometry_port*)nullptr;
666  }
667  }
668  else
669  {
670  static_assert(std::is_same_v<T, struct _>, "Invalid type requested");
671  }
672 }
673 
674 template <typename T>
675 inline const T* outlet::target() const noexcept
676 {
677  if constexpr(std::is_same_v<T, audio_port>)
678  {
679  if(which() == 0)
680  {
681  return &static_cast<const audio_outlet*>(this)->data;
682  }
683  else
684  {
685  return (const audio_port*)nullptr;
686  }
687  }
688  else if constexpr(std::is_same_v<T, midi_port>)
689  {
690  if(which() == 1)
691  {
692  return &static_cast<const midi_outlet*>(this)->data;
693  }
694  else
695  {
696  return (const midi_port*)nullptr;
697  }
698  }
699  else if constexpr(std::is_same_v<T, value_port>)
700  {
701  if(which() == 2)
702  {
703  return &static_cast<const value_outlet*>(this)->data;
704  }
705  else
706  {
707  return (const value_port*)nullptr;
708  }
709  }
710  else if constexpr(std::is_same_v<T, texture_outlet>)
711  {
712  if(which() == 3)
713  {
714  return static_cast<const texture_outlet*>(this);
715  }
716  else
717  {
718  return (const texture_outlet*)nullptr;
719  }
720  }
721  else if constexpr(std::is_same_v<T, geometry_port>)
722  {
723  if(which() == 4)
724  {
725  return &static_cast<const geometry_outlet*>(this)->data;
726  }
727  else
728  {
729  return (const geometry_port*)nullptr;
730  }
731  }
732  else
733  {
734  static_assert(std::is_same_v<T, struct _>, "Invalid type requested");
735  }
736 }
737 
738 template <typename T>
739 inline T& inlet::cast() noexcept
740 {
741  if constexpr(std::is_same_v<T, audio_port>)
742  {
743  return static_cast<audio_inlet*>(this)->data;
744  }
745  else if constexpr(std::is_same_v<T, midi_port>)
746  {
747  return static_cast<midi_inlet*>(this)->data;
748  }
749  else if constexpr(std::is_same_v<T, value_port>)
750  {
751  return static_cast<value_inlet*>(this)->data;
752  }
753  else if constexpr(std::is_same_v<T, texture_inlet>)
754  {
755  return static_cast<texture_inlet&>(*this);
756  }
757  else if constexpr(std::is_same_v<T, geometry_port>)
758  {
759  return static_cast<geometry_inlet*>(this)->data;
760  }
761  else
762  {
763  static_assert(std::is_same_v<T, struct _>, "Invalid type requested");
764  }
765 }
766 
767 template <typename T>
768 inline T& outlet::cast() noexcept
769 {
770  if constexpr(std::is_same_v<T, audio_port>)
771  {
772  return static_cast<audio_outlet*>(this)->data;
773  }
774  else if constexpr(std::is_same_v<T, midi_port>)
775  {
776  return static_cast<midi_outlet*>(this)->data;
777  }
778  else if constexpr(std::is_same_v<T, value_port>)
779  {
780  return static_cast<value_outlet*>(this)->data;
781  }
782  else if constexpr(std::is_same_v<T, texture_outlet>)
783  {
784  return static_cast<texture_outlet&>(*this);
785  }
786  else if constexpr(std::is_same_v<T, geometry_port>)
787  {
788  return static_cast<geometry_outlet*>(this)->data;
789  }
790  else
791  {
792  static_assert(std::is_same_v<T, struct _>, "Invalid type requested");
793  }
794 }
795 template <typename T>
796 inline const T& inlet::cast() const noexcept
797 {
798  if constexpr(std::is_same_v<T, audio_port>)
799  {
800  return static_cast<const audio_inlet*>(this)->data;
801  }
802  else if constexpr(std::is_same_v<T, midi_port>)
803  {
804  return static_cast<const midi_inlet*>(this)->data;
805  }
806  else if constexpr(std::is_same_v<T, value_port>)
807  {
808  return static_cast<const value_inlet*>(this)->data;
809  }
810  else if constexpr(std::is_same_v<T, texture_inlet>)
811  {
812  return static_cast<const texture_inlet&>(*this);
813  }
814  else if constexpr(std::is_same_v<T, geometry_port>)
815  {
816  return static_cast<const geometry_inlet*>(this)->data;
817  }
818  else
819  {
820  static_assert(std::is_same_v<T, struct _>, "Invalid type requested");
821  }
822 }
823 
824 template <typename T>
825 inline const T& outlet::cast() const noexcept
826 {
827  if constexpr(std::is_same_v<T, audio_port>)
828  {
829  return static_cast<const audio_outlet*>(this)->data;
830  }
831  else if constexpr(std::is_same_v<T, midi_port>)
832  {
833  return static_cast<const midi_outlet*>(this)->data;
834  }
835  else if constexpr(std::is_same_v<T, value_port>)
836  {
837  return static_cast<const value_outlet*>(this)->data;
838  }
839  else if constexpr(std::is_same_v<T, texture_outlet>)
840  {
841  return static_cast<const texture_outlet&>(*this);
842  }
843  else if constexpr(std::is_same_v<T, geometry_port>)
844  {
845  return static_cast<const geometry_outlet*>(this)->data;
846  }
847  else
848  {
849  static_assert(std::is_same_v<T, struct _>, "Invalid type requested");
850  }
851 }
852 
853 template <typename T>
854 inline auto inlet::visit(const T& t)
855 {
856  switch(which())
857  {
858  case 0:
859  return t(static_cast<audio_inlet*>(this)->data);
860  case 1:
861  return t(static_cast<midi_inlet*>(this)->data);
862  case 2:
863  return t(static_cast<value_inlet*>(this)->data);
864  // case 3: return t(static_cast<texture_inlet&>(*this));
865  case 4:
866  return t(static_cast<geometry_inlet*>(this)->data);
867  }
868 
869  if constexpr(std::is_invocable_v<T>)
870  return t();
871 }
872 
873 template <typename T>
874 inline auto outlet::visit(const T& t)
875 {
876  switch(which())
877  {
878  case 0:
879  return t(static_cast<audio_outlet*>(this)->data);
880  case 1:
881  return t(static_cast<midi_outlet*>(this)->data);
882  case 2:
883  return t(static_cast<value_outlet*>(this)->data);
884  // case 3: return t(static_cast<texture_outlet&>(*this));
885  case 4:
886  return t(static_cast<geometry_outlet*>(this)->data);
887  }
888 
889  if constexpr(std::is_invocable_v<T>)
890  return t();
891 }
892 template <typename T>
893 inline auto inlet::visit(const T& t) const
894 {
895  switch(which())
896  {
897  case 0:
898  return t(static_cast<const audio_inlet*>(this)->data);
899  case 1:
900  return t(static_cast<const midi_inlet*>(this)->data);
901  case 2:
902  return t(static_cast<const value_inlet*>(this)->data);
903  // case 3: return t(static_cast<const texture_inlet&>(*this));
904  case 4:
905  return t(static_cast<const geometry_inlet*>(this)->data);
906  }
907 
908  if constexpr(std::is_invocable_v<T>)
909  return t();
910 }
911 template <typename T>
912 inline auto outlet::visit(const T& t) const
913 {
914  switch(which())
915  {
916  case 0:
917  return t(static_cast<const audio_outlet*>(this)->data);
918  case 1:
919  return t(static_cast<const midi_outlet*>(this)->data);
920  case 2:
921  return t(static_cast<const value_outlet*>(this)->data);
922  // case 3: return t(static_cast<const texture_outlet&>(*this));
923  case 4:
924  return t(static_cast<const geometry_outlet*>(this)->data);
925  }
926 
927  if constexpr(std::is_invocable_v<T>)
928  return t();
929 }
930 
931 }
The parameter_base class.
Definition: ossia/network/base/parameter.hpp:48
Definition: git_info.h:7