18 const auto n = std::min(vec.size(), self.pov.size());
19 for(std::size_t i = 0; i < n; i++)
23 static void store_output(
auto& self,
const ossia::value& v)
27 case ossia::val_type::NONE:
29 case ossia::val_type::FLOAT:
30 self.po = *v.target<
float>();
32 case ossia::val_type::VEC2F: {
33 if constexpr(
requires { self.pov; })
37 case ossia::val_type::VEC3F: {
38 if constexpr(
requires { self.pov; })
42 case ossia::val_type::VEC4F: {
43 if constexpr(
requires { self.pov; })
47 case ossia::val_type::LIST: {
48 if constexpr(
requires { self.pov; })
50 auto& arr = *v.target<std::vector<ossia::value>>();
54 const auto n = std::min(arr.size(), self.pov.size());
55 for(std::size_t i = 0; i < n; i++)
56 self.pov[i] = ossia::convert<float>(arr[i]);
66 static void exec_scalar(
State& self, value_output_callback& output)
68 auto res = self.expr.result();
71 store_output(self, res);
80 const auto N = self.expressions.size();
83 for(std::size_t i = 0; i < N; i++)
85 auto& e = self.expressions[i];
86 auto r = e.expr.result();
88 if constexpr(
requires { e.x; })
95 res[i] = std::move(r);
100 exec_array(
State& self, value_output_callback& output,
bool vector_size_did_change)
105 if(vector_size_did_change)
111 self.pxv.resize(self.xv.size());
112 self.expr.rebase_vector(
"xv", self.xv);
113 self.expr.rebase_vector(
"pxv", self.pxv);
114 self.expr.recompile();
117 if(!self.expr.valid())
120 auto res = self.expr.result();
121 store_output(self, res);
124 self.pxv.assign(self.xv.begin(), self.xv.end());
126 output(std::move(res));
129 static void run_scalar(
130 const ossia::value& v, value_output_callback& output,
const halp::tick_flicks& tk,
133 setMathExpressionTiming(
134 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
135 self.last_value_time = tk.start_in_flicks;
139 case ossia::val_type::NONE:
141 case ossia::val_type::IMPULSE:
143 case ossia::val_type::INT:
144 self.x = *v.target<
int>();
146 case ossia::val_type::FLOAT:
147 self.x = *v.target<
float>();
149 case ossia::val_type::BOOL:
150 self.x = *v.target<
bool>() ? 1.f : 0.f;
152 case ossia::val_type::STRING:
153 self.x = ossia::convert<float>(v);
155 case ossia::val_type::VEC2F:
156 self.x = (*v.target<ossia::vec2f>())[0];
158 case ossia::val_type::VEC3F:
159 self.x = (*v.target<ossia::vec3f>())[0];
161 case ossia::val_type::VEC4F:
162 self.x = (*v.target<ossia::vec4f>())[0];
164 case ossia::val_type::LIST: {
165 auto& arr = *v.target<std::vector<ossia::value>>();
167 self.x = ossia::convert<float>(arr[0]);
170 case ossia::val_type::MAP: {
171 auto& arr = *v.target<ossia::value_map_type>();
173 self.x = ossia::convert<float>(arr.begin()->second);
178 GenericMathMapping::exec_scalar(self, output);
181 static bool resize(
const std::string& expr,
State& self,
int sz)
183 if(std::ssize(self.expressions) == sz && expr == self.last_expression)
184 return self.last_expression_ok;
186 self.expressions.resize(sz);
191 for(
auto& e : self.expressions)
196 if(!std::exchange(e.initialized,
true))
197 e.init(self.cur_time, self.cur_deltatime, self.cur_pos, self.count);
200 if(!e.expr.set_expression(expr))
203 UINT64_C(0xda3e39cb94b95bdb), UINT64_C(0x853c49e6748fea9b) * (1 + i));
209 self.last_expression = expr;
210 self.last_expression_ok = ok;
214 static void run_polyphonic(
215 int size, value_output_callback& output,
const std::string& expr,
216 const halp::tick_flicks& tk,
State& self)
222 if(size <= 1 || uses_identifier(expr,
"po"))
224 size = std::clamp(size, 0, 1024);
225 if(!resize(expr, self, size))
228 setMathExpressionTiming(
229 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
230 self.last_value_time = tk.start_in_flicks;
232 std::vector<ossia::value> res;
236 output(std::move(res));
240 if(!resize(expr, self, 1))
243 setMathExpressionTiming(
244 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
245 self.last_value_time = tk.start_in_flicks;
247 std::vector<ossia::value> res;
250 for(
int i = 0; i < size; i++)
252 auto& e = self.expressions[0];
254 res[i] = e.expr.result();
258 output(std::move(res));
262 static void run_polyphonic(
263 const ossia::value& value, value_output_callback& output,
const std::string& expr,
264 const halp::tick_flicks& tk,
State& self)
266 setMathExpressionTiming(
267 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
268 self.last_value_time = tk.start_in_flicks;
281 switch(value.get_type())
283 case ossia::val_type::NONE:
285 case ossia::val_type::IMPULSE:
287 case ossia::val_type::INT:
288 if(!resize(expr, self, 1))
290 self.expressions[0].x = *value.target<
int>();
292 case ossia::val_type::FLOAT:
293 if(!resize(expr, self, 1))
295 self.expressions[0].x = *value.target<
float>();
297 case ossia::val_type::BOOL:
298 if(!resize(expr, self, 1))
300 self.expressions[0].x = *value.target<
bool>() ? 1.f : 0.f;
302 case ossia::val_type::STRING:
303 if(!resize(expr, self, 1))
305 self.expressions[0].x = ossia::convert<float>(value);
307 case ossia::val_type::VEC2F:
308 if(!resize(expr, self, 2))
310 self.expressions[0].x = (*value.target<ossia::vec2f>())[0];
311 self.expressions[1].x = (*value.target<ossia::vec2f>())[1];
313 case ossia::val_type::VEC3F:
314 if(!resize(expr, self, 3))
316 self.expressions[0].x = (*value.target<ossia::vec3f>())[0];
317 self.expressions[1].x = (*value.target<ossia::vec3f>())[1];
318 self.expressions[2].x = (*value.target<ossia::vec3f>())[2];
320 case ossia::val_type::VEC4F:
321 if(!resize(expr, self, 4))
323 self.expressions[0].x = (*value.target<ossia::vec4f>())[0];
324 self.expressions[1].x = (*value.target<ossia::vec4f>())[1];
325 self.expressions[2].x = (*value.target<ossia::vec4f>())[2];
326 self.expressions[3].x = (*value.target<ossia::vec4f>())[3];
328 case ossia::val_type::LIST: {
329 auto& arr = *value.target<std::vector<ossia::value>>();
330 const auto N = std::clamp((
int)std::ssize(arr), 0, 1024);
331 if(!resize(expr, self, N))
333 for(
int i = 0; i < N; i++)
334 self.expressions[i].x = ossia::convert<float>(arr[i]);
337 case ossia::val_type::MAP: {
338 auto& arr = *value.target<ossia::value_map_type>();
339 const auto N = std::clamp((
int)std::ssize(arr), 0, 1024);
340 if(!resize(expr, self, N))
343 for(
auto& [k, v] : arr)
344 self.expressions[i++].x = ossia::convert<float>(v);
349 std::vector<ossia::value> res;
353 output(std::move(res));
356 static void run_array(
357 const ossia::value& value, value_output_callback& output,
358 const halp::tick_flicks& tk,
State& self)
368 auto array_run_scalar = [&](
float in) {
369 auto old_size = self.xv.size();
370 self.xv.assign(1, in);
372 GenericMathMapping::exec_array(self, output, old_size != new_size);
375 switch(value.get_type())
377 case ossia::val_type::NONE:
379 case ossia::val_type::IMPULSE:
380 GenericMathMapping::exec_array(self, output,
false);
382 case ossia::val_type::INT:
383 array_run_scalar(*value.target<
int>());
385 case ossia::val_type::FLOAT:
386 array_run_scalar(*value.target<
float>());
388 case ossia::val_type::BOOL:
389 array_run_scalar(*value.target<
bool>() ? 1.f : 0.f);
391 case ossia::val_type::STRING:
392 array_run_scalar(ossia::convert<float>(value));
394 case ossia::val_type::VEC2F: {
395 auto& arr = *value.target<ossia::vec2f>();
396 auto old_size = self.xv.size();
397 self.xv.assign(arr.begin(), arr.end());
399 GenericMathMapping::exec_array(self, output, old_size != new_size);
402 case ossia::val_type::VEC3F: {
403 auto& arr = *value.target<ossia::vec3f>();
404 auto old_size = self.xv.size();
405 self.xv.assign(arr.begin(), arr.end());
407 GenericMathMapping::exec_array(self, output, old_size != new_size);
410 case ossia::val_type::VEC4F: {
411 auto& arr = *value.target<ossia::vec4f>();
412 auto old_size = self.xv.size();
413 self.xv.assign(arr.begin(), arr.end());
415 GenericMathMapping::exec_array(self, output, old_size != new_size);
418 case ossia::val_type::LIST: {
419 auto& arr = *value.target<std::vector<ossia::value>>();
420 auto old_size = self.xv.size();
421 self.xv.resize(arr.size());
422 auto new_size = arr.size();
423 for(std::size_t i = 0; i < arr.size(); i++)
425 self.xv[i] = ossia::convert<float>(arr[i]);
427 GenericMathMapping::exec_array(self, output, old_size != new_size);
430 case ossia::val_type::MAP: {
431 auto& arr = *value.target<ossia::value_map_type>();
432 auto old_size = self.xv.size();
433 self.xv.resize(arr.size());
434 auto new_size = arr.size();
436 for(
const auto& [k, v] : arr)
438 self.xv[i++] = ossia::convert<float>(v);
440 GenericMathMapping::exec_array(self, output, old_size != new_size);