OSSIA
Open Scenario System for Interactive Application
pull_visitors.hpp
1 #pragma once
2 #include <ossia/dataflow/data_copy.hpp>
3 #include <ossia/dataflow/execution/execution_policy.hpp>
4 #include <ossia/dataflow/execution_state.hpp>
5 #include <ossia/protocols/midi/detail/midi_impl.hpp>
6 #include <ossia/protocols/midi/midi_node.hpp>
7 
8 namespace ossia
9 {
10 
11 struct local_pull_visitor
12 {
13  local_state_execution_policy& st;
15  bool operator()(value_port& val) const
16  {
17  OSSIA_EXEC_STATE_LOCK_READ(st);
18  auto it = st.m_valueState.find(addr);
19  if(it != st.m_valueState.end() && !it->second.empty())
20  {
21  copy_data{}(it->second, val);
22  return true;
23  }
24  return false;
25  }
26 
27  bool operator()(audio_port& val) const
28  {
29 #if defined(OSSIA_PROTOCOL_AUDIO)
30  OSSIA_EXEC_STATE_LOCK_READ(st);
31  auto it = st.m_audioState.find(static_cast<ossia::audio_parameter*>(addr));
32  if(it != st.m_audioState.end() && !it->second.empty())
33  {
34  copy_data{}(it->second, val);
35  return true;
36  }
37 #endif
38  return false;
39  }
40 
41  bool operator()(midi_port& val) const
42  {
43 #if defined(OSSIA_PROTOCOL_MIDI)
44  OSSIA_EXEC_STATE_LOCK_READ(st);
45  auto it = st.m_midiState.find(addr);
46  if(it != st.m_midiState.end() && !it->second.empty())
47  {
48  copy_data{}(it->second, val);
49  return true;
50  }
51 #endif
52  return false;
53  }
54 
55  [[noreturn]] bool operator()(geometry_port& val) const
56  {
57  assert(false);
58  return false;
59  }
60 
61  bool operator()() const { return false; }
62 };
63 
64 struct global_pull_visitor
65 {
66  ossia::execution_state& state;
67  const net::parameter_base& out;
68  void operator()(value_port& val) const
69  {
70  if(!val.is_event)
71  {
72  copy_data{}(out, val);
73  }
74  else
75  {
76  auto it = state.m_receivedValues.find(const_cast<net::parameter_base*>(&out));
77  if(it != state.m_receivedValues.end())
78  {
79  copy_data{}(*it->first, it->second, val);
80  }
81  }
82  }
83 
84  void operator()(audio_port& val) const
85  {
86 #if defined(OSSIA_PROTOCOL_AUDIO)
87 #if !defined(NDEBUG)
88  auto aa = dynamic_cast<const audio_parameter*>(&out);
89  assert(aa);
90 #else
91  auto aa = static_cast<const audio_parameter*>(&out);
92 #endif
93  aa->clone_value(val.get());
94 #endif
95  }
96 
97  void operator()(midi_port& val) const
98  {
99 #if defined(OSSIA_PROTOCOL_MIDI)
100  auto& node = out.get_node();
101  auto& dev = node.get_device();
102  auto& proto = dev.get_protocol();
103 
104 #if !defined(NDEBUG)
105  // TODO how to do without that dynamic_cast ?
106  // Can we *ensure* that the address of the midi_port is a midi one ?
107  auto midi = dynamic_cast<ossia::net::midi::midi_protocol*>(&proto);
108  assert(midi);
109 #else
110  auto midi = static_cast<ossia::net::midi::midi_protocol*>(&proto);
111 #endif
112 
113  auto it = state.m_receivedMidi.find(midi);
114  if(it != state.m_receivedMidi.end())
115  {
116  for(const libremidi::message& v : it->second.messages)
117  {
118  val.messages.push_back(v);
119  }
120  }
121 #endif
122  }
123 
124  [[noreturn]] void operator()(geometry_port& val) const { assert(false); }
125 
126  void operator()() const { }
127 };
128 
129 struct global_pull_node_visitor
130 {
131  ossia::execution_state& state;
132  const net::node_base& out;
133  void operator()(value_port& val) const { val.write_value(ossia::net::to_map(out), 0); }
134 
135  void operator()(audio_port& val) const
136  {
137  // TODO Nothing to do ?
138  }
139 
140  void operator()(midi_port& val) const
141  {
142 #if defined(OSSIA_PROTOCOL_MIDI)
143  auto& node = out;
144  auto& dev = node.get_device();
145  auto& proto = dev.get_protocol();
146 
147 #if !defined(NDEBUG)
148  // TODO how to do without that dynamic_cast ?
149  // Can we *ensure* that the address of the midi_port is a midi one ?
150  auto midi = dynamic_cast<ossia::net::midi::midi_protocol*>(&proto);
151  assert(midi);
152 #else
153  auto midi = static_cast<ossia::net::midi::midi_protocol*>(&proto);
154 #endif
155 
156  int channel = -1;
157  if(node.get_parent() == &dev.get_root_node())
158  {
159  // the node is a MIDI channel node
160  channel = static_cast<const ossia::net::midi::channel_node&>(node).channel;
161  }
162 
163  auto it = state.m_receivedMidi.find(midi);
164  if(it != state.m_receivedMidi.end())
165  {
166  if(channel == -1)
167  {
168  for(const libremidi::message& v : it->second.messages)
169  {
170  val.messages.push_back(v);
171  }
172  }
173  else
174  {
175  for(const libremidi::message& v : it->second.messages)
176  {
177  if(v.get_channel() == channel)
178  val.messages.push_back(v);
179  }
180  }
181  }
182 #endif
183  }
184 
185  [[noreturn]] void operator()(geometry_port& val) const { assert(false); }
186 
187  void operator()() const { }
188 };
189 
190 }
The parameter_base class.
Definition: ossia/network/base/parameter.hpp:48
Definition: git_info.h:7