2#include <ossia/detail/lockfree_queue.hpp>
4#include <ossia/detail/mutex.hpp>
5#include <ossia/network/base/listening.hpp>
6#include <ossia/network/base/parameter.hpp>
7#include <ossia/network/base/protocol.hpp>
8#include <ossia/network/context.hpp>
9#include <ossia/network/domain/domain.hpp>
10#include <ossia/network/exceptions.hpp>
11#include <ossia/network/generic/generic_device.hpp>
12#include <ossia/network/generic/generic_parameter.hpp>
13#include <ossia/network/osc/detail/osc_1_0_policy.hpp>
14#include <ossia/network/osc/detail/osc_1_1_extended_policy.hpp>
15#include <ossia/network/osc/detail/osc_1_1_policy.hpp>
16#include <ossia/network/osc/detail/osc_protocol_common.hpp>
17#include <ossia/network/sockets/configuration.hpp>
18#include <ossia/network/sockets/null_socket.hpp>
19#include <ossia/network/sockets/writers.hpp>
20#include <ossia/network/value/value.hpp>
22#include <ossia/detail/hash_map.hpp>
29template <
typename OscMode,
typename SendSocket,
typename RecvSocket>
30class osc_generic_bidir_protocol final :
public can_learn<ossia::net::protocol_base>
33 using osc_configuration =
typename OscMode::osc_configuration;
34 static constexpr bool bundled =
requires {
typename osc_configuration::bundled; };
35 using writer_type = socket_writer<SendSocket>;
37 osc_generic_bidir_protocol(
38 network_context_ptr ctx,
const send_fd_configuration& send_conf,
39 const receive_fd_configuration& recv_conf)
40 : can_learn<
ossia::net::protocol_base>{flags{SupportsMultiplex}}
41 , m_ctx{std::move(ctx)}
43 , from_client{recv_conf, m_ctx->
context}
44 , to_client{send_conf, m_ctx->
context}
49 from_client.receive([
this](
const char* data, std::size_t sz) {
52 auto on_message = [
this](
auto&& msg) { this->on_received_message(msg); };
53 osc_packet_processor<
decltype(on_message)>{on_message}(data, sz);
57 osc_generic_bidir_protocol(
58 network_context_ptr ctx,
const outbound_socket_configuration& send_conf,
59 const inbound_socket_configuration& recv_conf)
60 : can_learn<
ossia::net::protocol_base>{flags{SupportsMultiplex}}
61 , m_ctx{std::move(ctx)}
63 , from_client{recv_conf, m_ctx->
context}
64 , to_client{send_conf, m_ctx->
context}
69 from_client.receive([
this](
const char* data, std::size_t sz) {
72 auto on_message = [
this](
auto&& msg) { this->on_received_message(msg); };
73 osc_packet_processor<
decltype(on_message)>{on_message}(data, sz);
77 osc_generic_bidir_protocol(
78 network_context_ptr ctx,
const outbound_socket_configuration& send_conf)
79 : can_learn<
ossia::net::protocol_base>{flags{SupportsMultiplex}}
80 , m_ctx{std::move(ctx)}
82 , to_client{send_conf, m_ctx->
context}
87 osc_generic_bidir_protocol(
88 network_context_ptr ctx,
const inbound_socket_configuration& recv_conf)
89 : can_learn<
ossia::net::protocol_base>{flags{SupportsMultiplex}}
90 , m_ctx{std::move(ctx)}
92 , from_client{recv_conf, m_ctx->
context}
96 from_client.receive([
this](
const char* data, std::size_t sz) {
99 auto on_message = [
this](
auto&& msg) { this->on_received_message(msg); };
100 osc_packet_processor<
decltype(on_message)>{on_message}(data, sz);
104 osc_generic_bidir_protocol(
105 network_context_ptr ctx,
const send_fd_configuration& send_conf)
106 : can_learn<
ossia::net::protocol_base>{flags{SupportsMultiplex}}
107 , m_ctx{std::move(ctx)}
109 , to_client{send_conf, m_ctx->
context}
114 osc_generic_bidir_protocol(
115 network_context_ptr ctx,
const receive_fd_configuration& recv_conf)
116 : can_learn<
ossia::net::protocol_base>{flags{SupportsMultiplex}}
117 , m_ctx{std::move(ctx)}
119 , from_client{recv_conf, m_ctx->
context}
123 from_client.receive([
this](
const char* data, std::size_t sz) {
126 auto on_message = [
this](
auto&& msg) { this->on_received_message(msg); };
127 osc_packet_processor<
decltype(on_message)>{on_message}(data, sz);
131 osc_generic_bidir_protocol(
const osc_generic_bidir_protocol&) =
delete;
132 osc_generic_bidir_protocol(osc_generic_bidir_protocol&&) =
delete;
133 osc_generic_bidir_protocol& operator=(
const osc_generic_bidir_protocol&) =
delete;
134 osc_generic_bidir_protocol& operator=(osc_generic_bidir_protocol&&) =
delete;
136 ~osc_generic_bidir_protocol()
override =
default;
144 if constexpr(!std::is_same_v<RecvSocket, ossia::net::null_socket>)
146 return OscMode::observe(*
this, parameter_base, enable);
154 bool echo_incoming_message(
155 const message_origin_identifier&
id,
const parameter_base& addr,
156 const value& val)
override
158 if constexpr(!std::is_same_v<SendSocket, ossia::net::null_socket>)
161 return OscMode::echo_incoming_message(*
this,
id, addr, val);
171 if constexpr(!std::is_same_v<SendSocket, ossia::net::null_socket>)
173 if constexpr(bundled)
174 return OscMode::push_bundle(*
this, writer(), addr, v);
176 return OscMode::push(*
this, addr, v);
186 if constexpr(!std::is_same_v<SendSocket, ossia::net::null_socket>)
188 if constexpr(bundled)
189 return OscMode::push_bundle(*
this, writer(), addr, std::move(v));
191 return OscMode::push(*
this, addr, std::move(v));
201 if constexpr(!std::is_same_v<SendSocket, ossia::net::null_socket>)
203 if constexpr(bundled)
204 return OscMode::push_bundle(*
this, writer(), addr);
206 return OscMode::push_raw(*
this, addr);
214 bool push_bundle(
const std::vector<const parameter_base*>& addresses)
override
216 if constexpr(!std::is_same_v<SendSocket, ossia::net::null_socket>)
218 return OscMode::push_bundle(*
this, writer(), addresses);
226 bool push_bundle(tcb::span<ossia::bundle_element> addresses)
override
228 if constexpr(!std::is_same_v<SendSocket, ossia::net::null_socket>)
230 return OscMode::push_bundle(*
this, writer(), addresses);
238 bool push_bundle_bounded(tcb::span<ossia::bundle_element> addresses)
override
240 if constexpr(!std::is_same_v<SendSocket, ossia::net::null_socket>)
242 return OscMode::push_bundle_bounded(*
this, writer(), addresses);
251 push_raw_bundle(
const std::vector<ossia::net::full_parameter_data>& addresses)
override
253 if constexpr(!std::is_same_v<SendSocket, ossia::net::null_socket>)
255 return OscMode::push_bundle(*
this, writer(), addresses);
263 void on_received_message(
const oscpack::ReceivedMessage& m)
265 if constexpr(!std::is_same_v<RecvSocket, ossia::net::null_socket>)
267 return OscMode::on_received_message(*
this, m);
273 auto writer() noexcept {
return writer_type{to_client}; }
275 using ossia::net::protocol_base::m_logger;
276 ossia::net::network_context_ptr m_ctx;
277 message_origin_identifier m_id;
278 listened_parameters m_listening;
282 RecvSocket from_client;
283 SendSocket to_client;
286template <
typename OscMode,
typename Socket>
287class osc_generic_server_protocol final :
public can_learn<ossia::net::protocol_base>
290 using osc_configuration =
typename OscMode::osc_configuration;
291 static constexpr bool bundled =
requires {
typename osc_configuration::bundled; };
292 using socket_type = Socket;
293 using writer_type = socket_writer<socket_type>;
295 template <
typename Configuration>
296 requires(
requires(Configuration conf) { Socket{conf, network_context_ptr{}}; })
297 osc_generic_server_protocol(network_context_ptr ctx,
const Configuration& conf)
298 : can_learn<ossia::net::protocol_base>{flags{SupportsMultiplex}}
299 , m_ctx{std::move(ctx)}
301 , m_server{conf, m_ctx}
308 m_server.listen([
this](
const unsigned char* data, std::size_t sz) {
309 auto on_message = [
this](
auto&& msg) { this->on_received_message(msg); };
310 osc_packet_processor<
decltype(on_message)>{on_message}((
const char*)data, sz);
314 osc_generic_server_protocol(
const osc_generic_server_protocol&) =
delete;
315 osc_generic_server_protocol(osc_generic_server_protocol&&) =
delete;
316 osc_generic_server_protocol& operator=(
const osc_generic_server_protocol&) =
delete;
317 osc_generic_server_protocol& operator=(osc_generic_server_protocol&&) =
delete;
319 ~osc_generic_server_protocol()
override =
default;
327 return OscMode::observe(*
this, parameter_base, enable);
330 bool echo_incoming_message(
331 const message_origin_identifier&
id,
const parameter_base& addr,
332 const value& val)
override
334 return OscMode::echo_incoming_message(*
this,
id, addr, val);
339 if constexpr(bundled)
340 return OscMode::push_bundle(*
this, writer(), addr, v);
342 return OscMode::push(*
this, addr, v);
347 if constexpr(bundled)
348 return OscMode::push_bundle(*
this, writer(), addr, std::move(v));
350 return OscMode::push(*
this, addr, std::move(v));
355 if constexpr(bundled)
356 return OscMode::push_bundle(*
this, writer(), addr);
358 return OscMode::push_raw(*
this, addr);
361 bool push_bundle(
const std::vector<const parameter_base*>& addresses)
override
363 return OscMode::push_bundle(*
this, writer(), addresses);
366 bool push_bundle(tcb::span<ossia::bundle_element> addresses)
override
368 return OscMode::push_bundle(*
this, writer(), addresses);
371 bool push_bundle_bounded(tcb::span<ossia::bundle_element> addresses)
override
373 return OscMode::push_bundle_bounded(*
this, writer(), addresses);
377 push_raw_bundle(
const std::vector<ossia::net::full_parameter_data>& addresses)
override
379 return OscMode::push_bundle(*
this, writer(), addresses);
382 void on_received_message(
const oscpack::ReceivedMessage& m)
384 return OscMode::on_received_message(*
this, m);
389 auto writer() noexcept {
return writer_type{m_server}; }
391 using ossia::net::protocol_base::m_logger;
392 ossia::net::network_context_ptr m_ctx;
393 message_origin_identifier m_id;
394 listened_parameters m_listening;
401template <
typename OscMode,
typename Socket>
402class osc_generic_client_protocol :
public can_learn<ossia::net::protocol_base>
405 using osc_configuration =
typename OscMode::osc_configuration;
406 static constexpr bool bundled =
requires {
typename osc_configuration::bundled; };
407 using socket_type = Socket;
408 using writer_type = socket_writer<socket_type>;
410 template <
typename Configuration>
411 osc_generic_client_protocol(network_context_ptr ctx,
const Configuration& conf)
412 : can_learn<
ossia::net::protocol_base>{flags{SupportsMultiplex}}
413 , m_ctx{std::move(ctx)}
415 , m_client{conf, m_ctx->
context}
422 m_client.on_open.connect(this->on_connection_open);
423 m_client.on_close.connect(this->on_connection_closed);
424 m_client.on_fail.connect(this->on_connection_failure);
427 m_client.receive([
this](
const unsigned char* data, std::size_t sz) {
428 auto on_message = [
this](
auto&& msg) { this->on_received_message(msg); };
429 osc_packet_processor<
decltype(on_message)>{on_message}((
const char*)data, sz);
433 osc_generic_client_protocol(
const osc_generic_client_protocol&) =
delete;
434 osc_generic_client_protocol(osc_generic_client_protocol&&) =
delete;
435 osc_generic_client_protocol& operator=(
const osc_generic_client_protocol&) =
delete;
436 osc_generic_client_protocol& operator=(osc_generic_client_protocol&&) =
delete;
438 ~osc_generic_client_protocol()
override =
default;
446 return OscMode::observe(*
this, parameter_base, enable);
449 bool echo_incoming_message(
450 const message_origin_identifier&
id,
const parameter_base& addr,
451 const value& val)
override
453 return OscMode::echo_incoming_message(*
this,
id, addr, val);
458 if constexpr(bundled)
459 return OscMode::push_bundle(*
this, writer(), addr, v);
461 return OscMode::push(*
this, addr, v);
466 if constexpr(bundled)
467 return OscMode::push_bundle(*
this, writer(), addr, std::move(v));
469 return OscMode::push(*
this, addr, std::move(v));
474 if constexpr(bundled)
475 return OscMode::push_bundle(*
this, writer(), addr);
477 return OscMode::push_raw(*
this, addr);
480 bool push_bundle(
const std::vector<const parameter_base*>& addresses)
override
482 return OscMode::push_bundle(*
this, writer(), addresses);
485 bool push_bundle(tcb::span<ossia::bundle_element> addresses)
override
487 return OscMode::push_bundle(*
this, writer(), addresses);
490 bool push_bundle_bounded(tcb::span<ossia::bundle_element> addresses)
override
492 return OscMode::push_bundle_bounded(*
this, writer(), addresses);
496 push_raw_bundle(
const std::vector<ossia::net::full_parameter_data>& addresses)
override
498 return OscMode::push_bundle(*
this, writer(), addresses);
501 void on_received_message(
const oscpack::ReceivedMessage& m)
503 return OscMode::on_received_message(*
this, m);
508 auto writer() noexcept {
return writer_type{m_client}; }
510 bool connected() const noexcept
override {
return m_client.connected(); }
512 void connect()
override {
return m_client.connect(); }
514 using ossia::net::protocol_base::m_logger;
515 ossia::net::network_context_ptr m_ctx;
516 message_origin_identifier m_id;
517 listened_parameters m_listening;
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 value class.
Definition value.hpp:173
If using the library, you should create this class at some point.
Definition context.hpp:27
context()
Most common case.
Definition context.cpp:87
Full information about a parameter.
Definition parameter_data.hpp:61