OSSIA
Open Scenario System for Interactive Application
flat_state.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <ossia/detail/config.hpp>
4 
5 #include <ossia/detail/apply.hpp>
6 #include <ossia/detail/flat_map.hpp>
8 #include <ossia/editor/state/detail/state_execution_visitor.hpp>
10 #include <ossia/network/base/parameter.hpp>
11 #include <ossia/network/dataspace/dataspace_variant_visitors.hpp>
13 #include <ossia/network/dataspace/detail/dataspace_convert.hpp>
14 #include <ossia/network/dataspace/detail/dataspace_merge.hpp>
15 #include <ossia/network/dataspace/detail/dataspace_parse.hpp>
16 #include <ossia/network/dataspace/detail/list_units.hpp>
17 #include <ossia/network/dataspace/detail/make_unit.hpp>
18 #include <ossia/network/dataspace/detail/make_value.hpp>
19 #include <ossia/network/dataspace/value_with_unit.hpp>
20 
21 #include <memory>
22 //#include <ossia/network/value/detail/value_conversion_impl.hpp>
23 #include <ossia/detail/hash.hpp>
24 #include <ossia/detail/hash_map.hpp>
26 namespace std
27 {
28 template <>
29 struct hash<std::pair<ossia::net::parameter_base*, ossia::unit_t>>
30 {
31  struct vis
32  {
33  template <typename T>
34  std::size_t operator()(const T& t)
35  {
36  return t.which();
37  }
38 
39  std::size_t operator()() { return ossia::unit_variant::npos; }
40  };
41  std::size_t
42  operator()(const std::pair<ossia::net::parameter_base*, ossia::unit_t>& k) const
43  {
44  std::size_t seed = 0;
45  ossia::hash_combine(seed, k.first);
46  ossia::hash_combine(seed, k.second.v.which());
47  auto res = ossia::apply(vis{}, k.second.v);
48  ossia::hash_combine(seed, res);
49 
50  return seed;
51  }
52 };
53 }
57 namespace ossia
58 {
69 class OSSIA_EXPORT flat_set_state
70 {
71 public:
72  OSSIA_EXPORT friend bool operator==(const state& lhs, const state& rhs);
73  OSSIA_EXPORT friend bool operator!=(const state& lhs, const state& rhs);
74 
75  auto begin() { return m_children.begin(); }
76  auto end() { return m_children.end(); }
77  auto begin() const { return m_children.begin(); }
78  auto end() const { return m_children.end(); }
79  auto cbegin() const { return m_children.cbegin(); }
80  auto cend() const { return m_children.cend(); }
81 
82  auto& children() const { return m_children; }
83 
84  std::size_t size() const { return m_children.size(); }
85 
86  bool empty() const { return m_children.empty(); }
87 
88  void launch()
89  {
90  for(auto& state : m_children)
91  {
92  ossia::apply(state_execution_visitor{}, std::move(state.second));
93  }
94  }
95 
96  void add(const ossia::message& e)
97  {
98  // TODO push in vector instead... or flat_multimap
99  // But normally there should be a single one with a given address / unit
100  // pair... do an assert ?
101 
102  m_children[std::make_pair(&e.dest.value.get(), e.get_unit())] = e;
103  }
104  void add(ossia::message&& e)
105  {
106  // TODO push in vector instead... or flat_multimap
107  m_children[std::make_pair(&e.dest.value.get(), e.get_unit())] = std::move(e);
108  }
109  void add(const ossia::piecewise_message& e)
110  {
111  // TODO push in vector instead... or flat_multimap
112  m_children[std::make_pair(&e.address.get(), e.get_unit())] = e;
113  }
114  template <std::size_t N>
115  void add(piecewise_vec_message<N>&& e)
116  {
117  // TODO push in vector instead... or flat_multimap
118  m_children[std::make_pair(&e.address.get(), e.get_unit())] = std::move(e);
119  }
120  template <std::size_t N>
121  void add(const piecewise_vec_message<N>& e)
122  {
123  // TODO push in vector instead... or flat_multimap
124  m_children[std::make_pair(&e.address.get(), e.get_unit())] = e;
125  }
126 
127  void add(const ossia::state_element& e)
128  {
129  switch(e.which())
130  {
131  case 0:
132  return add(*static_cast<const ossia::message*>(e.target()));
133  case 2:
134  return add(*static_cast<const ossia::piecewise_message*>(e.target()));
135  case 3:
136  return add(*static_cast<const ossia::piecewise_vec_message<2>*>(e.target()));
137  case 4:
138  return add(*static_cast<const ossia::piecewise_vec_message<3>*>(e.target()));
139  case 5:
140  return add(*static_cast<const ossia::piecewise_vec_message<4>*>(e.target()));
141  case 1:
142  default:
143  throw std::runtime_error("there shouldn't be a state here");
144  break;
145  }
146  }
147  void add(ossia::state_element&& e)
148  {
149  switch(e.which())
150  {
151  case 0:
152  return add(std::move(*static_cast<ossia::message*>(e.target())));
153  case 2:
154  return add(std::move(*static_cast<ossia::piecewise_message*>(e.target())));
155  case 3:
156  return add(
157  std::move(*static_cast<ossia::piecewise_vec_message<2>*>(e.target())));
158  case 4:
159  return add(
160  std::move(*static_cast<ossia::piecewise_vec_message<3>*>(e.target())));
161  case 5:
162  return add(
163  std::move(*static_cast<ossia::piecewise_vec_message<4>*>(e.target())));
164  case 1:
165  default:
166  throw std::runtime_error("there shouldn't be a state here");
167  break;
168  }
169  }
170 
171  auto find(const message& e)
172  {
173  return m_children.find({&e.dest.value.get(), e.get_unit()});
174  }
175  auto find(const piecewise_message& e)
176  {
177  return m_children.find({&e.address.get(), e.get_unit()});
178  }
179  template <std::size_t N>
180  auto find(const piecewise_vec_message<N>& e)
181  {
182  return m_children.find({&e.address.get(), e.get_unit()});
183  }
184 
185  void remove(const ossia::message& e)
186  {
187  m_children.erase(std::make_pair(&e.dest.value.get(), e.get_unit()));
188  }
189 
190  void remove(const ossia::piecewise_message& e)
191  {
192  m_children.erase(std::make_pair(&e.address.get(), e.get_unit()));
193  }
194 
195  using map_t = ossia::hash_map<
196  std::pair<ossia::net::parameter_base*, ossia::unit_t>, state_element>;
197  using iterator = map_t::iterator;
198  using const_iterator = map_t::const_iterator;
199  void remove(iterator it) { m_children.erase(it); }
200  void remove(const_iterator it) { m_children.erase(it); }
201 
202  template <std::size_t N>
203  void remove(const ossia::piecewise_vec_message<N>& e)
204  {
205  m_children.erase(std::make_pair(&e.address.get(), e.get_unit()));
206  }
207 
208  void reserve(std::size_t n) { m_children.reserve(n); }
209  void clear() { m_children.clear(); }
210 
211 private:
212  map_t m_children;
213 };
214 
215 inline ossia::state_element& get_state_element(ossia::flat_set_state::iterator iterator)
216 {
217  return iterator->second;
218 }
219 }
The flat_state class.
Definition: flat_state.hpp:70
The state class.
Definition: editor/state/state.hpp:25
Definition: git_info.h:7
void launch(state_element &e)
launch Launch a state_element
Definition: state_element.cpp:18
ossia::nullable_variant< message, state, piecewise_message, piecewise_vec_message< 2 >, piecewise_vec_message< 3 >, piecewise_vec_message< 4 > > state_element
Definition: state_element_fwd.hpp:28
The message struct.
Definition: message.hpp:29