Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
ser_dispatch.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 Serializer, typename T, typename SaveTrivial>
15 void save_dispatch(Serializer& s, const T& arg, SaveTrivial&& saveTrivial) {
16 using U = core::raw_t<T>;
17
18 // Custom save() has precedence
19 if constexpr (has_func_save<U, Serializer&>::value) {
20 arg.save(s);
21 } else if constexpr (has_tag_save<Serializer, 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 saveTrivial(s, 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 saveTrivial(s, size);
32
33 for (const auto& e: std::as_const(arg))
34 save_dispatch(s, e, saveTrivial);
35 }
36 // Classes
37 else if constexpr (std::is_class_v<U>) {
38 meta::each_member(GAIA_FWD(arg), [&s, &saveTrivial](auto&&... items) {
39 // TODO: Handle contiguous blocks of trivially copyable types
40 (save_dispatch(s, items, saveTrivial), ...);
41 });
42 } else
43 static_assert(!sizeof(U), "Type is not supported for serialization, yet");
44 }
45
46 template <typename Serializer, typename T, typename LoadTrivial>
47 void load_dispatch(Serializer& s, T& arg, LoadTrivial&& loadTrivial) {
48 using U = core::raw_t<T>;
49
50 // Custom load() has precedence
51 if constexpr (has_func_load<U, Serializer&>::value) {
52 arg.load(s);
53 } else if constexpr (has_tag_load<Serializer, 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 loadTrivial(s, 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 loadTrivial(s, 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_dispatch(s, e, loadTrivial);
74
75 uint32_t i = 0;
76 for (auto e: arg) {
77 load_dispatch(s, e, loadTrivial);
78 arg[i] = GAIA_MOV(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_dispatch(s, val, loadTrivial);
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, &loadTrivial](auto&&... items) {
94 // TODO: Handle contiguous blocks of trivially copyable types
95 (load_dispatch(s, items, loadTrivial), ...);
96 });
97 } else
98 static_assert(!sizeof(U), "Type is not supported for serialization, yet");
99 }
100 } // namespace detail
101 } // namespace ser
102} // namespace gaia
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Definition utility.h:153
Definition ser_common.h:92