Loading...
Searching...
No Matches
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
9namespace oscr
10{
11
13{
15
16 template <typename F>
17 void operator()(const F& f)
18 {
19 if constexpr(std::is_arithmetic_v<F>)
20 r.stream().stream << f;
21 else if constexpr(std::is_aggregate_v<F>)
22 boost::pfr::for_each_field(f, *this);
23 else if constexpr(avnd::list_ish<F>)
24 {
25 r.stream().stream << (int64_t)std::ssize(f);
26 for(const auto& val : f)
27 {
28 (*this)(val);
29 }
30 }
31 else
32 r.stream() << f;
33 }
34
35 template <typename... Args>
36 void operator()(const std::variant<Args...>& f)
37 {
38 r.stream().stream << (int)f.index();
39 std::visit(*this, f);
40 }
41};
42
44{
45 std::function<void(QByteArray)>& bus;
46
47 template <typename T>
48 requires std::is_trivial_v<T>
49 void operator()(const T& msg)
50 {
51 // Here we can just do a memcpy
52 this->bus(QByteArray((const char*)&msg, sizeof(msg)));
53 }
54
55 template <typename T>
56 requires(
57 !std::is_trivial_v<T> && avnd::relocatable<T>
58 && alignof(T) <= alignof(max_align_t))
59 void operator()(const T& msg)
60 {
61 QByteArray b(msg.size(), Qt::Uninitialized);
62 auto dst = reinterpret_cast<T*>(b.data());
63 new(dst) T(msg);
64
65 this->bus(std::move(b));
66 }
67
68 template <typename T>
69 requires(
70 !std::is_trivial_v<T> && avnd::relocatable<T>
71 && alignof(T) <= alignof(max_align_t))
72 void operator()(T&& msg)
73 {
74 QByteArray b(sizeof(msg), Qt::Uninitialized);
75 auto dst = reinterpret_cast<T*>(b.data());
76 std::construct_at(dst, std::move(msg));
77
78 this->bus(std::move(b));
79 }
80
81 template <typename T>
82 requires(
83 !std::is_trivial_v<T>
84 && (!avnd::relocatable<T> || (alignof(T) > alignof(max_align_t))))
85 void operator()(const T& msg)
86 {
87 // Here we gotta serialize... :D
88 QByteArray buf;
89
90 DataStreamReader str{&buf};
91 Serializer{str}(msg);
92
93 this->bus(std::move(buf));
94 }
95
96 template <typename T>
97 void operator()(const std::shared_ptr<T>& msg)
98 {
99 SCORE_ASSERT(msg);
100 return (*this)(std::move(*msg));
101 }
102 template <typename T>
103 void operator()(std::unique_ptr<T> msg)
104 {
105 SCORE_ASSERT(msg);
106 return (*this)(std::move(*msg));
107 }
108};
109
111{
113
114 template <typename F>
115 requires std::is_aggregate_v<F>
116 void operator()(F& f) { boost::pfr::for_each_field(f, *this); }
117
118 template <typename F>
119 requires(std::is_arithmetic_v<F>)
120 void operator()(F& f)
121 {
122 r.stream().stream >> f;
123 }
124
125 template <typename F>
126 requires avnd::list_ish<F>
127 void operator()(F& f)
128 {
129 int64_t sz;
130 r.stream().stream >> sz;
131 SCORE_ASSERT(sz >= 0);
132 for(int64_t i = 0; i < sz; i++)
133 {
134 using type = typename F::value_type;
135 type val;
136 (*this)(val);
137 f.push_back(std::move(val));
138 }
139 }
140
141 template <std::size_t I, typename... Args>
142 bool write_variant(std::variant<Args...>& f)
143 {
144 auto& elt = f.template emplace<I>();
145 (*this)(elt);
146 return true;
147 }
148
149 template <typename... Args>
150 void operator()(std::variant<Args...>& f)
151 {
152 int index{};
153 r.stream().stream >> index;
154
155 SCORE_ASSERT(index >= 0);
156 SCORE_ASSERT(index < sizeof...(Args));
157 [&]<std::size_t... I>(std::index_sequence<I...>)
158 {
159 (((index == I) && write_variant<I>(f)) || ...);
160 }
161 (std::make_index_sequence<sizeof...(Args)>{});
162 }
163
164 void operator()(auto& f) { r.stream() >> f; }
165};
166
168{
169 QByteArray& mess;
170
171 template <typename T>
172 requires std::is_trivial_v<T>
173 void operator()(T& msg)
174 {
175 // Here we can just do a memcpy
176 memcpy(&msg, mess.data(), mess.size());
177 }
178 template <typename T>
179 requires(
180 !std::is_trivial_v<T> && avnd::relocatable<T>
181 && alignof(T) <= alignof(max_align_t))
182 void operator()(T& msg)
183 {
184 auto src = reinterpret_cast<T*>(mess.data());
185 msg = std::move(*src);
186 std::destroy_at(src);
187 }
188
189 template <typename T>
190 requires(
191 !std::is_trivial_v<T>
192 && (!avnd::relocatable<T> || (alignof(T) > alignof(max_align_t))))
193 void operator()(T& msg)
194 {
195 // Deserialize... :D
196
197 DataStreamWriter str{mess};
198 Deserializer{str}(msg);
199 }
200};
201
202}
Definition DataStreamVisitor.hpp:27
Definition DataStreamVisitor.hpp:202
Definition Factories.hpp:19
Definition MessageBus.hpp:111
Definition MessageBus.hpp:168
Definition MessageBus.hpp:44
Definition MessageBus.hpp:13