3#include <ossia/detail/timer.hpp>
4#include <ossia/network/base/bundle.hpp>
5#include <ossia/network/base/parameter.hpp>
6#include <ossia/network/base/protocol.hpp>
7#include <ossia/network/context.hpp>
8#include <ossia/network/osc/detail/osc_packet_processor.hpp>
9#include <ossia/network/osc/detail/osc_receive.hpp>
10#include <ossia/network/sockets/configuration.hpp>
11#include <ossia/network/sockets/null_socket.hpp>
12#include <ossia/network/sockets/writers.hpp>
13#include <ossia/protocols/dense/dense_protocol_configuration.hpp>
15#include <oscpack/osc/OscReceivedElements.h>
25 int available() const noexcept {
return end - it; }
27 bool operator()() {
return false; }
28 bool operator()(ossia::impulse) {
return true; }
29 bool operator()(uint16_t v)
noexcept
33 memcpy(it, &v,
sizeof(v));
39 bool operator()(int32_t v)
noexcept
43 memcpy(it, &v,
sizeof(v));
49 bool operator()(
bool vv)
noexcept
51 int32_t v = vv ? 1 : 0;
54 memcpy(it, &v,
sizeof(v));
60 bool operator()(
float v)
noexcept
64 memcpy(it, &v,
sizeof(v));
70 bool operator()(std::string_view v)
noexcept
72 if(available() >= (4 + v.size()))
74 (*this)((int)std::ssize(v));
75 memcpy(it, v.data(), v.size());
81 template <std::
size_t N>
82 bool operator()(std::array<float, N> v)
noexcept
84 if(available() >= 4 * N)
86 for(
int i = 0; i < N; i++)
92 bool operator()(
const std::vector<ossia::value>& v)
noexcept
94 if(available() >= 4 * v.size() + 4)
97 (*this)((uint16_t)v.size());
99 for(
int i = 0; i < v.size(); i++)
101 ok &= v[i].apply(*
this);
109 bool operator()(
const ossia::value_map_type& v)
noexcept
111 if(available() >= 4 * v.size() + 4)
113 (*this)((uint16_t)0);
114 (*this)((uint16_t)v.size());
116 for(
auto& [k, val] : v)
118 ok &= val.apply(*
this);
128template <
typename SendSocket,
typename RecvSocket>
133 using writer_type = socket_writer<SendSocket>;
135 dense_generic_bidir_protocol(
136 network_context_ptr ctx,
const dense_configuration& conf,
137 const send_fd_configuration& send_conf,
const receive_fd_configuration& recv_conf)
138 :
ossia::net::protocol_base{flags{SupportsMultiplex}}
139 , m_ctx{std::move(ctx)}
141 , from_client{recv_conf, m_ctx->context}
142 , to_client{send_conf, m_ctx->context}
147 init_timer(conf.interval);
150 dense_generic_bidir_protocol(
151 network_context_ptr ctx,
const dense_configuration& conf,
152 const outbound_socket_configuration& send_conf,
153 const inbound_socket_configuration& recv_conf)
154 :
ossia::net::protocol_base{flags{SupportsMultiplex}}
155 , m_ctx{std::move(ctx)}
157 , from_client{recv_conf, m_ctx->context}
158 , to_client{send_conf, m_ctx->context}
163 init_timer(conf.interval);
166 dense_generic_bidir_protocol(
167 network_context_ptr ctx,
const dense_configuration& conf,
168 const outbound_socket_configuration& send_conf)
169 :
ossia::net::protocol_base{flags{SupportsMultiplex}}
170 , m_ctx{std::move(ctx)}
172 , to_client{send_conf, m_ctx->context}
173 , m_timer{m_ctx->context}
176 init_timer(conf.interval);
179 dense_generic_bidir_protocol(
180 network_context_ptr ctx,
const dense_configuration& conf,
181 const inbound_socket_configuration& recv_conf)
182 :
ossia::net::protocol_base{flags{SupportsMultiplex}}
183 , m_ctx{std::move(ctx)}
185 , from_client{recv_conf, m_ctx->context}
189 init_timer(conf.interval);
192 dense_generic_bidir_protocol(
193 network_context_ptr ctx,
const dense_configuration& conf,
194 const send_fd_configuration& send_conf)
195 :
ossia::net::protocol_base{flags{SupportsMultiplex}}
196 , m_ctx{std::move(ctx)}
198 , to_client{send_conf, m_ctx->context}
201 init_timer(conf.interval);
204 dense_generic_bidir_protocol(
205 network_context_ptr ctx,
const dense_configuration& conf,
206 const receive_fd_configuration& recv_conf)
207 :
ossia::net::protocol_base{flags{SupportsMultiplex}}
208 , m_ctx{std::move(ctx)}
210 , from_client{recv_conf, m_ctx->context}
214 init_timer(conf.interval);
217 dense_generic_bidir_protocol(
const dense_generic_bidir_protocol&) =
delete;
218 dense_generic_bidir_protocol(dense_generic_bidir_protocol&&) =
delete;
219 dense_generic_bidir_protocol& operator=(
const dense_generic_bidir_protocol&) =
delete;
220 dense_generic_bidir_protocol& operator=(dense_generic_bidir_protocol&&) =
delete;
222 ~dense_generic_bidir_protocol()
override =
default;
224 void init_timer(std::chrono::microseconds us) { m_timer.set_delay(us); }
228 from_client.receive([
this](
const char* data, std::size_t sz) {
231 auto on_message = [
this](
auto&& msg) {
232 ossia::net::on_input_message<false>(
233 msg.AddressPattern(), ossia::net::osc_message_applier{m_id, msg},
false,
234 *m_device, m_logger);
236 osc_packet_processor<
decltype(on_message)>{on_message}(data, sz);
249 bool echo_incoming_message(
250 const message_origin_identifier&
id,
const parameter_base& addr,
251 const value& val)
override
275 bool push_bundle(
const std::vector<const parameter_base*>& addresses)
override
281 bool push_bundle(tcb::span<ossia::bundle_element> addresses)
override
287 bool push_bundle_bounded(tcb::span<ossia::bundle_element> addresses)
override
294 push_raw_bundle(
const std::vector<ossia::net::full_parameter_data>& addresses)
override
303 m_timer.start([
this] { this->update_function(); });
306 auto writer() noexcept {
return writer_type{to_client}; }
308 void update_function()
312 static std::atomic_int seq = 0;
316 pkt.header.protocol_code = 0xCAFECAFE;
318 int n = write_packet(pkt.data);
320 to_client.write(
reinterpret_cast<const char*
>(&pkt),
sizeof(pkt.header) + n);
322 catch(std::exception& e)
332 void recompute_nodes()
335 m_params.reserve(200);
339 auto& dev = this->m_device->get_root_node();
340 ossia::net::iterate_all_children(
344 for(
auto& p : m_params)
349 int write_packet(std::span<unsigned char> data)
351 dense_writer wr{data.data(), data.data() + data.size()};
352 for(
auto& param : m_params)
354 param->value().apply(wr);
356 return wr.it - data.data();
359 using ossia::net::protocol_base::m_logger;
360 ossia::net::network_context_ptr m_ctx;
361 message_origin_identifier m_id;
365 RecvSocket from_client;
366 SendSocket to_client;
368 ossia::timer m_timer;
370 ossia::flat_set<ossia::net::parameter_base*, parameter_alphabetical_sort> m_params;
Root of a device tree.
Definition ossia/network/base/device.hpp:58
The node_base class.
Definition node.hpp:48
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
The protocol_base class.
Definition protocol.hpp:40
The value class.
Definition value.hpp:173
spdlog::logger & logger() noexcept
Where the errors will be logged. Default is stderr.
Definition context.cpp:118
Full information about a parameter.
Definition parameter_data.hpp:61