Combiner.hpp
1 #pragma once
2 #include <AvndProcesses/AddressTools.hpp>
3 
4 namespace avnd_tools
5 {
6 
8 {
9  halp_meta(name, "Pattern combiner")
10  halp_meta(author, "ossia team")
11  halp_meta(category, "Control/Data processing")
12  halp_meta(description, "Apply an operation to all inputs matching a pattern")
13  halp_meta(c_name, "avnd_pattern_combine")
14  halp_meta(uuid, "18efe965-9acc-4703-9af3-3cef658b301a")
15 
16  struct
17  {
18  PatternSelector pattern;
19 
20  struct
21  {
22  halp__enum("Mode", List, List, Average, Sum, Min, Max);
23  } mode{};
24 
25  } inputs;
26 
27  struct
28  {
29  halp::val_port<"Output", ossia::value> output;
30  } outputs;
31 
32  std::vector<ossia::value> current_values;
33 
34  void operator()()
35  {
36  if(!m_path)
37  return;
38 
39  current_values.clear();
40  if(inputs.pattern.devices_dirty)
41  inputs.pattern.reprocess();
42  for(auto in : this->roots)
43  {
44  if(auto p = in->get_parameter())
45  current_values.push_back(p->value());
46  }
47 
48  if(current_values.empty())
49  {
50  return;
51  }
52 
53  using mode = decltype(inputs.mode)::enum_type;
54  switch(inputs.mode)
55  {
56  case mode::List:
57  outputs.output.value = current_values;
58  break;
59  case mode::Average: {
60  double res{};
61  for(const auto& val : current_values)
62  {
63  res += ossia::convert<double>(val);
64  }
65  res /= current_values.size();
66  outputs.output.value = float(res);
67  break;
68  }
69  case mode::Sum: {
70  double res{};
71  for(const auto& val : current_values)
72  {
73  res += ossia::convert<double>(val);
74  }
75  outputs.output.value = float(res);
76  break;
77  }
78  case mode::Min: {
79  double res = ossia::convert<double>(current_values[0]);
80  for(std::size_t i = 1; i < current_values.size(); i++)
81  {
82  res = std::min(res, ossia::convert<double>(current_values[i]));
83  }
84  outputs.output.value = float(res);
85  break;
86  }
87  case mode::Max: {
88  double res = ossia::convert<double>(current_values[0]);
89  for(std::size_t i = 1; i < current_values.size(); i++)
90  {
91  res = std::max(res, ossia::convert<double>(current_values[i]));
92  }
93  outputs.output.value = float(res);
94  break;
95  }
96  }
97 
98  /*
99  auto process = [this](const std::vector<ossia::value>& vec) {
100  QTimer::singleShot(1, qApp, [roots = this->roots, vec] {
101  const auto N = std::min(roots.size(), vec.size());
102  for(std::size_t i = 0; i < N; i++)
103  {
104  if(auto p = roots[i]->get_parameter())
105  {
106  // Needs to be done in main thread because of the QJSEngine in serial_protocols
107  p->push_value(vec[i]);
108  }
109  }
110  });
111  };
112  if(auto vvec = inputs.input.value.target<std::vector<ossia::value>>())
113  {
114  process(*vvec);
115  }
116  else
117  {
118  process(ossia::convert<std::vector<ossia::value>>(inputs.input.value));
119  }
120  */
121  }
122 };
123 
124 }
Definition: Combiner.hpp:8
Definition: AddressTools.hpp:20
Definition: AddressTools.hpp:27