DomainSerializationImpl.hpp
1 #pragma once
2 #include <State/OSSIASerializationImpl.hpp>
3 #include <State/ValueSerializationImpl.hpp>
4 
5 #include <ossia/detail/typelist.hpp>
6 
8 
9 template <>
10 struct TSerializer<DataStream, ossia::vector_domain>
11 {
12  using domain_t = ossia::vector_domain;
13  static void readFrom(DataStream::Serializer& s, const domain_t& domain)
14  {
15  s.stream() << domain.min << domain.max << domain.values;
16  }
17 
18  static void writeTo(DataStream::Deserializer& s, domain_t& domain)
19  {
20  s.stream() >> domain.min >> domain.max >> domain.values;
21  }
22 };
23 
24 template <std::size_t N>
25 struct TSerializer<JSONObject, ossia::vecf_domain<N>>
26 {
27  using domain_t = ossia::vecf_domain<N>;
28  static void readFrom(JSONObject::Serializer& s, const domain_t& domain)
29  {
30  s.stream.StartObject();
31  s.obj[s.strings.Min] = domain.min;
32  s.obj[s.strings.Max] = domain.max;
33  s.obj[s.strings.Values] = domain.values;
34  s.stream.EndObject();
35  }
36 
37  static void writeTo(JSONObject::Deserializer& s, domain_t& domain)
38  {
39  // OPTIMIZEME there should be something in boost
40  // to get multiple iterators from multiple keys in one pass...
41  if(auto it = s.obj.tryGet(s.strings.Min))
42  {
43  domain.min <<= *it;
44  }
45  if(auto it = s.obj.tryGet(s.strings.Max))
46  {
47  domain.max <<= *it;
48  }
49  if(auto it = s.obj.tryGet(s.strings.Values))
50  {
51  domain.values <<= *it;
52  }
53  }
54 };
55 
56 template <std::size_t N>
57 struct TSerializer<DataStream, ossia::vecf_domain<N>>
58 {
59  using domain_t = ossia::vecf_domain<N>;
60  static void readFrom(DataStream::Serializer& s, const domain_t& domain)
61  {
62  s.stream() << domain.min << domain.max << domain.values;
63  }
64 
65  static void writeTo(DataStream::Deserializer& s, domain_t& domain)
66  {
67  s.stream() >> domain.min >> domain.max >> domain.values;
68  }
69 };
70 
71 template <typename T>
72 struct TSerializer<JSONObject, ossia::domain_base<T>>
73 {
74  using domain_t = ossia::domain_base<T>;
75  static void readFrom(JSONObject::Serializer& s, const domain_t& domain)
76  {
77  s.stream.StartObject();
78 
79  if(domain.min)
80  s.obj[s.strings.Min] = *domain.min;
81  if(domain.max)
82  s.obj[s.strings.Max] = *domain.max;
83  if(!domain.values.empty())
84  s.obj[s.strings.Values] = domain.values;
85 
86  s.stream.EndObject();
87  }
88 
89  static void writeTo(const JSONObject::Deserializer& s, domain_t& domain)
90  {
91  // OPTIMIZEME there should be something in boost
92  // to get multiple iterators from multiple keys in one pass...
93  if(auto it = s.obj.tryGet(s.strings.Min))
94  {
95  domain.min <<= *it;
96  }
97  if(auto it = s.obj.tryGet(s.strings.Max))
98  {
99  domain.max <<= *it;
100  }
101  if(auto it = s.obj.tryGet(s.strings.Values))
102  {
103  domain.values <<= *it;
104  }
105  }
106 };
107 
108 template <>
109 struct TSerializer<JSONObject, ossia::domain_base<std::string>>
110 {
111  using domain_t = ossia::domain_base<std::string>;
112  static void readFrom(JSONObject::Serializer& s, const domain_t& domain)
113  {
114  s.stream.StartObject();
115  if(!domain.values.empty())
116  s.obj[s.strings.Values] = domain.values;
117  s.stream.EndObject();
118  }
119 
120  static void writeTo(JSONObject::Deserializer& s, domain_t& domain)
121  {
122  if(auto it_values = s.obj.tryGet(s.strings.Values))
123  {
124  domain.values <<= *it_values;
125  }
126  }
127 };
128 
129 template <>
130 struct TSerializer<JSONObject, ossia::domain_base<ossia::impulse>>
131 {
132  using domain_t = ossia::domain_base<ossia::impulse>;
133  static void readFrom(JSONObject::Serializer& s, const domain_t& domain)
134  {
135  s.stream.Null();
136  }
137 
138  static void writeTo(JSONObject::Deserializer& s, domain_t& domain) { }
139 };
140 
141 template <>
142 struct TSerializer<JSONObject, ossia::domain_base<bool>>
143 {
144  using domain_t = ossia::domain_base<bool>;
145  static void readFrom(JSONObject::Serializer& s, const domain_t& domain)
146  {
147  s.stream.Null();
148  }
149 
150  static void writeTo(JSONObject::Deserializer& s, domain_t& domain) { }
151 };
152 
153 template <>
154 struct TSerializer<JSONObject, ossia::vector_domain>
155 {
156  using domain_t = ossia::vector_domain;
157  static void readFrom(JSONObject::Serializer& s, const domain_t& domain)
158  {
159  s.stream.StartObject();
160  s.obj[s.strings.Min] = domain.min;
161  s.obj[s.strings.Max] = domain.max;
162  s.obj[s.strings.Values] = domain.values;
163  s.stream.EndObject();
164  }
165 
166  static void writeTo(JSONObject::Deserializer& s, domain_t& domain)
167  {
168  // OPTIMIZEME there should be something in boost
169  // to get multiple iterators from multiple keys in one pass...
170 
171  if(auto it = s.obj.tryGet(s.strings.Min))
172  {
173  domain.min <<= *it;
174  }
175  if(auto it = s.obj.tryGet(s.strings.Max))
176  {
177  domain.max <<= *it;
178  }
179  if(auto it = s.obj.tryGet(s.strings.Values))
180  {
181  domain.values <<= *it;
182  }
183  }
184 };
185 
186 template <typename T>
187 struct TSerializer<DataStream, ossia::domain_base<T>>
188 {
189  using domain_t = ossia::domain_base<T>;
190  static void readFrom(DataStream::Serializer& s, const domain_t& domain)
191  {
192  // Min
193  {
194  bool min_b{domain.min};
195  s.stream() << min_b;
196  if(min_b)
197  s.stream() << *domain.min;
198  }
199 
200  // Max
201  {
202  bool max_b{domain.max};
203  s.stream() << max_b;
204  if(max_b)
205  s.stream() << *domain.max;
206  }
207 
208  // Values
209  {
210  s.stream() << (int32_t)domain.values.size();
211  for(auto& val : domain.values)
212  s.stream() << val;
213  }
214 
215  s.insertDelimiter();
216  }
217 
218  static void writeTo(DataStream::Deserializer& s, domain_t& domain)
219  {
220  {
221  bool min_b;
222  s.stream() >> min_b;
223  if(min_b)
224  {
225  typename domain_t::value_type v;
226  s.stream() >> v;
227  domain.min = std::move(v);
228  }
229  }
230 
231  {
232  bool max_b;
233  s.stream() >> max_b;
234  if(max_b)
235  {
236  typename domain_t::value_type v;
237  s.stream() >> v;
238  domain.max = std::move(v);
239  }
240  }
241 
242  {
243  int32_t count;
244  s.stream() >> count;
245  for(int i = 0; i < count; i++)
246  {
247  typename domain_t::value_type v;
248  s.stream() >> v;
249  domain.values.push_back(v);
250  }
251  }
252 
253  s.checkDelimiter();
254  }
255 };
256 
257 template <>
258 struct TSerializer<DataStream, ossia::domain_base<std::string>>
259 {
260  using domain_t = ossia::domain_base<std::string>;
261  static void readFrom(DataStream::Serializer& s, const domain_t& domain)
262  {
263  // Values
264  {
265  s.stream() << (int32_t)domain.values.size();
266  for(auto& val : domain.values)
267  s.stream() << val;
268  }
269 
270  s.insertDelimiter();
271  }
272 
273  static void writeTo(DataStream::Deserializer& s, domain_t& domain)
274  {
275  {
276  int32_t count;
277  s.stream() >> count;
278  for(int i = 0; i < count; i++)
279  {
280  std::string v;
281  s.stream() >> v;
282  domain.values.push_back(v);
283  }
284  }
285 
286  s.checkDelimiter();
287  }
288 };
289 
290 template <>
291 struct TSerializer<DataStream, ossia::domain_base<ossia::impulse>>
292 {
293  using domain_t = ossia::domain_base<ossia::impulse>;
294  static void readFrom(DataStream::Serializer& s, const domain_t& domain) { }
295 
296  static void writeTo(DataStream::Deserializer& s, domain_t& domain) { }
297 };
298 
299 template <>
300 struct TSerializer<DataStream, ossia::domain_base<bool>>
301 {
302  using domain_t = ossia::domain_base<bool>;
303  static void readFrom(DataStream::Serializer& s, const domain_t& domain) { }
304 
305  static void writeTo(DataStream::Deserializer& s, domain_t& domain) { }
306 };
307 
308 template <typename Functor>
309 void apply_typeonly(
310  Functor&& functor, ossia::domain_base_variant::Type type,
311  ossia::domain_base_variant& var)
312 {
313  using namespace ossia;
314  switch(type)
315  {
316  case domain_base_variant::Type::Type0:
317  return functor(typeholder<ossia::domain_base<ossia::impulse>>{}, var);
318  case domain_base_variant::Type::Type1:
319  return functor(typeholder<ossia::domain_base<bool>>{}, var);
320  case domain_base_variant::Type::Type2:
321  return functor(typeholder<ossia::domain_base<int32_t>>{}, var);
322  case domain_base_variant::Type::Type3:
323  return functor(typeholder<ossia::domain_base<float>>{}, var);
324  case domain_base_variant::Type::Type5:
325  return functor(typeholder<ossia::domain_base<std::string>>{}, var);
326  case domain_base_variant::Type::Type6:
327  return functor(typeholder<ossia::vector_domain>{}, var);
328  case domain_base_variant::Type::Type7:
329  return functor(typeholder<ossia::vecf_domain<2>>{}, var);
330  case domain_base_variant::Type::Type8:
331  return functor(typeholder<ossia::vecf_domain<3>>{}, var);
332  case domain_base_variant::Type::Type9:
333  return functor(typeholder<ossia::vecf_domain<4>>{}, var);
334  case domain_base_variant::Type::Type10:
335  return functor(typeholder<ossia::domain_base<ossia::value>>{}, var);
336  default:
337  throw;
338  }
339 }
340 
341 template <>
342 struct TSerializer<DataStream, ossia::domain_base_variant>
343 {
344  using var_t = ossia::domain_base_variant;
345  static void readFrom(DataStream::Serializer& s, const var_t& var)
346  {
347  s.stream() << (quint64)var.which();
348 
349  if(var)
350  {
351  ossia::apply_nonnull([&](const auto& v) { s.stream() << v; }, var);
352  }
353 
354  s.insertDelimiter();
355  }
356 
357  static void writeTo(DataStream::Deserializer& s, var_t& var)
358  {
359  quint64 which;
360  s.stream() >> which;
361 
362  if(which != (quint64)var.npos)
363  {
364  apply_typeonly(
365  [&](auto type, var_t& var) {
366  typename decltype(type)::type value;
367  s.stream() >> value;
368  var = std::move(value);
369  },
370  (var_t::Type)which, var);
371  }
372  s.checkDelimiter();
373  }
374 };
375 
376 template <>
377 struct TSerializer<JSONObject, ossia::domain_base_variant>
378 {
379  using var_t = ossia::domain_base_variant;
380  static void readFrom(JSONObject::Serializer& s, const var_t& var)
381  {
382  s.stream.StartObject();
383  if((quint64)var.which() != (quint64)var.npos)
384  {
385  ossia::for_each_type(value_type_list{}, VariantJSONSerializer<var_t>{s, var});
386  }
387  s.stream.EndObject();
388  }
389 
390  using value_type_list = ossia::tl<
391  ossia::domain_base<ossia::impulse>, ossia::domain_base<bool>,
392  ossia::domain_base<int32_t>, ossia::domain_base<float>,
393  ossia::domain_base<std::string>, ossia::vector_domain, ossia::vecf_domain<2>,
394  ossia::vecf_domain<3>, ossia::vecf_domain<4>, ossia::domain_base<ossia::value>>;
395 
396  static auto init_keys()
397  {
398  std::array<QString, ossia::size<value_type_list>::value> arr;
399  int i = 0;
400  ossia::for_each_tagged(value_type_list{}, [&](auto t) {
401  using type = typename decltype(t)::type;
402  arr[i] = Metadata<Json_k, type>::get();
403  i++;
404  });
405  return arr;
406  }
407  static const auto& keys_list()
408  {
409  static const auto arr = init_keys();
410  return arr;
411  }
412 
413  static void writeTo(JSONObject::Deserializer& s, var_t& var)
414  {
415  if(!s.base.IsObject() || s.base.MemberCount() == 0)
416  return;
417  ossia::for_each_type(value_type_list{}, VariantJSONDeserializer<var_t>{s, var});
418  }
419 };
Definition: VisitorInterface.hpp:53
Definition: DataStreamVisitor.hpp:27
Definition: DataStreamVisitor.hpp:202
Definition: VisitorInterface.hpp:61
Definition: JSONVisitor.hpp:52
Definition: JSONVisitor.hpp:423
Static metadata implementation.
Definition: lib/score/tools/Metadata.hpp:36
Definition: VisitorInterface.hpp:13
Definition: VariantSerialization.hpp:183
Definition: VariantSerialization.hpp:152
Definition: OSSIASerializationImpl.hpp:81