2 #include <Fx/MathHelpers.hpp>
3 #include <Fx/Types.hpp>
5 #include <ossia/dataflow/value_port.hpp>
7 #include <halp/callback.hpp>
10 template <
typename State>
13 static void store_output(
auto&
self,
const ossia::value& v)
17 case ossia::val_type::NONE:
19 case ossia::val_type::FLOAT:
20 self.po = *v.target<
float>();
22 case ossia::val_type::VEC2F: {
23 if constexpr(requires {
self.pov; })
25 auto& vec = *v.target<ossia::vec2f>();
26 self.pov.assign(vec.begin(), vec.end());
30 case ossia::val_type::VEC3F: {
31 if constexpr(requires {
self.pov; })
33 auto& vec = *v.target<ossia::vec3f>();
34 self.pov.assign(vec.begin(), vec.end());
38 case ossia::val_type::VEC4F: {
39 if constexpr(requires {
self.pov; })
41 auto& vec = *v.target<ossia::vec4f>();
42 self.pov.assign(vec.begin(), vec.end());
46 case ossia::val_type::LIST: {
47 if constexpr(requires {
self.pov; })
49 auto& arr = *v.target<std::vector<ossia::value>>();
54 self.pov.push_back(ossia::convert<float>(v));
65 static void exec_scalar(
State&
self, value_output_callback& output)
67 auto res =
self.expr.result();
70 store_output(
self, res);
75 static void exec_polyphonic(
State&
self, value_output_callback& output)
77 for(
auto& e :
self.expressions)
79 auto res = e.expr.result();
81 if constexpr(requires { e.x; })
89 exec_array(
State&
self, value_output_callback& output,
bool vector_size_did_change)
94 if(vector_size_did_change)
96 self.expr.remove_vector(
"xv");
97 self.expr.add_vector(
"xv",
self.xv);
98 self.expr.recompile();
101 auto res =
self.expr.result();
102 store_output(
self, res);
106 bool old_prev =
self.pxv.size();
107 self.pxv.assign(
self.xv.begin(),
self.xv.end());
108 bool new_prev =
self.pxv.size();
110 if(old_prev != new_prev)
112 self.expr.remove_vector(
"pxv");
113 self.expr.add_vector(
"pxv",
self.pxv);
114 self.expr.recompile();
118 output(std::move(res));
121 static void run_scalar(
122 const ossia::value& v, value_output_callback& output,
const halp::tick_flicks& tk,
137 case ossia::val_type::NONE:
139 case ossia::val_type::IMPULSE:
141 case ossia::val_type::INT:
142 self.x = *v.target<
int>();
144 case ossia::val_type::FLOAT:
145 self.x = *v.target<
float>();
147 case ossia::val_type::BOOL:
148 self.x = *v.target<
bool>() ? 1.f : 0.f;
150 case ossia::val_type::STRING:
151 self.x = ossia::convert<float>(v);
153 case ossia::val_type::VEC2F:
154 self.x = (*v.target<ossia::vec2f>())[0];
156 case ossia::val_type::VEC3F:
157 self.x = (*v.target<ossia::vec3f>())[0];
159 case ossia::val_type::VEC4F:
160 self.x = (*v.target<ossia::vec4f>())[0];
162 case ossia::val_type::LIST: {
163 auto& arr = *v.target<std::vector<ossia::value>>();
165 self.x = ossia::convert<float>(arr[0]);
168 case ossia::val_type::MAP: {
169 auto& arr = *v.target<ossia::value_map_type>();
171 self.x = ossia::convert<float>(arr.begin()->second);
176 GenericMathMapping::exec_scalar(
self, output);
179 static bool resize(
const std::string& expr,
State&
self,
int sz)
181 if(std::ssize(
self.expressions) == sz && expr ==
self.last_expression)
184 self.expressions.resize(sz);
186 for(
auto& e :
self.expressions)
188 e.init(
self.cur_time,
self.cur_deltatime,
self.cur_pos);
190 if(!e.expr.set_expression(expr))
193 UINT64_C(0xda3e39cb94b95bdb), UINT64_C(0x853c49e6748fea9b) * (1 + i));
195 self.last_expression = expr;
199 static void run_polyphonic(
200 int size, value_output_callback& output,
const std::string& expr,
201 const halp::tick_flicks& tk,
State&
self)
203 resize(expr,
self, size);
205 setMathExpressionTiming(
206 self, tk.start_in_flicks,
self.last_value_time, tk.relative_position);
207 self.last_value_time = tk.start_in_flicks;
209 GenericMathMapping::exec_polyphonic(
self, output);
211 std::vector<ossia::value> res;
212 res.resize(
self.expressions.size());
213 for(
int i = 0; i <
self.expressions.size(); i++)
214 res[i] = (
float)
self.expressions[i].po;
217 output(std::move(res));
220 static void run_polyphonic(
221 const ossia::value& value, value_output_callback& output,
const std::string& expr,
222 const halp::tick_flicks& tk,
State&
self)
224 setMathExpressionTiming(
225 self, tk.start_in_flicks,
self.last_value_time, tk.relative_position);
226 self.last_value_time = tk.start_in_flicks;
239 switch(value.get_type())
241 case ossia::val_type::NONE:
243 case ossia::val_type::IMPULSE:
245 case ossia::val_type::INT:
246 if(!resize(expr,
self, 1))
248 self.expressions[0].x = *value.target<
int>();
250 case ossia::val_type::FLOAT:
251 if(!resize(expr,
self, 1))
253 self.expressions[0].x = *value.target<
float>();
255 case ossia::val_type::BOOL:
256 if(!resize(expr,
self, 1))
258 self.expressions[0].x = *value.target<
bool>() ? 1.f : 0.f;
260 case ossia::val_type::STRING:
261 if(!resize(expr,
self, 1))
263 self.expressions[0].x = ossia::convert<float>(value);
265 case ossia::val_type::VEC2F:
266 if(!resize(expr,
self, 2))
268 self.expressions[0].x = (*value.target<ossia::vec2f>())[0];
269 self.expressions[1].x = (*value.target<ossia::vec2f>())[1];
271 case ossia::val_type::VEC3F:
272 if(!resize(expr,
self, 3))
274 self.expressions[0].x = (*value.target<ossia::vec3f>())[0];
275 self.expressions[1].x = (*value.target<ossia::vec3f>())[1];
276 self.expressions[2].x = (*value.target<ossia::vec3f>())[2];
278 case ossia::val_type::VEC4F:
279 if(!resize(expr,
self, 4))
281 self.expressions[0].x = (*value.target<ossia::vec4f>())[0];
282 self.expressions[1].x = (*value.target<ossia::vec4f>())[1];
283 self.expressions[2].x = (*value.target<ossia::vec4f>())[2];
284 self.expressions[3].x = (*value.target<ossia::vec4f>())[3];
286 case ossia::val_type::LIST: {
287 auto& arr = *value.target<std::vector<ossia::value>>();
288 const auto N = std::ssize(arr);
289 if(!resize(expr,
self, N))
291 for(
int i = 0; i < N; i++)
292 self.expressions[i].x = ossia::convert<float>(arr[i]);
295 case ossia::val_type::MAP: {
296 auto& arr = *value.target<ossia::value_map_type>();
297 const auto N = std::ssize(arr);
298 if(!resize(expr,
self, N))
301 for(
auto& [k, v] : arr)
302 self.expressions[i++].x = ossia::convert<float>(v);
307 GenericMathMapping::exec_polyphonic(
self, output);
309 std::vector<ossia::value> res;
310 res.resize(
self.expressions.size());
311 for(
int i = 0; i <
self.expressions.size(); i++)
312 res[i] = (
float)
self.expressions[i].po;
315 output(std::move(res));
318 static void run_array(
319 const ossia::value& value, value_output_callback& output,
320 const halp::tick_flicks& tk,
State&
self)
330 auto array_run_scalar = [&](
float in) {
331 auto old_size =
self.xv.size();
332 self.xv.assign(1, in);
334 GenericMathMapping::exec_array(
self, output, old_size != new_size);
337 switch(value.get_type())
339 case ossia::val_type::NONE:
341 case ossia::val_type::IMPULSE:
342 GenericMathMapping::exec_array(
self, output,
false);
344 case ossia::val_type::INT:
345 array_run_scalar(*value.target<
int>());
347 case ossia::val_type::FLOAT:
348 array_run_scalar(*value.target<
float>());
350 case ossia::val_type::BOOL:
351 array_run_scalar(*value.target<
bool>() ? 1.f : 0.f);
353 case ossia::val_type::STRING:
354 array_run_scalar(ossia::convert<float>(value));
356 case ossia::val_type::VEC2F: {
357 auto& arr = *value.target<ossia::vec2f>();
358 auto old_size =
self.xv.size();
359 self.xv.assign(arr.begin(), arr.end());
361 GenericMathMapping::exec_array(
self, output, old_size != new_size);
364 case ossia::val_type::VEC3F: {
365 auto& arr = *value.target<ossia::vec3f>();
366 auto old_size =
self.xv.size();
367 self.xv.assign(arr.begin(), arr.end());
369 GenericMathMapping::exec_array(
self, output, old_size != new_size);
372 case ossia::val_type::VEC4F: {
373 auto& arr = *value.target<ossia::vec4f>();
374 auto old_size =
self.xv.size();
375 self.xv.assign(arr.begin(), arr.end());
377 GenericMathMapping::exec_array(
self, output, old_size != new_size);
380 case ossia::val_type::LIST: {
381 auto& arr = *value.target<std::vector<ossia::value>>();
382 auto old_size =
self.xv.size();
383 self.xv.resize(arr.size());
384 auto new_size = arr.size();
385 for(std::size_t i = 0; i < arr.size(); i++)
387 self.xv[i] = ossia::convert<float>(arr[i]);
389 GenericMathMapping::exec_array(
self, output, old_size != new_size);
392 case ossia::val_type::MAP: {
393 auto& arr = *value.target<ossia::value_map_type>();
394 auto old_size =
self.xv.size();
395 self.xv.resize(arr.size());
396 auto new_size = arr.size();
398 for(
const auto& [k, v] : arr)
400 self.xv[i++] = ossia::convert<float>(v);
402 GenericMathMapping::exec_array(
self, output, old_size != new_size);
Utilities for OSSIA data structures.
Definition: DeviceInterface.hpp:33
Definition: MathMapping_generic.hpp:12