1616#include < ossia/dataflow/graph_node.hpp>
1717#include < ossia/dataflow/port.hpp>
1818#include < ossia/detail/math.hpp>
19+ #include < ossia/detail/parse_relax.hpp>
1920#include < ossia/editor/curve/curve_segment/easing.hpp>
2021#include < ossia/network/value/format_value.hpp>
2122
2223namespace oscr
2324{
24- template <typename Field, std::size_t Idx>
25- inline void update_value (
26- auto & node, auto & obj, Field& field, const ossia::value& src, auto & dst,
27- avnd::field_index<Idx> idx)
25+
26+ // If we have a polyphonic object
27+ // And we get an array input that corresponds to the kind of data expected
28+ // Then we apply the value element-wise to each monophonic instance
29+ //
30+ // To do this we must make sure that we always create as many "input" objects as needed
31+ template <typename Value>
32+ requires std::is_arithmetic_v<Value>
33+ struct apply_value_polyphonic_control
2834{
29- if (node.from_ossia_value (field, src, dst, idx))
35+ Value& res;
36+ int instance;
37+ bool operator ()() const { return false ; }
38+ bool operator ()(ossia::impulse) const
3039 {
31- if_possible (field.update (obj));
40+ if_possible (res = {});
41+ return true ;
3242 }
33- }
43+
44+ bool operator ()(float v) const
45+ {
46+ res = v;
47+ return true ;
48+ }
49+
50+ bool operator ()(int v) const
51+ {
52+ res = v;
53+ return true ;
54+ }
55+
56+ bool operator ()(bool v) const
57+ {
58+ res = v ? 1 . : 0 .;
59+ return true ;
60+ }
61+
62+ bool operator ()(const std::string& v) const
63+ {
64+ if (auto f = ossia::parse_relax<double >(v))
65+ {
66+ res = *f;
67+ return true ;
68+ }
69+ return false ;
70+ }
71+
72+ template <std::size_t N>
73+ bool operator ()(const std::array<float , N>& v) const
74+ {
75+ if (instance >= 0 && instance < N)
76+ {
77+ res = v[instance];
78+ return true ;
79+ }
80+ return false ;
81+ }
82+ bool operator ()(const std::vector<ossia::value>& v) const
83+ {
84+ if (instance >= 0 && instance < v.size ())
85+ {
86+ res = ossia::convert<float >(v[instance]);
87+ return true ;
88+ }
89+ return false ;
90+ }
91+ bool operator ()(const ossia::value_map_type& v) const { return false ; }
92+ };
3493
3594template <typename Exec_T, typename Obj_T>
3695struct process_before_run
3796{
3897 Exec_T& self;
3998 Obj_T& impl;
99+ int instance{};
40100 int start{};
41101 int frames{};
42102
103+ template <typename Field, typename Value, std::size_t Idx>
104+ OSSIA_INLINE void update_value (
105+ Field& field, const ossia::value& src, Value& dst,
106+ avnd::field_index<Idx> idx) const
107+ {
108+ // TODO
109+ // if constexpr(oscr::real_good_mono_processor<Obj>)
110+ if (self.from_ossia_value (field, src, dst, idx))
111+ {
112+ if_possible (field.update (impl));
113+ }
114+ }
115+
116+ // Some heads up for the most common cases, + handle mono deconstruction
117+ template <typename Field, typename Value, std::size_t Idx>
118+ requires std::is_arithmetic_v<Value>
119+ OSSIA_INLINE void update_value (
120+ Field& field, const ossia::value& src, Value& dst,
121+ avnd::field_index<Idx> idx) const
122+ {
123+ // FIXME time controls & smooth
124+ using eff_t = avnd::effect_container<Obj_T>;
125+ static constexpr bool multi_instance = requires { sizeof (eff_t ::multi_instance); };
126+ if constexpr (
127+ multi_instance && !avnd::smooth_parameter<Field> && !avnd::time_control<Field>)
128+ {
129+ if (src.apply (apply_value_polyphonic_control<Value>{dst, instance}))
130+ {
131+ if_possible (field.update (impl));
132+ }
133+ }
134+ else
135+ {
136+ if (self.from_ossia_value (field, src, dst, idx))
137+ {
138+ if_possible (field.update (impl));
139+ }
140+ }
141+ }
43142 template <avnd::parameter Field, std::size_t Idx>
44143 requires ossia_port<Field>
45144 void init_value (Field& ctrl, auto & port, avnd::field_index<Idx> idx) const noexcept
@@ -60,7 +159,7 @@ struct process_before_run
60159 if (!port.data .get_data ().empty ())
61160 {
62161 auto & last = port.data .get_data ().back ().value ;
63- update_value (self, impl, ctrl, last, ctrl.value , idx);
162+ update_value (ctrl, last, ctrl.value , idx);
64163
65164 if constexpr (avnd::control<Field>)
66165 {
@@ -169,8 +268,7 @@ struct process_before_run
169268 {
170269 if (ts >= start && ts < start + frames)
171270 {
172- update_value (
173- self, impl, ctrl, val, ctrl.values [ts - start], avnd::field_index<Idx>{});
271+ update_value (ctrl, val, ctrl.values [ts - start], avnd::field_index<Idx>{});
174272 }
175273 }
176274 }
0 commit comments