3#include <ossia/detail/apply.hpp>
5#include <ossia/network/base/parameter.hpp>
7#include <ossia/network/value/value_algorithms.hpp>
28 const auto first = lhs.get_type();
29 const auto second = rhs.get_type();
38 const ossia::destination& existing_dest;
39 const ossia::destination& incoming_dest;
41 template <
typename T,
typename U>
49 template <
typename T,
typename U>
58 template <std::
size_t N>
59 auto make_piecewise_from_floats(
float orig,
float incoming)
const
61 piecewise_vec_message<N> mess{existing_dest.value, {}, incoming_dest.unit, {}};
63 auto& existing_index = existing_dest.index;
64 if(existing_index[0] < (int64_t)N)
66 mess.message_value[existing_index[0]] = orig;
67 mess.used_values.set(existing_index[0]);
70 auto& incoming_index = incoming_dest.index;
71 if(incoming_index[0] < (int64_t)N)
73 mess.message_value[incoming_index[0]] = incoming;
74 mess.used_values.set(incoming_index[0]);
81 auto& existing_index = existing_dest.index;
82 auto& incoming_index = incoming_dest.index;
84 if(!existing_index.empty() && !incoming_index.empty()
85 && existing_index != incoming_index)
88 if(incoming_dest.unit)
91 type = existing_dest.address().get_value_type();
96 return make_piecewise_from_floats<2>(orig, incoming);
98 return make_piecewise_from_floats<3>(orig, incoming);
100 return make_piecewise_from_floats<4>(orig, incoming);
109 template <std::
size_t N>
112 return vec_merger{incoming_dest, existing_dest}(incoming, orig);
115 template <std::
size_t N>
118 auto& existing_index = existing_dest.index;
119 auto& incoming_index = incoming_dest.index;
120 if(incoming_index.empty())
126 auto i = incoming_index[0];
130 if(existing_index != incoming_index && !existing_index.empty())
135 piecewise_vec_message<N> mess{existing_dest.value, orig, incoming_dest.unit, {}};
136 mess.used_values.set(existing_index[0]);
137 mess.used_values.set(i);
147 template <std::
size_t N>
149 operator()(std::array<float, N>& orig,
const std::array<float, N>& incoming)
const
151 auto& existing_index = existing_dest.index;
152 auto& incoming_index = incoming_dest.index;
153 if(incoming_index.empty())
160 auto i = incoming_index[0];
162 orig[i] = incoming[i];
164 if(existing_index != incoming_index && !existing_index.empty())
169 piecewise_vec_message<N> mess{existing_dest.value, orig, incoming_dest.unit, {}};
170 mess.used_values.set(existing_index[0]);
171 mess.used_values.set(i);
181 template <std::
size_t N>
183 operator()(std::array<float, N>& orig,
const std::vector<ossia::value>& incoming)
const
185 auto& existing_index = existing_dest.index;
186 auto& incoming_index = incoming_dest.index;
187 if(incoming_index.empty())
189 value_merger<true>::merge_list(orig, incoming);
194 auto i = incoming_index[0];
197 value_merger<true>::write_float(incoming[i], orig[i]);
200 if(existing_index != incoming_index && !existing_index.empty())
205 piecewise_vec_message<N> mess{existing_dest.value, orig, incoming_dest.unit, {}};
206 mess.used_values.set(existing_index[0]);
207 mess.used_values.set(i);
218template <
typename State_T,
typename ExistingIt,
bool MergeSingleValues>
219struct state_flatten_visitor_merger
222 ExistingIt existing_it;
226 void operator()(message& existing,
const message& incoming)
228 auto to_append_index_empty = incoming.dest.index.empty();
229 auto source_index_empty = existing.dest.index.empty();
230 if(incoming.message_value.valid()
231 && (same_vec_type(existing.message_value, incoming.message_value)
232 || is_vec(existing.dest.address().get_value_type())))
238 auto res = ossia::apply(
239 vec_merger{existing.dest, incoming.dest}, existing.message_value.v,
240 incoming.message_value.v);
244 state.remove(existing_it);
248 else if(to_append_index_empty && source_index_empty)
250 if(MergeSingleValues)
253 value_merger<true>::merge_value(existing.message_value, incoming.message_value);
263 piecewise_message pw{incoming.dest.value, {}, incoming.dest.unit};
264 if(!to_append_index_empty && !source_index_empty)
267 value_merger<true>::insert_in_list(
268 pw.message_value, existing.message_value, existing.dest.index);
269 value_merger<true>::insert_in_list(
270 pw.message_value, incoming.message_value, incoming.dest.index);
274 else if(!to_append_index_empty)
276 pw.message_value.push_back(existing.message_value);
277 value_merger<true>::insert_in_list(
278 pw.message_value, incoming.message_value, incoming.dest.index);
280 else if(!source_index_empty)
282 value_merger<true>::insert_in_list(
283 pw.message_value, existing.message_value, existing.dest.index);
284 value_merger<true>::set_first_value(pw.message_value, incoming.message_value);
286 state.remove(existing_it);
287 state.add(std::move(pw));
291 void operator()(piecewise_message& existing,
const message& incoming)
293 if(incoming.dest.index.empty())
296 value_merger<true>::set_first_value(
297 existing.message_value, incoming.message_value);
302 value_merger<true>::insert_in_list(
303 existing.message_value, incoming.message_value, incoming.dest.index);
307 template <std::
size_t N>
308 void operator()(piecewise_vec_message<N>& existing,
const message& incoming)
310 auto t = incoming.message_value.get_type();
311 using vec_type =
decltype(existing.message_value);
315 case ossia::val_type::FLOAT: {
316 if(!incoming.dest.index.empty())
318 auto i = incoming.dest.index[0];
321 existing.message_value[i] = incoming.message_value.get<
float>();
322 existing.used_values.set(i);
328 case ossia::value_trait<vec_type>::ossia_enum: {
330 if(!incoming.dest.index.empty())
332 auto i = incoming.dest.index[0];
335 auto& inc = incoming.message_value.get<vec_type>();
336 existing.message_value[i] = inc[i];
337 existing.used_values.set(i);
343 existing.message_value = incoming.message_value.get<vec_type>();
353 void operator()(message& existing,
const piecewise_message& incoming)
355 piecewise_message other = incoming;
361 if(existing.dest.index.empty())
364 value_merger<false>::set_first_value(other.message_value, existing.message_value);
369 value_merger<false>::insert_in_list(
370 other.message_value, existing.message_value, existing.dest.index);
373 state.remove(existing_it);
374 state.remove(incoming);
375 state.add(std::move(other));
378 void operator()(piecewise_message& existing,
const piecewise_message& incoming)
381 value_merger<true>::merge_list(existing.message_value, incoming.message_value);
385 template <std::
size_t N>
387 piecewise_vec_message<N>& existing,
const piecewise_vec_message<N>& incoming)
389 for(std::size_t i = 0; i < N; i++)
391 if(incoming.used_values.test(i))
393 existing.message_value[i] = incoming.message_value[i];
394 existing.used_values.set(i);
401 void operator()(message& existing, message&& incoming)
408 auto to_append_index_empty = incoming.dest.index.empty();
409 auto source_index_empty = existing.dest.index.empty();
410 if(incoming.message_value.valid()
411 && (same_vec_type(existing.message_value, incoming.message_value)
412 || is_vec(existing.dest.address().get_value_type())))
418 auto res = ossia::apply(
419 vec_merger{existing.dest, incoming.dest}, existing.message_value.v,
420 incoming.message_value.v);
424 state.remove(existing_it);
425 state.add(std::move(res));
428 else if(to_append_index_empty && source_index_empty)
431 if(MergeSingleValues)
433 value_merger<true>::merge_value(
434 existing.message_value, std::move(incoming.message_value));
438 state.add(std::move(incoming));
443 piecewise_message pw{incoming.dest.value, {}, incoming.dest.unit};
444 if(!to_append_index_empty && !source_index_empty)
447 value_merger<true>::insert_in_list(
448 pw.message_value, existing.message_value, existing.dest.index);
449 value_merger<true>::insert_in_list(
450 pw.message_value, std::move(incoming.message_value), incoming.dest.index);
454 else if(!to_append_index_empty)
456 pw.message_value.push_back(existing.message_value);
457 value_merger<true>::insert_in_list(
458 pw.message_value, std::move(incoming.message_value), incoming.dest.index);
460 else if(!source_index_empty)
462 value_merger<true>::insert_in_list(
463 pw.message_value, existing.message_value, existing.dest.index);
464 value_merger<true>::set_first_value(
465 pw.message_value, std::move(incoming.message_value));
468 state.remove(existing_it);
469 state.add(std::move(pw));
472 void operator()(piecewise_message& existing, message&& incoming)
474 if(incoming.dest.index.empty())
477 value_merger<true>::set_first_value(
478 existing.message_value, std::move(incoming.message_value));
483 value_merger<true>::insert_in_list(
484 existing.message_value, std::move(incoming.message_value),
485 incoming.dest.index);
490 void operator()(message& existing, piecewise_message&& incoming)
492 piecewise_message other = incoming;
498 if(existing.dest.index.empty())
501 value_merger<false>::set_first_value(other.message_value, existing.message_value);
506 value_merger<false>::insert_in_list(
507 other.message_value, existing.message_value, existing.dest.index);
510 state.remove(existing_it);
511 state.remove(incoming);
512 state.add(std::move(other));
515 void operator()(piecewise_message& existing, piecewise_message&& incoming)
518 value_merger<true>::merge_list(
519 existing.message_value, std::move(incoming.message_value));
526 template <
typename T>
531 "state_flatten_visitor_merger: "
532 "impossible case (state <- *");
535 template <std::
size_t M>
536 void operator()(message& existing,
const piecewise_vec_message<M>& incoming)
540 "state_flatten_visitor_merger: "
541 "impossible case (message <- const piecewise_vec_message&");
544 template <std::
size_t M>
545 void operator()(piecewise_message& existing,
const piecewise_vec_message<M>& incoming)
549 "state_flatten_visitor_merger: "
550 "impossible case (piecewise_message <- const piecewise_vec_message&");
553 template <std::
size_t N>
554 void operator()(piecewise_vec_message<N>& existing,
const piecewise_message& incoming)
558 "state_flatten_visitor_merger: "
559 "impossible case (piecewise_vec_message <- const piecewise_message&");
561 template <std::
size_t N>
562 void operator()(piecewise_vec_message<N>& existing, piecewise_message&& incoming)
566 "state_flatten_visitor_merger: "
567 "impossible case (piecewise_vec_message <- piecewise_message&&");
570 template <std::
size_t N, std::
size_t M>
572 piecewise_vec_message<N>& existing,
const piecewise_vec_message<M>& incoming)
576 "state_flatten_visitor_merger: "
577 "impossible case (piecewise_vec_message<N> <- "
578 "piecewise_vec_message<M>");
583struct state_flatten_impl_same_address
587 template <
typename U>
588 bool operator()(
const U& m)
590 return incoming.get_unit() == m.get_unit();
592 bool operator()(
const ossia::state& t) {
return false; }
593 bool operator()(
const ossia::monostate& t) {
return false; }
597struct state_flatten_impl_different_address
604 return &m.dest.value.get() == address && incoming.get_unit() == m.get_unit();
607 bool operator()(
const ossia::piecewise_message& m)
609 return &m.address.get() == address && incoming.get_unit() == m.get_unit();
611 template <std::
size_t N>
612 bool operator()(
const ossia::piecewise_vec_message<N>& m)
614 return &m.address.get() == address && incoming.get_unit() == m.get_unit();
616 bool operator()(
const ossia::state& t) {
return false; }
617 bool operator()(
const ossia::monostate& t) {
return false; }
620template <
typename State_T,
bool MergeSingleValues,
bool AssumeSameAddresses = false>
621struct state_flatten_visitor
627 return &m.dest.
value.get();
632 return &m.address.get();
635 template <std::
size_t N>
638 return &m.address.get();
642 template <
typename T>
643 static auto find_same_param(
ossia::state& st,
const T& incoming)
645 if constexpr(AssumeSameAddresses)
647 state_flatten_impl_same_address<T> vis{incoming};
648 return find_if(st, [&](
const state_element& e) {
return ossia::visit(vis, e); });
652 state_flatten_impl_different_address<T> vis{incoming, param_ptr(incoming)};
653 return find_if(st, [&](
const state_element& e) {
return ossia::visit(vis, e); });
657 template <
typename State,
typename T>
658 static auto find_same_param(State& st,
const T& incoming)
660 return st.find(incoming);
664 template <
typename Message_T>
665 void operator()(Message_T&& incoming)
668 auto it = find_same_param(state, incoming);
669 if(it == state.end())
671 state.add(std::forward<Message_T>(incoming));
676 state_flatten_visitor_merger<
677 State_T, std::remove_reference_t<
decltype(it)>, MergeSingleValues>
682 using type = std::decay_t<
decltype(u)>;
683 if constexpr(!std::is_same_v<ossia::monostate, type>)
684 merger(u, std::forward<Message_T>(incoming));
686 get_state_element(it));
692 state.reserve(state.size() + s.size());
693 for(
const auto& e : s)
695 ossia::apply(*
this, e);
701 state.reserve(state.size() + s.size());
704 ossia::apply(*
this, std::move(e));
708 void operator()(
const ossia::monostate&) { }
709 void operator()(ossia::monostate&&) { }
711 void operator()() { }
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
virtual ossia::value value() const =0
Clone the current value without any network request.
The state class.
Definition editor/state/state.hpp:25
The value class.
Definition value.hpp:173
val_type
Enum to represent the types that a value can take.
Definition parameter_properties.hpp:16
val_type matching_type(const unit_t &u)
underlying_type Get the implementation type of an unit
Definition dataspace_visitors.cpp:198
ossia::nullable_variant< message, state, piecewise_message, piecewise_vec_message< 2 >, piecewise_vec_message< 3 >, piecewise_vec_message< 4 > > state_element
Definition state_element_fwd.hpp:28
The message struct.
Definition message.hpp:29