MessageBus.hpp
1 #pragma once
3 
4 #include <boost/pfr.hpp>
5 
6 #include <avnd/common/tag.hpp>
7 #include <avnd/concepts/message_bus.hpp>
8 
9 namespace oscr
10 {
11 
12 struct Serializer
13 {
15 
16  template <typename F>
17  requires std::is_aggregate_v<F>
18  void operator()(const F& f) { boost::pfr::for_each_field(f, *this); }
19 
20  template <typename F>
21  requires(std::is_arithmetic_v<F>) void operator()(const F& f)
22  {
23  r.stream().stream << f;
24  }
25 
26  template <typename... Args>
27  void operator()(const std::variant<Args...>& f)
28  {
29  r.stream() << (int)f.index();
30  std::visit([&](const auto& arg) { r.stream() << arg; }, f);
31  }
32 
33  void operator()(const auto& f) { r.stream() << f; }
34 };
35 
37 {
38  std::function<void(QByteArray)>& bus;
39 
40  template <typename T>
41  requires std::is_trivial_v<T>
42  void operator()(const T& msg)
43  {
44  // Here we can just do a memcpy
45  this->bus(QByteArray((const char*)&msg, sizeof(msg)));
46  }
47 
48  template <typename T>
49  requires(!std::is_trivial_v<T> && avnd::relocatable<T>)
50  void operator()(const T& msg)
51  {
52  QByteArray b(msg.size(), Qt::Uninitialized);
53  auto dst = reinterpret_cast<T*>(b.data());
54  new(dst) T(msg);
55 
56  this->bus(std::move(b));
57  }
58 
59  template <typename T>
60  requires(!std::is_trivial_v<T> && avnd::relocatable<T>)
61  void operator()(T&& msg)
62  {
63  QByteArray b(sizeof(msg), Qt::Uninitialized);
64  auto dst = reinterpret_cast<T*>(b.data());
65  std::construct_at(dst, std::move(msg));
66 
67  this->bus(std::move(b));
68  }
69 
70  template <typename T>
71  requires(!std::is_trivial_v<T> && !avnd::relocatable<T>)
72  void operator()(const T& msg)
73  {
74  // Here we gotta serialize... :D
75  QByteArray buf;
76 
77  DataStreamReader str{&buf};
78  Serializer{str}(msg);
79 
80  this->bus(std::move(buf));
81  }
82 };
83 
85 {
87 
88  template <typename F>
89  requires std::is_aggregate_v<F>
90  void operator()(F& f) { boost::pfr::for_each_field(f, *this); }
91 
92  template <typename F>
93  requires(std::is_arithmetic_v<F>) void operator()(F& f) { r.stream().stream >> f; }
94 
95  template <std::size_t I, typename... Args>
96  bool write_variant(std::variant<Args...>& f)
97  {
98  auto& elt = f.template emplace<I>();
99  r.stream() >> elt;
100  return true;
101  }
102 
103  template <typename... Args>
104  void operator()(std::variant<Args...>& f)
105  {
106  int index{};
107  r.stream() >> index;
108 
109  [&]<std::size_t... I>(std::index_sequence<I...>)
110  {
111  (((index == I) && write_variant<I>(f)) || ...);
112  }
113  (std::make_index_sequence<sizeof...(Args)>{});
114  }
115 
116  void operator()(auto& f) { r.stream() >> f; }
117 };
118 
120 {
121  QByteArray& mess;
122 
123  template <typename T>
124  requires std::is_trivial_v<T>
125  void operator()(T& msg)
126  {
127  // Here we can just do a memcpy
128  memcpy(&msg, mess.data(), mess.size());
129  }
130  template <typename T>
131  requires(!std::is_trivial_v<T> && avnd::relocatable<T>)
132  void operator()(T& msg)
133  {
134  auto src = reinterpret_cast<T*>(mess.data());
135  msg = std::move(*src);
136  std::destroy_at(src);
137  }
138 
139  template <typename T>
140  requires(!std::is_trivial_v<T> && !avnd::relocatable<T>)
141  void operator()(T& msg)
142  {
143  // Deserialize... :D
144 
145  DataStreamWriter str{mess};
146  Deserializer{str}(msg);
147  }
148 };
149 
150 }
Definition: DataStreamVisitor.hpp:27
Definition: DataStreamVisitor.hpp:202
Definition: MessageBus.hpp:85
Definition: MessageBus.hpp:120
Definition: MessageBus.hpp:37
Definition: MessageBus.hpp:13