OSSIA
Open Scenario System for Interactive Application
detail/dataspace_parse.hpp
1 #pragma once
2 #include <ossia/detail/for_each.hpp>
4 #include <ossia/detail/string_view.hpp>
5 #include <ossia/network/dataspace/dataspace.hpp>
6 #include <ossia/network/dataspace/dataspace_parse.hpp>
8 #include <ossia/network/dataspace/detail/dataspace_list.hpp>
9 
10 namespace ossia::detail
11 {
12 using unit_map = string_view_map<ossia::unit_t>;
13 
14 template <typename Arg, typename... Args>
15 struct unit_map_factory
16 {
17  void operator()(unit_map& m)
18  {
19  for(std::string_view v : ossia::unit_traits<Arg>::text())
20  m.emplace(v, ossia::unit_t{Arg{}});
21  unit_map_factory<Args...>{}(m);
22  }
23 };
24 
25 template <typename Arg>
26 struct unit_map_factory<Arg>
27 {
28  void operator()(unit_map& m)
29  {
30  for(std::string_view v : ossia::unit_traits<Arg>::text())
31  m.emplace(v, ossia::unit_t{Arg{}});
32  }
33 };
34 
35 template <typename... Args>
36 struct make_unit_map
37 {
38  unit_map operator()()
39  {
40  unit_map map;
41  unit_map_factory<Args...>{}(map);
42  return map;
43  }
44 };
45 
46 struct unit_factory_visitor
47 {
48  std::string_view text;
49 
50  template <typename Dataspace_T>
51  ossia::unit_t operator()(Dataspace_T arg)
52  {
53  static const auto units = boost::mp11::mp_rename<
54  typename matching_unit_u_list<Dataspace_T>::type, make_unit_map>{}();
55  auto it = units.find(text);
56  return it != units.end() ? it->second : ossia::unit_t{};
57  }
58 
59  OSSIA_INLINE ossia::unit_t operator()() { return {}; }
60 };
61 
62 template <typename Unit>
63 using enable_if_multidimensional = std::enable_if_t<Unit::is_multidimensional::value>;
64 
65 template <typename Dataspace, typename Unit, typename = void>
66 struct make_unit_symbols_sub_helper
67 {
68  void operator()(unit_parse_symbols_t& map)
69  {
70  using unit_type = Unit;
71 
72  std::string res;
73  res.reserve(20);
74 
75  for(auto ds : dataspace_traits<Dataspace>::text())
76  {
77  // For each unit :
78  for(auto un : unit_traits<unit_type>::text())
79  {
80  res.clear();
81 
82  res.append(ds.data(), ds.size()); // color
83  res += '.'; // color.
84 
85  res.append(un.data(), un.size()); // color.rgb
86 
87  // Add the unit in long form
88  map.add(res, {{}, unit_type{}});
89  }
90  }
91  }
92 };
93 
94 template <typename Dataspace, typename Unit>
95 struct make_unit_symbols_sub_helper<Dataspace, Unit, enable_if_multidimensional<Unit>>
96 {
97  void operator()(unit_parse_symbols_t& map)
98  {
99  using unit_type = Unit;
100 
101  std::string res;
102  res.reserve(20);
103 
104  for(auto ds : dataspace_traits<Dataspace>::text())
105  {
106  // For each unit :
107  for(auto un : unit_traits<unit_type>::text())
108  {
109  res.clear();
110 
111  res.append(ds.data(), ds.size()); // color
112  res += '.'; // color.
113 
114  res.append(un.data(), un.size()); // color.rgb
115 
116  // Add the unit in long form
117  map.add(res, {{}, unit_type{}});
118 
119  // Add all the accessors
120  res += "._"; // color.rgb._
121 
122  const auto& params = unit_type::array_parameters();
123  const auto n = params.size();
124  for(std::size_t i = 0; i < n; i++)
125  {
126  // replace the last char with the one in the array parameter
127  res[res.size() - 1] = params[i]; // color.rgb.r
128  map.add(res, {{(uint8_t)i}, unit_type{}});
129  }
130  }
131  }
132  }
133 };
134 
135 struct make_unit_symbols_helper
136 {
137  unit_parse_symbols_t map;
138 
139  make_unit_symbols_helper()
140  {
141  ossia::for_each_tagged(dataspace_u_list{}, [&](auto t) {
142  using dataspace_type = typename decltype(t)::type;
143  ossia::for_each_tagged(dataspace_type{}, [&](auto u) {
144  using unit_type = typename decltype(u)::type;
145  make_unit_symbols_sub_helper<dataspace_type, unit_type>{}(map);
146  });
147  });
148  }
149 };
150 }
Definition: transitive_closure.hpp:27
Definition: dataspace.hpp:24