2#include <ossia/detail/buffer_pool.hpp>
4#include <ossia/network/base/bundle.hpp>
5#include <ossia/network/base/osc_address.hpp>
6#include <ossia/network/osc/detail/osc_1_0_policy.hpp>
7#include <ossia/network/osc/detail/osc_messages.hpp>
8#include <ossia/network/value/value.hpp>
10#include <oscpack/osc/OscOutboundPacketStream.h>
18template <
typename OscPolicy>
19struct bundle_common_policy
21 template <
typename Addr_T>
23 operator()(oscpack::OutboundPacketStream& str,
ossia::value& val,
const Addr_T& addr)
25 if(val = bound_value(addr, std::move(val)); val.valid())
27 str << oscpack::BeginMessageN(osc_address(addr));
28 val.apply(
typename OscPolicy::dynamic_policy{{str, addr.get_unit()}});
29 str << oscpack::EndMessage();
34template <
typename OscPolicy>
35struct bundle_client_policy
37 template <
typename Addr_T>
39 operator()(oscpack::OutboundPacketStream& str,
ossia::value& val,
const Addr_T& addr)
44 bundle_common_policy<OscPolicy>{}(str, val, addr);
48template <
typename OscPolicy>
49using bundle_server_policy = bundle_common_policy<OscPolicy>;
52template <
typename OscPolicy>
53struct bundle_bounded_common_policy
55 template <
typename Addr_T>
57 operator()(oscpack::OutboundPacketStream& str,
ossia::value& val,
const Addr_T& addr)
61 str << oscpack::BeginMessageN(osc_address(addr));
62 val.apply(
typename OscPolicy::dynamic_policy{{str, addr.get_unit()}});
63 str << oscpack::EndMessage();
68template <
typename OscPolicy>
69struct bundle_bounded_client_policy
71 template <
typename Addr_T>
73 operator()(oscpack::OutboundPacketStream& str,
ossia::value& val,
const Addr_T& addr)
78 bundle_bounded_common_policy<OscPolicy>{}(str, val, addr);
82template <
typename OscPolicy>
83using bundle_bounded_server_policy = bundle_bounded_common_policy<OscPolicy>;
93static inline auto& access_parameter(
const ossia::bundle_element& p)
100 ossia::buffer_pool::buffer data;
104template <
typename NetworkPolicy,
typename Addresses>
106make_bundle(NetworkPolicy add_element_to_bundle,
const Addresses& addresses)
109 bundle ret{ossia::buffer_pool::instance().acquire(max_osc_message_size),
false};
111 oscpack::OutboundPacketStream str(ret.data.data(), max_osc_message_size);
112 str << oscpack::BeginBundleImmediate();
115 for(
const auto& a : addresses)
117 auto& param = access_parameter(a);
118 ret.critical |= param.get_critical();
120 if constexpr(
requires {
121 { a.value } -> std::same_as<ossia::value>;
123 add_element_to_bundle(str, val = a.value, param);
125 add_element_to_bundle(str, val = param.value(), param);
127 str << oscpack::EndBundle();
128 ret.data.resize(str.Size());
136catch(
const oscpack::OutOfBufferMemoryException&)
139 "make_bundle_client: message too large (limit is {} bytes)", max_osc_message_size);
142catch(
const std::runtime_error& e)
153template <
typename NetworkPolicy>
154std::optional<bundle> make_bundle(
160 ossia::buffer_pool::instance().acquire(max_osc_message_size), param.critical};
162 oscpack::OutboundPacketStream str(ret.data.data(), max_osc_message_size);
163 str << oscpack::BeginBundleImmediate();
164 add_element_to_bundle(str, val = param.value(), param);
165 str << oscpack::EndBundle();
166 ret.data.resize(str.Size());
174catch(
const oscpack::OutOfBufferMemoryException&)
177 "make_bundle_client: message too large (limit is {} bytes)", max_osc_message_size);
180catch(
const std::runtime_error& e)
191template <
typename NetworkPolicy>
192std::optional<bundle> make_bundle(
198 ossia::buffer_pool::instance().acquire(max_osc_message_size),
199 param.get_critical()};
201 oscpack::OutboundPacketStream str(ret.data.data(), max_osc_message_size);
202 str << oscpack::BeginBundleImmediate();
203 add_element_to_bundle(str, v, param);
204 str << oscpack::EndBundle();
205 ret.data.resize(str.Size());
213catch(
const oscpack::OutOfBufferMemoryException&)
216 "make_bundle_client: message too large (limit is {} bytes)", max_osc_message_size);
219catch(
const std::runtime_error& e)
230template <
typename NetworkPolicy>
231std::optional<bundle> make_bundle(
232 NetworkPolicy add_element_to_bundle,
233 const std::span<ossia::bundle_element>& addresses)
236 bundle ret{ossia::buffer_pool::instance().acquire(max_osc_message_size),
false};
238 oscpack::OutboundPacketStream str(ret.data.data(), max_osc_message_size);
239 str << oscpack::BeginBundleImmediate();
241 for(
auto& [p, v] : addresses)
244 ret.critical |= param.get_critical();
245 add_element_to_bundle(str, v, param);
247 str << oscpack::EndBundle();
248 ret.data.resize(str.Size());
256catch(
const oscpack::OutOfBufferMemoryException&)
259 "make_bundle_client: message too large (limit is {} bytes)", max_osc_message_size);
262catch(
const std::runtime_error& e)
273template <
typename NetworkPolicy>
274bool make_bundle_bounded(
275 NetworkPolicy add_element_to_bundle,
276 const std::span<ossia::bundle_element>& addresses,
auto callback)
278 bundle ret{ossia::buffer_pool::instance().acquire(max_osc_message_size),
false};
282 oscpack::OutboundPacketStream str(ret.data.data(), max_osc_message_size);
283 str << oscpack::BeginBundleImmediate();
285 for(
auto& [p, v] : addresses)
288 ret.critical |= param.get_critical();
289 add_element_to_bundle(str, v, param);
291 str << oscpack::EndBundle();
292 ret.data.resize(str.Size());
300 catch(
const oscpack::OutOfBufferMemoryException&)
303 "make_bundle_client: message too large (limit is {} bytes)",
304 max_osc_message_size);
306 catch(
const std::runtime_error& e)
314 ossia::buffer_pool::instance().release(std::move(ret.data));
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
The value class.
Definition value.hpp:173
spdlog::logger & logger() noexcept
Where the errors will be logged. Default is stderr.
Definition context.cpp:118
@ 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
Full information about a parameter.
Definition parameter_data.hpp:61