OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
oscquery_protocol_common.hpp
1#pragma once
2#include <ossia/network/base/osc_address.hpp>
3#include <ossia/network/base/parameter.hpp>
4#include <ossia/network/base/parameter_data.hpp>
5#include <ossia/network/osc/detail/bundle.hpp>
6#include <ossia/network/osc/detail/osc.hpp>
7#include <ossia/network/osc/detail/osc_1_1_extended_policy.hpp>
8#include <ossia/network/osc/detail/osc_value_write_visitor.hpp>
9#include <ossia/network/sockets/udp_socket.hpp>
10#include <ossia/network/sockets/writers.hpp>
11
12namespace ossia::oscquery
13{
14template <typename OscVersion>
15struct oscquery_protocol_common
16{
17 template <typename Protocol, typename Socket, typename Addr>
18 static void osc_send_message(
19 Protocol& proto, Socket& socket, const Addr& addr, const ossia::value& val)
20 {
21 using namespace ossia::net;
22 using send_visitor
23 = osc_value_send_visitor<Addr, OscVersion, socket_writer<udp_send_socket>>;
24 send_visitor vis{addr, ossia::net::osc_address(addr), {socket}};
25 val.apply(vis);
26 }
27 template <typename Protocol, typename Addr>
28 static void
29 osc_send_message(Protocol& proto, const Addr& addr, const ossia::value& val)
30 {
31 osc_send_message(proto, proto.osc_sender(), addr, val);
32 }
33
34 template <typename Protocol, typename Socket, typename Addr>
35 static void ws_send_binary_message(
36 Protocol& proto, Socket&& socket, const Addr& addr, const ossia::value& val)
37 {
38 using namespace ossia::net;
39 using write_visitor = osc_value_write_visitor<Addr, OscVersion>;
40
41 auto& pool = buffer_pool::instance();
42 auto buf = pool.acquire();
43
44 write_visitor vis{addr, ossia::net::osc_address(addr), buf};
45 val.apply(vis);
46
47 socket.send_binary_message({buf.data(), buf.size()});
48
49 pool.release(std::move(buf));
50 }
51
52 template <typename Protocol, typename Addr>
53 static void
54 ws_send_binary_message(Protocol& proto, const Addr& addr, const ossia::value& val)
55 {
56 using namespace ossia::net;
57 using write_visitor = osc_value_write_visitor<Addr, OscVersion>;
58
59 auto& pool = buffer_pool::instance();
60 auto buf = pool.acquire();
61
62 write_visitor vis{addr, ossia::net::osc_address(addr), buf};
63 val.apply(vis);
64 proto.ws_client().send_binary_message({buf.data(), buf.size()});
65
66 pool.release(std::move(buf));
67 }
68
69 template <typename Protocol, typename Addr>
70 static bool push(Protocol& proto, const Addr& addr, const ossia::value& v)
71 {
72 if(auto val = bound_value(addr, v); val.valid())
73 {
74 // Push to server
75 const bool critical = addr.get_critical();
76 const bool has_ws = proto.ws_connected();
77 const bool has_osc = proto.osc_connected();
78 if((!critical || !has_ws) && has_osc)
79 { /*
80 if (m_logger.outbound_logger)
81 {
82 m_logger.outbound_logger->info("Out: {} {}", addr.address, val);
83 }*/
84 osc_send_message(proto, addr, val);
85 return true;
86 }
87 else if(has_ws)
88 { /*
89 if (m_logger.outbound_logger)
90 {
91 m_logger.outbound_logger->info("Out: {} {}", addr.address, val);
92 }*/
93
94 ws_send_binary_message(proto, addr, val);
95 return true;
96 }
97
98 /*
99 if (m_logger.outbound_listened_logger)
100 m_logger.outbound_listened_logger->info("Out: {0}", addr, val);
101 */
102 }
103 return false;
104 }
105};
106
107template <typename OscVersion>
108struct oscquery_protocol_client : oscquery_protocol_common<OscVersion>
109{
110 template <typename T, typename Addr_T, typename Val_T>
111 static bool push(T& self, const Addr_T& addr, Val_T&& v)
112 {
113 if(addr.get_access() == ossia::access_mode::GET)
114 return false;
115
116 return oscquery_protocol_common<OscVersion>::push(
117 self, addr, std::forward<Val_T>(v));
118 }
119
120 template <typename Protocol, typename Addresses>
121 requires(!requires(Protocol p) { p.ws_connected(); })
122 static bool push_bundle(Protocol& proto, const Addresses& addresses)
123 {
124 // FIXME most likely we shouldn't do anything here but maybe
125 // the concept heuristic isn't the best
126 return false;
127 }
128
129 template <typename Protocol, typename Addresses>
130 requires requires(Protocol p) { p.ws_connected(); }
131 static bool push_bundle(Protocol& proto, const Addresses& addresses)
132 {
133 if(auto bundle = ossia::net::make_bundle(
134 ossia::net::bundle_client_policy<OscVersion>{}, addresses))
135 {
136 const bool critical = bundle->critical;
137 const bool has_ws = proto.ws_connected();
138 const bool has_osc = proto.osc_connected();
139 if((!critical || !has_ws) && has_osc)
140 {
141 proto.osc_sender().write(bundle->data.data(), bundle->data.size());
142 ossia::buffer_pool::instance().release(std::move(bundle->data));
143 }
144 else if(has_ws)
145 {
146 proto.ws_client().send_binary_message(
147 {bundle->data.data(), bundle->data.size()});
148 }
149 return true;
150 }
151 return false;
152 }
153};
154
155/*
156template<typename OscVersion>
157struct oscquery_protocol_server: oscquery_protocol_common<OscVersion>
158{
159
160 template<typename Protocol, typename Addresses>
161 static bool push_bundle(Protocol& proto, const Addresses& addresses)
162 {
163 if(auto bundle =
164ossia::net::make_bundle(ossia::net::bundle_client_policy<OscVersion>{},
165addresses))
166 {
167 const bool critical = bundle->critical;
168 const bool has_ws = proto.ws_connected();
169 const bool has_osc = proto.osc_connected();
170 if ((!critical || !has_ws) && has_osc)
171 {
172 proto.osc_sender().write(bundle->data.data(), bundle->data.size());
173 ossia::buffer_pool::instance().release(std::move(bundle->data));
174 }
175 else if (has_ws)
176 {
177 proto.ws_client().send_binary_message({bundle->data.data(),
178bundle->data.size()});
179 }
180 return true;
181 }
182 return false;
183 }
184};
185*/
186}
The value class.
Definition value.hpp:173
@ GET
The value can be retrieved and changed.
bool critical
Means that the node is very important, e.g. a "play" message.
Definition node_attributes.hpp:92