OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
pull_visitors.hpp
1#pragma once
2#include <ossia/audio/audio_parameter.hpp>
3#include <ossia/dataflow/audio_lock.hpp>
4#include <ossia/dataflow/data_copy.hpp>
5#include <ossia/dataflow/execution/local_state_execution_policy.hpp>
6#include <ossia/dataflow/execution_state.hpp>
7#include <ossia/protocols/midi/detail/midi_impl.hpp>
8#include <ossia/protocols/midi/midi_node.hpp>
9
10namespace ossia
11{
12struct texture_port;
13struct geometry_port;
14struct local_pull_visitor
15{
16 local_state_execution_policy& st;
18 bool operator()(value_port& val) const
19 {
20 OSSIA_EXEC_STATE_LOCK_READ(st);
21 auto it = st.m_valueState.find(addr);
22 if(it != st.m_valueState.end() && !it->second.empty())
23 {
24 copy_data{}(it->second, val);
25 return true;
26 }
27 return false;
28 }
29
30 bool operator()(audio_port& val) const
31 {
32#if defined(OSSIA_PROTOCOL_AUDIO)
33 OSSIA_EXEC_STATE_LOCK_READ(st);
34 auto it = st.m_audioState.find(static_cast<ossia::audio_parameter*>(addr));
35 if(it != st.m_audioState.end() && !it->second.empty())
36 {
37 copy_data{}(it->second, val);
38 return true;
39 }
40#endif
41 return false;
42 }
43
44 bool operator()(midi_port& val) const
45 {
46#if defined(OSSIA_PROTOCOL_MIDI)
47 OSSIA_EXEC_STATE_LOCK_READ(st);
48 auto it = st.m_midiState.find(addr);
49 if(it != st.m_midiState.end() && !it->second.empty())
50 {
51 copy_data{}(it->second, val);
52 return true;
53 }
54#endif
55 return false;
56 }
57
58 [[noreturn]] bool operator()(texture_port& val) const = delete;
59 [[noreturn]] bool operator()(geometry_port& val) const = delete;
60
61 bool operator()() const { return false; }
62};
63
64struct 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 // An address whose device speaks no MIDI can still be bound to a port;
105 // register_port() leaves it unregistered.
106 auto midi = dynamic_cast<ossia::net::midi::midi_stream*>(&proto);
107 if(!midi)
108 return;
109
110 auto it = state.m_receivedMidi.find(midi);
111 if(it != state.m_receivedMidi.end())
112 {
113 for(const libremidi::ump& v : it->second.messages)
114 {
115 val.messages.push_back(v);
116 }
117 }
118#endif
119 }
120
121 [[noreturn]] void operator()(texture_port& val) const = delete;
122 [[noreturn]] void operator()(geometry_port& val) const = delete;
123
124 void operator()() const { }
125};
126
127struct global_pull_node_visitor
128{
129 ossia::execution_state& state;
130 const net::node_base& out;
131 void operator()(value_port& val) const { val.write_value(ossia::net::to_map(out), 0); }
132
133 void operator()(audio_port& val) const
134 {
135 // TODO Nothing to do ?
136 }
137
138 void operator()(midi_port& val) const
139 {
140#if defined(OSSIA_PROTOCOL_MIDI)
141 auto& node = out;
142 auto& dev = node.get_device();
143 auto& proto = dev.get_protocol();
144
145 auto midi = dynamic_cast<ossia::net::midi::midi_stream*>(&proto);
146 if(!midi)
147 return;
148
149 const int channel = midi->stream_channel(node).value_or(-1);
150
151 auto it = state.m_receivedMidi.find(midi);
152 if(it != state.m_receivedMidi.end())
153 {
154 if(channel == -1)
155 {
156 for(const libremidi::ump& v : it->second.messages)
157 {
158 val.messages.push_back(v);
159 }
160 }
161 else
162 {
163 for(const libremidi::ump& v : it->second.messages)
164 {
165 if(v.get_channel() == channel)
166 val.messages.push_back(v);
167 }
168 }
169 }
170#endif
171 }
172
173 [[noreturn]] void operator()(texture_port& val) const = delete;
174 [[noreturn]] void operator()(geometry_port& val) const = delete;
175
176 void operator()() const { }
177};
178
179}
Definition midi_stream.hpp:33
virtual std::optional< int > stream_channel(const node_base &n) const noexcept
Definition midi_stream.cpp:7
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
Definition git_info.h:7