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 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 template <typename T>
84 void operator()(const std::shared_ptr<T>& msg)
85 {
86 SCORE_ASSERT(msg);
87 return (*this)(std::move(*msg));
88 }
89 template <typename T>
90 void operator()(std::unique_ptr<T> msg)
91 {
92 SCORE_ASSERT(msg);
93 return (*this)(std::move(*msg));
94 }
95};
96
98{
100
101 template <typename F>
102 requires std::is_aggregate_v<F>
103 void operator()(F& f) { boost::pfr::for_each_field(f, *this); }
104
105 template <typename F>
106 requires(std::is_arithmetic_v<F>) void operator()(F& f) { r.stream().stream >> f; }
107
108 template <std::size_t I, typename... Args>
109 bool write_variant(std::variant<Args...>& f)
110 {
111 auto& elt = f.template emplace<I>();
112 r.stream() >> elt;
113 return true;
114 }
115
116 template <typename... Args>
117 void operator()(std::variant<Args...>& f)
118 {
119 int index{};
120 r.stream() >> index;
121
122 [&]<std::size_t... I>(std::index_sequence<I...>)
123 {
124 (((index == I) && write_variant<I>(f)) || ...);
125 }
126 (std::make_index_sequence<sizeof...(Args)>{});
127 }
128
129 void operator()(auto& f) { r.stream() >> f; }
130};
131
133{
134 QByteArray& mess;
135
136 template <typename T>
137 requires std::is_trivial_v<T>
138 void operator()(T& msg)
139 {
140 // Here we can just do a memcpy
141 memcpy(&msg, mess.data(), mess.size());
142 }
143 template <typename T>
144 requires(!std::is_trivial_v<T> && avnd::relocatable<T>)
145 void operator()(T& msg)
146 {
147 auto src = reinterpret_cast<T*>(mess.data());
148 msg = std::move(*src);
149 std::destroy_at(src);
150 }
151
152 template <typename T>
153 requires(!std::is_trivial_v<T> && !avnd::relocatable<T>)
154 void operator()(T& msg)
155 {
156 // Deserialize... :D
157
158 DataStreamWriter str{mess};
159 Deserializer{str}(msg);
160 }
161};
162
163}
Definition DataStreamVisitor.hpp:27
Definition DataStreamVisitor.hpp:202
Definition Factories.hpp:19
Definition MessageBus.hpp:98
Definition MessageBus.hpp:133
Definition MessageBus.hpp:37
Definition MessageBus.hpp:13