2#include <ossia/detail/buffer_pool.hpp>
4#include <ossia/network/osc/detail/message_generator.hpp>
5#include <ossia/network/osc/detail/osc_messages.hpp>
6#include <ossia/network/osc/detail/osc_packet_processor.hpp>
7#include <ossia/network/osc/detail/osc_utils.hpp>
8#include <ossia/network/value/value.hpp>
10#include <boost/endian/conversion.hpp>
12#include <oscpack/osc/OscOutboundPacketStream.h>
13#include <oscpack/osc/OscReceivedElements.h>
17template <
typename Parameter,
typename OscPolicy,
typename Writer>
18#if __cpp_lib_concepts >= 201907L
19 requires std::is_invocable_v<Writer, const char*, std::size_t>
21struct osc_value_send_visitor
23 const Parameter& parameter;
24 std::string_view address_pattern;
27 using static_policy =
typename OscPolicy::static_policy;
28 using dynamic_policy =
typename OscPolicy::dynamic_policy;
31 void operator()(T v)
const noexcept
35 = pattern_size(address_pattern.size()) + 8 + oscpack::RoundUp4(
sizeof(v));
36 char* buffer = (
char*)alloca(sz);
37 std::size_t i = write_string(address_pattern, buffer);
39 i += static_policy{parameter.get_unit()}(buffer + i, v);
43 catch(
const std::exception& e)
45 ossia::logger().error(
"osc_value_send_visitor: {}", e.what());
49 ossia::logger().error(
"osc_value_send_visitor: unknown error");
52 void operator()(ossia::impulse v)
const noexcept
56 = pattern_size(address_pattern.size()) + 8 + oscpack::RoundUp4(
sizeof(v));
57 char* buffer = (
char*)alloca(sz);
58 std::size_t i = write_string(address_pattern, buffer);
60 if(
auto ep = ossia::net::get_extended_type(parameter))
61 i += static_policy{parameter.get_unit()}(buffer + i, v, *ep);
63 i += static_policy{parameter.get_unit()}(buffer + i, v);
67 catch(
const std::exception& e)
69 ossia::logger().error(
"osc_value_send_visitor: {}", e.what());
73 ossia::logger().error(
"osc_value_send_visitor: unknown error");
76 void operator()(
const std::string& v)
const noexcept
80 = pattern_size(address_pattern.size()) + 4 + pattern_size(v.size());
83 char* buffer = (
char*)alloca(sz);
84 std::size_t i = write_string(address_pattern, buffer);
86 if(is_blob(parameter))
87 i += static_policy{parameter.get_unit()}(
88 buffer + i, oscpack::Blob(v.data(), v.size()));
90 i += static_policy{parameter.get_unit()}(buffer + i, v);
96 auto& pool = buffer_pool::instance();
97 auto buffer = pool.acquire();
99 std::size_t i = write_string(address_pattern, buffer.data());
101 if(is_blob(parameter))
102 i += static_policy{parameter.get_unit()}(
103 buffer.data() + i, oscpack::Blob(v.data(), v.size()));
105 i += static_policy{parameter.get_unit()}(buffer.data() + i, v);
107 writer(buffer.data(), i);
110 catch(
const std::exception& e)
112 ossia::logger().error(
"osc_value_send_visitor: {}", e.what());
116 ossia::logger().error(
"osc_value_send_visitor: unknown error");
119 void operator()(
const std::vector<ossia::value>& v)
const noexcept
122 auto& pool = buffer_pool::instance();
123 auto buf = pool.acquire();
124 while(buf.size() < max_osc_message_size)
128 oscpack::OutboundPacketStream p{buf.data(), buf.size()};
130 p << oscpack::BeginMessageN(address_pattern);
133 if(
auto ep = ossia::net::get_extended_type(parameter))
134 ok = process_extended_array(*ep, p, v);
136 dynamic_policy{{p, parameter.get_unit()}}(v);
137 p << oscpack::EndMessage();
139 writer(p.Data(), p.Size());
146 buf.resize(n * 2 + 1);
150 pool.release(std::move(buf));
152 catch(
const std::exception& e)
154 ossia::logger().error(
"osc_value_send_visitor: {}", e.what());
158 ossia::logger().error(
"osc_value_send_visitor: unknown error");
161 void operator()(
const value_map_type& v)
const noexcept { }
162 void operator()() { }
164 bool process_extended_array(
166 const std::vector<ossia::value>& v)
const
173 data +=
static_cast<unsigned char>(ossia::convert<int>(val));
176 oscpack::Blob b(data.data(), data.size());
184template <
typename Parameter,
typename OscPolicy>
185struct osc_value_write_visitor
187 const Parameter& parameter;
188 std::string_view address_pattern;
189 ossia::buffer_pool::buffer& result;
191 using static_policy =
typename OscPolicy::static_policy;
192 using dynamic_policy =
typename OscPolicy::dynamic_policy;
194 template <
typename T>
195 void operator()(T v)
const noexcept
198 = pattern_size(address_pattern.size()) + 8 + oscpack::RoundUp4(
sizeof(v));
200 std::size_t i = write_string(address_pattern, result.data());
202 i += static_policy{parameter.get_unit()}(result.data() + i, v);
207 void operator()(
const std::string& v)
const noexcept
210 = pattern_size(address_pattern.size()) + 4 + pattern_size(v.size());
212 std::size_t i = write_string(address_pattern, result.data());
214 if(is_blob(parameter))
215 i += static_policy{parameter.get_unit()}(
216 result.data() + i, oscpack::Blob(v.data(), v.size()));
218 i += static_policy{parameter.get_unit()}(result.data() + i, v);
223 void operator()(
const std::vector<ossia::value>& v)
const noexcept
226 while(result.size() < max_osc_message_size)
230 oscpack::OutboundPacketStream p{result.data(), result.size()};
232 p << oscpack::BeginMessageN(address_pattern);
233 dynamic_policy{{p, parameter.get_unit()}}(v);
234 p << oscpack::EndMessage();
236 result.resize(p.Size());
241 auto n = result.size();
243 result.resize(n * 2 + 1);
248 void operator()(
const value_map_type& v)
const noexcept { }
250 void operator()() { }
spdlog::logger & logger() noexcept
Where the errors will be logged. Default is stderr.
Definition context.cpp:118
std::string extended_type
How a low-level type should be interpreted.
Definition complex_type.hpp:9
extended_type u8_blob_type()
Definition extended_types.cpp:43