OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
osc_protocol_common.hpp
1#pragma once
2#include <ossia/network/base/parameter.hpp>
3#include <ossia/network/osc/detail/bundle.hpp>
4#include <ossia/network/osc/detail/message_generator.hpp>
5#include <ossia/network/osc/detail/osc_1_0_policy.hpp>
6#include <ossia/network/osc/detail/osc_packet_processor.hpp>
7#include <ossia/network/osc/detail/osc_receive.hpp>
8#include <ossia/network/osc/detail/osc_value_write_visitor.hpp>
9#include <ossia/network/value/format_value.hpp>
10
11namespace ossia::net
12{
13
14template <typename OscVersion>
15struct osc_protocol_common
16{
17 using osc_configuration = OscVersion;
18 template <typename T, typename Value_T>
19 static bool push(T& self, const ossia::net::parameter_base& addr, Value_T&& v)
20 {
21 auto val = bound_value(addr, std::forward<Value_T>(v));
22 if(val.valid())
23 {
24 using send_visitor = osc_value_send_visitor<
25 ossia::net::parameter_base, OscVersion, typename T::writer_type>;
26
27 send_visitor vis{addr, addr.get_node().osc_address(), self.writer()};
28 val.apply(vis);
29
30 if(const auto& logger = self.m_logger.outbound_logger)
31 {
32 logger->info("[push] {} {}", addr.get_node().osc_address(), val);
33 }
34 return true;
35 }
36 return false;
37 }
38
39 template <typename T>
40 static bool push_raw(T& self, const ossia::net::full_parameter_data& addr)
41 {
42 auto val = bound_value(addr, addr.value());
43 if(val.valid())
44 {
45 using send_visitor = osc_value_send_visitor<
46 ossia::net::full_parameter_data, OscVersion, typename T::writer_type>;
47 val.apply(send_visitor{addr, addr.address, self.writer()});
48
49 if(const auto& logger = self.m_logger.outbound_logger)
50 {
51 logger->info("[push_raw] {} {}", addr.address, val);
52 }
53 return true;
54 }
55 return false;
56 }
57
58 template <typename T>
59 static bool echo_incoming_message(
60 T& self, const message_origin_identifier& id, const parameter_base& addr,
61 const value& val)
62 {
63 if(&id.protocol == &self)
64 return true;
65
66 using send_visitor = osc_value_send_visitor<
67 ossia::net::parameter_base, OscVersion, typename T::writer_type>;
68 val.apply(send_visitor{addr, addr.get_node().osc_address(), self.writer()});
69
70 if(const auto& logger = self.m_logger.outbound_logger)
71 {
72 logger->info("[echo] {} {}", addr.get_node().osc_address(), val);
73 }
74 return true;
75 }
76
77 template <typename T>
78 static bool observe(T& self, ossia::net::parameter_base& address, bool enable)
79 {
80 if(enable)
81 self.m_listening.insert(
82 std::make_pair(address.get_node().osc_address(), &address));
83 else
84 self.m_listening.erase(address.get_node().osc_address());
85
86 return true;
87 }
88
89 template <typename T>
90 static void on_received_message(T& self, const oscpack::ReceivedMessage& m)
91 {
92 [[unlikely]] if(self.learning())
93 {
94 auto already_learned = ossia::net::osc_learn(&self.m_device->get_root_node(), m);
95 if(!already_learned)
96 return;
97 }
98
99 ossia::net::on_input_message<false>(
100 m.AddressPattern(), ossia::net::osc_message_applier{self.m_id, m},
101 self.m_listening, *self.m_device, self.m_logger);
102 }
103};
104
105// Client can't push to GET addresses
106template <typename OscVersion>
107struct osc_protocol_client : osc_protocol_common<OscVersion>
108{
109 template <typename T, typename Val_T>
110 static bool push(T& self, const ossia::net::parameter_base& addr, Val_T&& v)
111 {
112 if(addr.get_access() == ossia::access_mode::GET)
113 return false;
114
115 return osc_protocol_common<OscVersion>::push(self, addr, std::forward<Val_T>(v));
116 }
117
118 template <typename T>
119 static bool push_raw(T& self, const ossia::net::full_parameter_data& addr)
120 {
121 if(addr.get_access() == ossia::access_mode::GET)
122 return false;
123
124 return osc_protocol_common<OscVersion>::push_raw(self, addr);
125 }
126
127 template <typename T, typename Writer>
128 static bool push_bundle(
129 T& self, Writer writer, const ossia::net::parameter_base& addr, ossia::value v)
130 {
131 if(auto bundle = make_bundle(bundle_client_policy<OscVersion>{}, addr, v))
132 {
133 writer(bundle->data.data(), bundle->data.size());
134 ossia::buffer_pool::instance().release(std::move(bundle->data));
135 return true;
136 }
137 return false;
138 }
139
140 template <typename T, typename Writer>
141 static bool
142 push_bundle(T& self, Writer writer, const ossia::net::full_parameter_data& addr)
143 {
144 if(auto bundle = make_bundle(bundle_client_policy<OscVersion>{}, addr))
145 {
146 writer(bundle->data.data(), bundle->data.size());
147 ossia::buffer_pool::instance().release(std::move(bundle->data));
148 return true;
149 }
150 return false;
151 }
152
153 template <typename T, typename Writer, typename Addresses>
154 static bool push_bundle(T& self, Writer writer, const Addresses& addresses)
155 {
156 if(auto bundle = make_bundle(bundle_client_policy<OscVersion>{}, addresses))
157 {
158 writer(bundle->data.data(), bundle->data.size());
159 ossia::buffer_pool::instance().release(std::move(bundle->data));
160 return true;
161 }
162 return false;
163 }
164
165 template <typename T, typename Writer, typename Addresses>
166 static bool push_bundle_bounded(T& self, Writer writer, const Addresses& addresses)
167 {
168 return make_bundle_bounded(
169 bundle_bounded_client_policy<OscVersion>{}, addresses,
170 [writer](const ossia::net::bundle& bundle) {
171 writer(bundle.data.data(), bundle.data.size());
172 });
173 }
174};
175
176// Servers can push to GET addresses
177template <typename OscVersion>
178struct osc_protocol_server : osc_protocol_common<OscVersion>
179{
180 template <typename T, typename Val_T>
181 static bool push(T& self, const ossia::net::parameter_base& addr, Val_T&& v)
182 {
183 if(addr.get_access() == ossia::access_mode::SET)
184 return false;
185
186 return osc_protocol_common<OscVersion>::push(self, addr, std::forward<Val_T>(v));
187 }
188
189 template <typename T>
190 static bool push_raw(T& self, const ossia::net::full_parameter_data& addr)
191 {
192 if(addr.get_access() == ossia::access_mode::SET)
193 return false;
194
195 return osc_protocol_common<OscVersion>::push_raw(self, addr);
196 }
197
198 template <typename T, typename Writer>
199 static bool
200 push_bundle(T& self, Writer writer, const ossia::net::full_parameter_data& addr)
201 {
202 if(auto bundle = make_bundle(bundle_server_policy<OscVersion>{}, addr))
203 {
204 writer(bundle->data.data(), bundle->data.size());
205 ossia::buffer_pool::instance().release(std::move(bundle->data));
206 return true;
207 }
208 return false;
209 }
210
211 template <typename T, typename Writer>
212 static bool push_bundle(
213 T& self, Writer writer, const ossia::net::parameter_base& addr, ossia::value v)
214 {
215 if(auto bundle = make_bundle(bundle_server_policy<OscVersion>{}, addr, v))
216 {
217 writer(bundle->data.data(), bundle->data.size());
218 ossia::buffer_pool::instance().release(std::move(bundle->data));
219 return true;
220 }
221 return false;
222 }
223
224 template <typename T, typename Writer, typename Addresses>
225 static bool push_bundle(T& self, Writer writer, const Addresses& addresses)
226 {
227 if(auto bundle = make_bundle(bundle_server_policy<OscVersion>{}, addresses))
228 {
229 writer(bundle->data.data(), bundle->data.size());
230 ossia::buffer_pool::instance().release(std::move(bundle->data));
231 return true;
232 }
233 return false;
234 }
235
236 template <typename T, typename Writer>
237 static bool
238 push_bundle(T& self, Writer writer, tcb::span<ossia::bundle_element> addresses)
239 {
240 if(auto bundle = make_bundle(bundle_server_policy<OscVersion>{}, addresses))
241 {
242 writer(bundle->data.data(), bundle->data.size());
243 ossia::buffer_pool::instance().release(std::move(bundle->data));
244 return true;
245 }
246 return false;
247 }
248
249 template <typename T, typename Writer>
250 static bool
251 push_bundle_bounded(T& self, Writer writer, tcb::span<ossia::bundle_element> addresses)
252 {
253 return make_bundle_bounded(
254 bundle_bounded_server_policy<OscVersion>{}, addresses,
255 [writer](const ossia::net::bundle& bundle) {
256 writer(bundle.data.data(), bundle.data.size());
257 });
258 }
259};
260
261}
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
The value class.
Definition value.hpp:173
spdlog::logger & logger() noexcept
Where the errors will be logged. Default is stderr.
Definition context.cpp:118
@ GET
The value can be retrieved and changed.
@ SET
The value can be retrieved.
Full information about a parameter.
Definition parameter_data.hpp:61