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>
17 template <
typename Parameter,
typename OscPolicy,
typename Writer>
18 #if __cpp_lib_concepts >= 201907L
19 requires std::is_invocable_v<Writer, const char*, std::size_t>
21 struct 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);
131 dynamic_policy{{p, parameter.get_unit()}}(v);
132 p << oscpack::EndMessage();
134 writer(p.Data(), p.Size());
141 buf.resize(n * 2 + 1);
145 pool.release(std::move(buf));
147 catch(
const std::exception& e)
149 ossia::logger().error(
"osc_value_send_visitor: {}", e.what());
153 ossia::logger().error(
"osc_value_send_visitor: unknown error");
156 void operator()(
const value_map_type& v)
const noexcept { }
158 void operator()() { }
161 template <
typename Parameter,
typename OscPolicy>
162 struct osc_value_write_visitor
164 const Parameter& parameter;
165 std::string_view address_pattern;
166 ossia::buffer_pool::buffer& result;
168 using static_policy =
typename OscPolicy::static_policy;
169 using dynamic_policy =
typename OscPolicy::dynamic_policy;
171 template <
typename T>
172 void operator()(T v)
const noexcept
175 = pattern_size(address_pattern.size()) + 8 + oscpack::RoundUp4(
sizeof(v));
177 std::size_t i = write_string(address_pattern, result.data());
179 i += static_policy{parameter.get_unit()}(result.data() + i, v);
184 void operator()(
const std::string& v)
const noexcept
187 = pattern_size(address_pattern.size()) + 4 + pattern_size(v.size());
189 std::size_t i = write_string(address_pattern, result.data());
191 if(is_blob(parameter))
192 i += static_policy{parameter.get_unit()}(
193 result.data() + i, oscpack::Blob(v.data(), v.size()));
195 i += static_policy{parameter.get_unit()}(result.data() + i, v);
200 void operator()(
const std::vector<ossia::value>& v)
const noexcept
203 while(result.size() < max_osc_message_size)
207 oscpack::OutboundPacketStream p{result.data(), result.size()};
209 p << oscpack::BeginMessageN(address_pattern);
210 dynamic_policy{{p, parameter.get_unit()}}(v);
211 p << oscpack::EndMessage();
213 result.resize(p.Size());
218 auto n = result.size();
220 result.resize(n * 2 + 1);
225 void operator()(
const value_map_type& v)
const noexcept { }
227 void operator()() { }
spdlog::logger & logger() noexcept
Where the errors will be logged. Default is stderr.
Definition: context.cpp:104