SDEngine
Game Engine
Loading...
Searching...
No Matches
serialization.hpp
Go to the documentation of this file.
1#pragma once
2#include <array>
3#include <concepts>
4#include <cstring>
5#include <iterator>
6#include <string>
7#include <vector>
8
9#include <VLA/Matrix.hpp>
10
11#include "SD/core/types.hpp"
12
13namespace sd {
14
15struct Serializer;
16
17// ADL-based serialization detection
18template<typename T>
19concept HasSerialize = requires(Serializer& s, const T& obj) { serialize(s, obj); };
20
21template<typename T>
22concept HasDeserialize = requires(Serializer& s, T& obj) { deserialize(s, obj); };
23
24template<typename T> concept HasSerialization = HasSerialize<T> && HasDeserialize<T>;
25
38struct Serializer {
39 explicit Serializer(std::vector<std::byte>& buffer) : m_buffer(buffer) {}
40
41 // Write arithmetic types
42 template<typename T>
43 requires std::is_arithmetic_v<T>
44 void write(const T& value) {
45 const auto bytes = reinterpret_cast<const std::byte*>(&value);
46 m_buffer.insert(m_buffer.end(), bytes, bytes + sizeof(T));
47 }
48
49 // Write a C-style array
50 template<typename T, USize N>
51 void write(const T (&arr)[N]) {
52 for (const auto& val : arr) {
53 write(val);
54 }
55 }
56
57 // Write std::array
58 template<typename T, USize N>
59 void write(const std::array<T, N>& arr) {
60 for (const auto& val : arr) {
61 write(val);
62 }
63 }
64
65 // Write string
66 void write(const std::string& value) {
67 write(static_cast<U32>(value.size()));
68 const auto* bytes = reinterpret_cast<const std::byte*>(&value[0]);
69 m_buffer.insert(m_buffer.end(), bytes, bytes + value.size());
70 }
71
72 // Write std::vector (arithmetic types)
73 template<typename T>
74 requires std::is_arithmetic_v<T>
75 void write(const std::vector<T>& vec) {
76 write(static_cast<U32>(vec.size()));
77 for (const auto& val : vec) {
78 write(val);
79 }
80 }
81
82 // Write raw bytes
83 void write(const void* data, const USize size) {
84 const auto bytes = static_cast<const std::byte*>(data);
85 m_buffer.insert(m_buffer.end(), bytes, bytes + size);
86 }
87
88 // Write ADL-serializable object
89 template<HasSerialize T>
90 void write(const T& obj) {
91 serialize(*this, obj);
92 }
93
94 // Write VLA::Matrix4x4f
95 void write(const VLA::Matrix4x4f& m) { write(m.A); }
96
97 // Read arithmetic types
98 template<typename T>
99 requires std::is_arithmetic_v<T>
100 T read() {
101 assert(m_read_offset + sizeof(T) <= get_written_size());
102 T value;
103 std::memcpy(&value, m_buffer.data() + m_read_offset, sizeof(T));
104 m_read_offset += sizeof(T);
105 return value;
106 }
107
108 // Read C-style array
109 template<typename T, USize N>
110 void read(T (&arr)[N]) {
111 assert(m_read_offset + sizeof(T) * N <= get_written_size());
112 for (auto& val : arr) {
113 val = read<T>();
114 }
115 }
116
117 // Read std::array
118 template<typename T, USize N>
119 void read(std::array<T, N>& arr) {
120 assert(m_read_offset + sizeof(T) * N <= get_written_size());
121 for (auto& val : arr) {
122 val = read<T>();
123 }
124 }
125
126 // Read string
127 std::string read_string() {
129 const USize size = read<U32>();
130 assert(m_read_offset + size * sizeof(char) <= get_written_size());
131 const char* ptr = reinterpret_cast<const char*>(m_buffer.data() + m_read_offset);
132 std::string str(ptr, size);
133 m_read_offset += size;
134 return str;
135 }
136
137 // Read std::vector (arithmetic types)
138 template<typename T>
139 requires std::is_arithmetic_v<T>
140 void read(std::vector<T>& vec) {
141 U32 size = read<U32>();
142 vec.resize(size);
143 for (U32 i = 0; i < size; ++i) {
144 vec[i] = read<T>();
145 }
146 }
147
148 // Read ADL-deserializable object
149 template<HasDeserialize T>
150 void read(T& obj) {
151 deserialize(*this, obj);
152 }
153
154 // Read VLA::Matrix4x4f
155 VLA::Matrix4x4f read() {
156 VLA::Matrix4x4f m;
157 read(m.A);
158 return m;
159 }
160
162 [[nodiscard]] USize get_offset() const { return m_read_offset; }
164
165 [[nodiscard]] USize get_written_size() const { return m_buffer.size(); }
166 void clear() { m_buffer.clear(); }
167
168 [[nodiscard]] std::span<std::byte> get_span() const { return {m_buffer.data(), m_buffer.size()}; }
169
170
171 std::vector<std::byte>& m_buffer;
173};
174
175} // namespace sd
Definition serialization.hpp:22
Definition serialization.hpp:24
Definition serialization.hpp:19
Definition Application.hpp:22
Definition serialization.hpp:38
void write(const std::array< T, N > &arr)
Definition serialization.hpp:59
VLA::Matrix4x4f read()
Definition serialization.hpp:155
void read(T(&arr)[N])
Definition serialization.hpp:110
void write(const T &value)
Definition serialization.hpp:44
std::span< std::byte > get_span() const
Definition serialization.hpp:168
void write(const std::vector< T > &vec)
Definition serialization.hpp:75
void write(const VLA::Matrix4x4f &m)
Definition serialization.hpp:95
void write(const std::string &value)
Definition serialization.hpp:66
Serializer(std::vector< std::byte > &buffer)
Definition serialization.hpp:39
USize get_written_size() const
Definition serialization.hpp:165
void write(const T &obj)
Definition serialization.hpp:90
void read(std::vector< T > &vec)
Definition serialization.hpp:140
T read()
Definition serialization.hpp:100
std::string read_string()
Definition serialization.hpp:127
void write(const void *data, const USize size)
Definition serialization.hpp:83
void SetOffset(USize offset)
Definition serialization.hpp:163
USize m_read_offset
Definition serialization.hpp:172
void read(std::array< T, N > &arr)
Definition serialization.hpp:119
void reset_offset()
Definition serialization.hpp:161
void clear()
Definition serialization.hpp:166
void read(T &obj)
Definition serialization.hpp:150
void write(const T(&arr)[N])
Definition serialization.hpp:51
USize get_offset() const
Definition serialization.hpp:162
std::vector< std::byte > & m_buffer
Definition serialization.hpp:171
consteval U64 type_id_of()
Definition type_id.hpp:6
std::uint32_t U32
Definition types.hpp:15
std::size_t USize
Definition types.hpp:18