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();
74 store_output(self, res);
83 const auto N = self.expressions.size();
86 for(std::size_t i = 0; i < N; i++)
88 auto& e = self.expressions[i];
89 auto r = e.expr.result();
93 if constexpr(
requires { e.x; })
100 res[i] = std::move(r);
106 exec_array(
State& self, value_output_callback& output,
bool vector_size_did_change)
111 if(vector_size_did_change)
117 self.pxv.resize(self.xv.size());
118 self.expr.rebase_vector(
"xv", self.xv);
119 self.expr.rebase_vector(
"pxv", self.pxv);
120 self.expr.recompile();
123 if(!self.expr.valid())
126 auto res = self.expr.result();
127 store_output(self, res);
130 self.pxv.assign(self.xv.begin(), self.xv.end());
133 output(std::move(res));
136 static void run_scalar(
137 const ossia::value& v, value_output_callback& output,
const halp::tick_flicks& tk,
140 setMathExpressionTiming(
141 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
142 self.last_value_time = tk.start_in_flicks;
146 case ossia::val_type::NONE:
148 case ossia::val_type::IMPULSE:
150 case ossia::val_type::INT:
151 self.x = *v.target<
int>();
153 case ossia::val_type::FLOAT:
154 self.x = *v.target<
float>();
156 case ossia::val_type::BOOL:
157 self.x = *v.target<
bool>() ? 1.f : 0.f;
159 case ossia::val_type::STRING:
160 self.x = ossia::convert<float>(v);
162 case ossia::val_type::VEC2F:
163 self.x = (*v.target<ossia::vec2f>())[0];
165 case ossia::val_type::VEC3F:
166 self.x = (*v.target<ossia::vec3f>())[0];
168 case ossia::val_type::VEC4F:
169 self.x = (*v.target<ossia::vec4f>())[0];
171 case ossia::val_type::LIST: {
172 auto& arr = *v.target<std::vector<ossia::value>>();
174 self.x = ossia::convert<float>(arr[0]);
177 case ossia::val_type::MAP: {
178 auto& arr = *v.target<ossia::value_map_type>();
180 self.x = ossia::convert<float>(arr.begin()->second);
185 GenericMathMapping::exec_scalar(self, output);
188 static bool resize(
const std::string& expr,
State& self,
int sz)
190 if(std::ssize(self.expressions) == sz && expr == self.last_expression)
191 return self.last_expression_ok;
193 self.expressions.resize(sz);
198 for(
auto& e : self.expressions)
203 if(!std::exchange(e.initialized,
true))
204 e.init(self.cur_time, self.cur_deltatime, self.cur_pos, self.count);
207 if(!e.expr.set_expression(expr))
210 UINT64_C(0xda3e39cb94b95bdb), UINT64_C(0x853c49e6748fea9b) * (1 + i));
216 self.last_expression = expr;
217 self.last_expression_ok = ok;
221 static void run_polyphonic(
222 int size, value_output_callback& output,
const std::string& expr,
223 const halp::tick_flicks& tk,
State& self)
229 if(size <= 1 || uses_identifier(expr,
"po"))
231 size = std::clamp(size, 0, 1024);
232 if(!resize(expr, self, size))
235 setMathExpressionTiming(
236 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
237 self.last_value_time = tk.start_in_flicks;
239 std::vector<ossia::value> res;
241 output(std::move(res));
245 if(!resize(expr, self, 1))
248 setMathExpressionTiming(
249 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
250 self.last_value_time = tk.start_in_flicks;
252 std::vector<ossia::value> res;
255 for(
int i = 0; i < size; i++)
257 auto& e = self.expressions[0];
259 res[i] = e.expr.result();
265 output(std::move(res));
269 static void run_polyphonic(
270 const ossia::value& value, value_output_callback& output,
const std::string& expr,
271 const halp::tick_flicks& tk,
State& self)
273 setMathExpressionTiming(
274 self, tk.start_in_flicks, self.last_value_time, tk.relative_position);
275 self.last_value_time = tk.start_in_flicks;
288 switch(value.get_type())
290 case ossia::val_type::NONE:
292 case ossia::val_type::IMPULSE:
294 case ossia::val_type::INT:
295 if(!resize(expr, self, 1))
297 self.expressions[0].x = *value.target<
int>();
299 case ossia::val_type::FLOAT:
300 if(!resize(expr, self, 1))
302 self.expressions[0].x = *value.target<
float>();
304 case ossia::val_type::BOOL:
305 if(!resize(expr, self, 1))
307 self.expressions[0].x = *value.target<
bool>() ? 1.f : 0.f;
309 case ossia::val_type::STRING:
310 if(!resize(expr, self, 1))
312 self.expressions[0].x = ossia::convert<float>(value);
314 case ossia::val_type::VEC2F:
315 if(!resize(expr, self, 2))
317 self.expressions[0].x = (*value.target<ossia::vec2f>())[0];
318 self.expressions[1].x = (*value.target<ossia::vec2f>())[1];
320 case ossia::val_type::VEC3F:
321 if(!resize(expr, self, 3))
323 self.expressions[0].x = (*value.target<ossia::vec3f>())[0];
324 self.expressions[1].x = (*value.target<ossia::vec3f>())[1];
325 self.expressions[2].x = (*value.target<ossia::vec3f>())[2];
327 case ossia::val_type::VEC4F:
328 if(!resize(expr, self, 4))
330 self.expressions[0].x = (*value.target<ossia::vec4f>())[0];
331 self.expressions[1].x = (*value.target<ossia::vec4f>())[1];
332 self.expressions[2].x = (*value.target<ossia::vec4f>())[2];
333 self.expressions[3].x = (*value.target<ossia::vec4f>())[3];
335 case ossia::val_type::LIST: {
336 auto& arr = *value.target<std::vector<ossia::value>>();
337 const auto N = std::clamp((
int)std::ssize(arr), 0, 1024);
338 if(!resize(expr, self, N))
340 for(
int i = 0; i < N; i++)
341 self.expressions[i].x = ossia::convert<float>(arr[i]);
344 case ossia::val_type::MAP: {
345 auto& arr = *value.target<ossia::value_map_type>();
346 const auto N = std::clamp((
int)std::ssize(arr), 0, 1024);
347 if(!resize(expr, self, N))
350 for(
auto& [k, v] : arr)
351 self.expressions[i++].x = ossia::convert<float>(v);
356 std::vector<ossia::value> res;
358 output(std::move(res));
361 static void run_array(
362 const ossia::value& value, value_output_callback& output,
363 const halp::tick_flicks& tk,
State& self)
373 auto array_run_scalar = [&](
float in) {
374 auto old_size = self.xv.size();
375 self.xv.assign(1, in);
377 GenericMathMapping::exec_array(self, output, old_size != new_size);
380 switch(value.get_type())
382 case ossia::val_type::NONE:
384 case ossia::val_type::IMPULSE:
385 GenericMathMapping::exec_array(self, output,
false);
387 case ossia::val_type::INT:
388 array_run_scalar(*value.target<
int>());
390 case ossia::val_type::FLOAT:
391 array_run_scalar(*value.target<
float>());
393 case ossia::val_type::BOOL:
394 array_run_scalar(*value.target<
bool>() ? 1.f : 0.f);
396 case ossia::val_type::STRING:
397 array_run_scalar(ossia::convert<float>(value));
399 case ossia::val_type::VEC2F: {
400 auto& arr = *value.target<ossia::vec2f>();
401 auto old_size = self.xv.size();
402 self.xv.assign(arr.begin(), arr.end());
404 GenericMathMapping::exec_array(self, output, old_size != new_size);
407 case ossia::val_type::VEC3F: {
408 auto& arr = *value.target<ossia::vec3f>();
409 auto old_size = self.xv.size();
410 self.xv.assign(arr.begin(), arr.end());
412 GenericMathMapping::exec_array(self, output, old_size != new_size);
415 case ossia::val_type::VEC4F: {
416 auto& arr = *value.target<ossia::vec4f>();
417 auto old_size = self.xv.size();
418 self.xv.assign(arr.begin(), arr.end());
420 GenericMathMapping::exec_array(self, output, old_size != new_size);
423 case ossia::val_type::LIST: {
424 auto& arr = *value.target<std::vector<ossia::value>>();
425 auto old_size = self.xv.size();
426 self.xv.resize(arr.size());
427 auto new_size = arr.size();
428 for(std::size_t i = 0; i < arr.size(); i++)
430 self.xv[i] = ossia::convert<float>(arr[i]);
432 GenericMathMapping::exec_array(self, output, old_size != new_size);
435 case ossia::val_type::MAP: {
436 auto& arr = *value.target<ossia::value_map_type>();
437 auto old_size = self.xv.size();
438 self.xv.resize(arr.size());
439 auto new_size = arr.size();
441 for(
const auto& [k, v] : arr)
443 self.xv[i++] = ossia::convert<float>(v);
445 GenericMathMapping::exec_array(self, output, old_size != new_size);