Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
ser_ct.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <type_traits>
5#include <utility>
6
7#include "gaia/core/utility.h"
8#include "gaia/meta/reflection.h"
9#include "gaia/ser/ser_common.h"
10
11namespace gaia {
12 namespace ser {
13 namespace detail {
14 template <typename Writer, typename T>
15 void save_one(Writer& s, const T& arg) {
16 using U = core::raw_t<T>;
17
18 // Custom save() has precedence
19 if constexpr (has_func_save<U, Writer&>::value) {
20 arg.save(s);
21 } else if constexpr (has_tag_save<Writer, U>::value) {
22 tag_invoke(save_v, s, static_cast<const U&>(arg));
23 }
24 // Trivially serializable types
25 else if constexpr (is_trivially_serializable<U>::value) {
26 s.save(arg);
27 }
28 // Types which have size(), begin() and end() member functions
29 else if constexpr (core::has_size_begin_end<U>::value) {
30 const auto size = arg.size();
31 s.save(size);
32
33 for (const auto& e: std::as_const(arg))
34 save_one(s, e);
35 }
36 // Classes
37 else if constexpr (std::is_class_v<U>) {
38 meta::each_member(GAIA_FWD(arg), [&s](auto&&... items) {
39 // TODO: Handle contiguous blocks of trivially copyable types
40 (save_one(s, items), ...);
41 });
42 } else
43 static_assert(!sizeof(U), "Type is not supported for serialization, yet");
44 }
45
46 template <typename Reader, typename T>
47 void load_one(Reader& s, T& arg) {
48 using U = core::raw_t<T>;
49
50 // Custom load() has precedence
51 if constexpr (has_func_load<U, Reader&>::value) {
52 arg.load(s);
53 } else if constexpr (has_tag_load<Reader, U>::value) {
54 tag_invoke(load_v, s, static_cast<U&>(arg));
55 }
56 // Trivially serializable types
57 else if constexpr (is_trivially_serializable<U>::value) {
58 s.load(arg);
59 }
60 // Types which have size(), begin() and end() member functions
61 else if constexpr (core::has_size_begin_end<U>::value) {
62 auto size = arg.size();
63 s.load(size);
64
65 if constexpr (has_func_resize<U, size_t>::value) {
66 // If resize is present, use it
67 arg.resize(size);
68
69 // NOTE: We can't do it this way. If there are containers with the overloaded
70 // operator=, the result might not be what one would expect.
71 // E.g., in our case, SoA containers need specific handling.
72 // for (auto&& e: arg)
73 // load_one(s, e);
74
75 uint32_t i = 0;
76 for (auto e: arg) {
77 load_one(s, e);
78 arg[i] = std::move(e);
79 ++i;
80 }
81 } else {
82 // With no resize present, write directly into memory
83 GAIA_FOR(size) {
84 using arg_type = typename std::remove_pointer<decltype(arg.data())>::type;
85 arg_type val;
86 load_one(s, val);
87 arg[i] = val;
88 }
89 }
90 }
91 // Classes
92 else if constexpr (std::is_class_v<U>) {
93 meta::each_member(GAIA_FWD(arg), [&s](auto&&... items) {
94 // TODO: Handle contiguous blocks of trivially copyable types
95 (load_one(s, items), ...);
96 });
97 } else
98 static_assert(!sizeof(U), "Type is not supported for serialization, yet");
99 }
100
101#if GAIA_ASSERT_ENABLED
102 template <typename Writer, typename T>
103 void check_one(Writer& s, const T& arg) {
104 T tmp{};
105
106 // Make sure that we write just as many bytes as we read.
107 // If the positions are the same there is a good chance that save and load match.
108 const auto pos0 = s.tell();
109 save_one(s, arg);
110 const auto pos1 = s.tell();
111 s.seek(pos0);
112 load_one(s, tmp);
113 GAIA_ASSERT(s.tell() == pos1);
114
115 // Return back to the original position in the buffer.
116 s.seek(pos0);
117 }
118#endif
119 } // namespace detail
120
127 template <typename Writer, typename T>
128 void save(Writer& writer, const T& data) {
129 detail::save_one(writer, data);
130 }
131
138 template <typename Reader, typename T>
139 void load(Reader& reader, T& data) {
140 detail::load_one(reader, data);
141 }
142
143#if GAIA_ASSERT_ENABLED
151 template <typename Writer, typename T>
152 void check(Writer& writer, const T& data) {
153 detail::check_one(writer, data);
154 }
155#endif
156 } // namespace ser
157} // namespace gaia
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9