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.rebase_vector(
"xv", self.xv);
97 self.expr.recompile();
100 auto res = self.expr.result();
101 store_output(self, res);
105 bool old_prev = self.pxv.size();
106 self.pxv.assign(self.xv.begin(), self.xv.end());
107 bool new_prev = self.pxv.size();
109 if(old_prev != new_prev)
111 self.expr.rebase_vector(
"pxv", self.pxv);
112 self.expr.recompile();
116 output(std::move(res));
119 static void run_scalar(
120 const ossia::value& v, value_output_callback& output,
const halp::tick_flicks& tk,
135 case ossia::val_type::NONE:
137 case ossia::val_type::IMPULSE:
139 case ossia::val_type::INT:
140 self.x = *v.target<
int>();
142 case ossia::val_type::FLOAT:
143 self.x = *v.target<
float>();
145 case ossia::val_type::BOOL:
146 self.x = *v.target<
bool>() ? 1.f : 0.f;
148 case ossia::val_type::STRING:
149 self.x = ossia::convert<float>(v);
151 case ossia::val_type::VEC2F:
152 self.x = (*v.target<ossia::vec2f>())[0];
154 case ossia::val_type::VEC3F:
155 self.x = (*v.target<ossia::vec3f>())[0];
157 case ossia::val_type::VEC4F:
158 self.x = (*v.target<ossia::vec4f>())[0];
160 case ossia::val_type::LIST: {
161 auto& arr = *v.target<std::vector<ossia::value>>();
163 self.x = ossia::convert<float>(arr[0]);
166 case ossia::val_type::MAP: {
167 auto& arr = *v.target<ossia::value_map_type>();
169 self.x = ossia::convert<float>(arr.begin()->second);
174 GenericMathMapping::exec_scalar(self, output);
177 static bool resize(
const std::string& expr,
State& self,
int sz)
179 if(std::ssize(self.expressions) == sz && expr == self.last_expression)
182 self.expressions.resize(sz);
185 for(
auto& e : self.expressions)
187 e.init(self.cur_time, self.cur_deltatime, self.cur_pos, self.count);
189 if(!e.expr.set_expression(expr))
192 UINT64_C(0xda3e39cb94b95bdb), UINT64_C(0x853c49e6748fea9b) * (1 + i));
194 self.last_expression = expr;
198 static void run_polyphonic(
199 int size, value_output_callback& output,
const std::string& expr,
200 const halp::tick_flicks& tk,
State& self)
203 || (expr.find(
":=") != std::string::npos && expr.find(
"po") != std::string::npos))
205 size = std::clamp(size, 0, 1024);
206 resize(expr, self, size);
208 setMathExpressionTiming(
209 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
210 self.last_value_time = tk.start_in_flicks;
212 GenericMathMapping::exec_polyphonic(self, output);
214 std::vector<ossia::value> res;
215 res.resize(self.expressions.size());
217 for(
int i = 0; i < self.expressions.size(); i++)
218 res[i] = (
float)self.expressions[i].po;
220 output(std::move(res));
224 resize(expr, self, 1);
225 setMathExpressionTiming(
226 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
227 self.last_value_time = tk.start_in_flicks;
229 std::vector<ossia::value> res;
232 for(
int i = 0; i < size; i++)
234 auto& e = self.expressions[0];
236 res[i] = e.expr.result();
240 output(std::move(res));
244 static void run_polyphonic(
245 const ossia::value& value, value_output_callback& output,
const std::string& expr,
246 const halp::tick_flicks& tk,
State& self)
248 setMathExpressionTiming(
249 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
250 self.last_value_time = tk.start_in_flicks;
263 switch(value.get_type())
265 case ossia::val_type::NONE:
267 case ossia::val_type::IMPULSE:
269 case ossia::val_type::INT:
270 if(!resize(expr, self, 1))
272 self.expressions[0].x = *value.target<
int>();
274 case ossia::val_type::FLOAT:
275 if(!resize(expr, self, 1))
277 self.expressions[0].x = *value.target<
float>();
279 case ossia::val_type::BOOL:
280 if(!resize(expr, self, 1))
282 self.expressions[0].x = *value.target<
bool>() ? 1.f : 0.f;
284 case ossia::val_type::STRING:
285 if(!resize(expr, self, 1))
287 self.expressions[0].x = ossia::convert<float>(value);
289 case ossia::val_type::VEC2F:
290 if(!resize(expr, self, 2))
292 self.expressions[0].x = (*value.target<ossia::vec2f>())[0];
293 self.expressions[1].x = (*value.target<ossia::vec2f>())[1];
295 case ossia::val_type::VEC3F:
296 if(!resize(expr, self, 3))
298 self.expressions[0].x = (*value.target<ossia::vec3f>())[0];
299 self.expressions[1].x = (*value.target<ossia::vec3f>())[1];
300 self.expressions[2].x = (*value.target<ossia::vec3f>())[2];
302 case ossia::val_type::VEC4F:
303 if(!resize(expr, self, 4))
305 self.expressions[0].x = (*value.target<ossia::vec4f>())[0];
306 self.expressions[1].x = (*value.target<ossia::vec4f>())[1];
307 self.expressions[2].x = (*value.target<ossia::vec4f>())[2];
308 self.expressions[3].x = (*value.target<ossia::vec4f>())[3];
310 case ossia::val_type::LIST: {
311 auto& arr = *value.target<std::vector<ossia::value>>();
312 const auto N = std::clamp((
int)std::ssize(arr), 0, 1024);
313 if(!resize(expr, self, N))
315 for(
int i = 0; i < N; i++)
316 self.expressions[i].x = ossia::convert<float>(arr[i]);
319 case ossia::val_type::MAP: {
320 auto& arr = *value.target<ossia::value_map_type>();
321 const auto N = std::clamp((
int)std::ssize(arr), 0, 1024);
322 if(!resize(expr, self, N))
325 for(
auto& [k, v] : arr)
326 self.expressions[i++].x = ossia::convert<float>(v);
331 GenericMathMapping::exec_polyphonic(self, output);
333 std::vector<ossia::value> res;
334 res.resize(self.expressions.size());
335 for(
int i = 0; i < self.expressions.size(); i++)
336 res[i] = (
float)self.expressions[i].po;
339 output(std::move(res));
342 static void run_array(
343 const ossia::value& value, value_output_callback& output,
344 const halp::tick_flicks& tk,
State& self)
354 auto array_run_scalar = [&](
float in) {
355 auto old_size = self.xv.size();
356 self.xv.assign(1, in);
358 GenericMathMapping::exec_array(self, output, old_size != new_size);
361 switch(value.get_type())
363 case ossia::val_type::NONE:
365 case ossia::val_type::IMPULSE:
366 GenericMathMapping::exec_array(self, output,
false);
368 case ossia::val_type::INT:
369 array_run_scalar(*value.target<
int>());
371 case ossia::val_type::FLOAT:
372 array_run_scalar(*value.target<
float>());
374 case ossia::val_type::BOOL:
375 array_run_scalar(*value.target<
bool>() ? 1.f : 0.f);
377 case ossia::val_type::STRING:
378 array_run_scalar(ossia::convert<float>(value));
380 case ossia::val_type::VEC2F: {
381 auto& arr = *value.target<ossia::vec2f>();
382 auto old_size = self.xv.size();
383 self.xv.assign(arr.begin(), arr.end());
385 GenericMathMapping::exec_array(self, output, old_size != new_size);
388 case ossia::val_type::VEC3F: {
389 auto& arr = *value.target<ossia::vec3f>();
390 auto old_size = self.xv.size();
391 self.xv.assign(arr.begin(), arr.end());
393 GenericMathMapping::exec_array(self, output, old_size != new_size);
396 case ossia::val_type::VEC4F: {
397 auto& arr = *value.target<ossia::vec4f>();
398 auto old_size = self.xv.size();
399 self.xv.assign(arr.begin(), arr.end());
401 GenericMathMapping::exec_array(self, output, old_size != new_size);
404 case ossia::val_type::LIST: {
405 auto& arr = *value.target<std::vector<ossia::value>>();
406 auto old_size = self.xv.size();
407 self.xv.resize(arr.size());
408 auto new_size = arr.size();
409 for(std::size_t i = 0; i < arr.size(); i++)
411 self.xv[i] = ossia::convert<float>(arr[i]);
413 GenericMathMapping::exec_array(self, output, old_size != new_size);
416 case ossia::val_type::MAP: {
417 auto& arr = *value.target<ossia::value_map_type>();
418 auto old_size = self.xv.size();
419 self.xv.resize(arr.size());
420 auto new_size = arr.size();
422 for(
const auto& [k, v] : arr)
424 self.xv[i++] = ossia::convert<float>(v);
426 GenericMathMapping::exec_array(self, output, old_size != new_size);