OSSIA
Open Scenario System for Interactive Application
mapper_visitor.hpp
1 #pragma once
2 #include <ossia/detail/apply.hpp>
4 #include <ossia/editor/curve/curve.hpp>
6 #include <ossia/misc_visitors.hpp>
7 
8 namespace ossia::detail
9 {
10 struct mapper_compute_visitor
11 {
12  ossia::value operator()(float driver, const std::shared_ptr<curve_abstract>& c)
13  {
14  auto base_curve = c.get();
15  auto t = base_curve->get_type();
16 
17  switch(t.second)
18  {
19  case ossia::curve_segment_type::FLOAT: {
20  auto c = static_cast<curve<float, float>*>(base_curve);
21  return float{c->value_at(driver)};
22  }
23  case ossia::curve_segment_type::INT: {
24  auto c = static_cast<curve<float, int>*>(base_curve);
25  return int32_t{c->value_at(driver)};
26  }
27  case ossia::curve_segment_type::BOOL: {
28  auto c = static_cast<curve<float, bool>*>(base_curve);
29  return bool{c->value_at(driver)};
30  }
31  case ossia::curve_segment_type::DOUBLE:
32  case ossia::curve_segment_type::ANY:
33  default:
34  return {};
35  }
36  }
37 
38  ossia::value operator()(int32_t driver, const std::shared_ptr<curve_abstract>& c)
39  {
40  auto base_curve = c.get();
41  auto t = base_curve->get_type();
42 
43  switch(t.second)
44  {
45  case ossia::curve_segment_type::FLOAT: {
46  auto c = static_cast<curve<float, float>*>(base_curve);
47  return float{c->value_at(driver)};
48  }
49  case ossia::curve_segment_type::INT: {
50  auto c = static_cast<curve<float, int>*>(base_curve);
51  return int32_t{c->value_at(driver)};
52  }
53  case ossia::curve_segment_type::BOOL: {
54  auto c = static_cast<curve<float, bool>*>(base_curve);
55  return bool{c->value_at(driver)};
56  }
57  case ossia::curve_segment_type::DOUBLE:
58  case ossia::curve_segment_type::ANY:
59  default:
60  return {};
61  }
62  }
63 
64  ossia::value operator()(bool driver, const std::shared_ptr<curve_abstract>& c)
65  {
66  auto base_curve = c.get();
67  auto t = base_curve->get_type();
68 
69  switch(t.second)
70  {
71  case ossia::curve_segment_type::FLOAT: {
72  auto c = static_cast<curve<bool, float>*>(base_curve);
73  return float{c->value_at(driver)};
74  }
75  case ossia::curve_segment_type::INT: {
76  auto c = static_cast<curve<bool, int>*>(base_curve);
77  return int32_t{c->value_at(driver)};
78  }
79  case ossia::curve_segment_type::BOOL: {
80  auto c = static_cast<curve<bool, bool>*>(base_curve);
81  return bool{c->value_at(driver)};
82  }
83  case ossia::curve_segment_type::DOUBLE:
84  case ossia::curve_segment_type::ANY:
85  default:
86  return {};
87  }
88  }
89 
90  ossia::value operator()(
91  const std::vector<ossia::value>& t_driver,
92  const std::shared_ptr<curve_abstract>& c)
93  {
94  std::vector<ossia::value> t_value = t_driver;
95  for(auto& v : t_value)
96  {
97  if(v.valid())
98  {
99  v = ossia::apply_nonnull(
100  [&](const auto& e) { return this->operator()(e, c); }, std::move(v.v));
101  }
102  }
103 
104  return t_value;
105  }
106 
107  template <std::size_t N>
109  operator()(std::array<float, N> driver, const std::shared_ptr<curve_abstract>& c)
110  {
111  auto base_curve = c.get();
112  auto t = base_curve->get_type();
113  if(t.first == ossia::curve_segment_type::FLOAT
114  && t.second == ossia::curve_segment_type::FLOAT)
115  {
116  auto c = static_cast<curve<float, float>*>(base_curve);
117  for(std::size_t i = 0; i < N; i++)
118  {
119  driver[i] = c->value_at(driver[i]);
120  }
121  return driver;
122  }
123  else
124  {
125  return {};
126  }
127  }
128 
129  template <std::size_t N>
131  operator()(std::array<float, N> driver, const std::vector<ossia::behavior>& t_drive)
132  {
133  if(t_drive.size() != N)
134  return {};
135 
136  for(std::size_t i = 0; i < N; i++)
137  {
138  auto curve_p = t_drive[i].target<std::shared_ptr<curve_abstract>>();
139  if(!curve_p)
140  return {};
141 
142  auto c = curve_p->get();
143  if(!c)
144  return {};
145 
146  auto t = c->get_type();
147  if(t.first == ossia::curve_segment_type::FLOAT
148  && t.second == ossia::curve_segment_type::FLOAT)
149  driver[i] = static_cast<curve<float, float>*>(c)->value_at(driver[i]);
150  else
151  return {};
152  }
153 
154  return driver;
155  }
156 
157  ossia::value operator()(
158  const std::vector<ossia::value>& t_driver,
159  const std::vector<ossia::behavior>& t_drive)
160  {
161  std::vector<ossia::value> t_value;
162  t_value.reserve(t_drive.size());
163  auto it_driver = t_driver.begin();
164 
165  for(const auto& e_drive : t_drive)
166  {
167  if(it_driver == t_driver.end())
168  break;
169 
170  if(it_driver->valid() && e_drive)
171  {
172  t_value.push_back(ossia::apply(*this, it_driver->v, e_drive.v));
173  }
174  else
175  {
176  t_value.emplace_back();
177  }
178  it_driver++;
179  }
180 
181  return t_value;
182  }
183 
184  template <typename T, typename U>
185  ossia::value operator()(const T& driver, const U& t_drive)
186  {
187  throw invalid_value_type_error(
188  "mapper_compute_visitor_2: "
189  "invalid case");
190  return {};
191  }
192 };
193 }
The value class.
Definition: value.hpp:173
Definition: transitive_closure.hpp:27