Unravel Engine C++ Reference
Loading...
Searching...
No Matches
serialization.h
Go to the documentation of this file.
1#pragma once
2#include "ser20/access.hpp"
3#include "ser20/ser20.hpp"
4#include "ser20/types/polymorphic.hpp"
5#include "ser20/types/vector.hpp"
6#include <hpp/source_location.hpp>
7
8#include <functional>
9#include <string>
10#include <vector>
11#include <stack>
12
13#define SERIALIZE_FUNCTION_NAME SER20_SERIALIZE_FUNCTION_NAME
14#define SAVE_FUNCTION_NAME SER20_SAVE_FUNCTION_NAME
15#define LOAD_FUNCTION_NAME SER20_LOAD_FUNCTION_NAME
16#define SAVE_MINIMAL_FUNCTION_NAME SER20_SAVE_MINIMAL_FUNCTION_NAME
17#define LOAD_MINIMAL_FUNCTION_NAME SER20_LOAD_MINIMAL_FUNCTION_NAME
18#define SERIALIZE_REGISTER_TYPE_WITH_NAME(T, Name) SER20_REGISTER_TYPE_WITH_NAME(T, Name)
19namespace serialization
20{
21using namespace ser20;
22
23using log_callback_t = std::function<void(const std::string&, const hpp::source_location& loc)>;
25void log_warning(const std::string& log_msg, const hpp::source_location& loc = hpp::source_location::current());
26
27// Path tracking for deserialization
29{
30 std::function<bool(const std::string&)> should_serialize_property_callback;
31 std::vector<std::string> path_segments;
32 bool recording_enabled = false;
33 bool ignore_next_push = false;
34
35 void push_segment(const std::string& segment, bool ignore_next = false);
36 void pop_segment();
37 auto get_current_path() const -> std::string;
38 void enable_recording();
39 void disable_recording();
40 auto is_recording() const -> bool;
41 void clear();
42
43 auto should_serialize_property(const std::string& property_path) const -> bool
44 {
46 {
47 return should_serialize_property_callback(property_path);
48 }
49 return true;
50 }
51};
52
53auto get_path_context() -> path_context*;
54void set_path_context(path_context* ctx);
55
56// Convenience function to get current deserialization path
57auto get_current_deserialization_path() -> std::string;
58
59// RAII helper for path segments
61{
62 path_segment_guard(const std::string& segment, bool ignore_next_push = false);
64
65 // Non-copyable and non-movable to avoid double-popping
70
71private:
72 bool was_pushed_ = false;
73};
74
75} // namespace serialization
76
77#define SERIALIZABLE(T) \
78 \
79public: \
80 friend class serialization::access; \
81 template<typename Archive> \
82 friend void SAVE_FUNCTION_NAME(Archive& ar, T const&); \
83 template<typename Archive> \
84 friend void LOAD_FUNCTION_NAME(Archive& ar, T&);
85
86#define SERIALIZE_INLINE(cls) \
87 template<typename Archive> \
88 inline void SERIALIZE_FUNCTION_NAME(Archive& ar, cls& obj)
89
90#define SAVE_INLINE(cls) \
91 template<typename Archive> \
92 inline void SAVE_FUNCTION_NAME(Archive& ar, cls const& obj)
93
94#define LOAD_INLINE(cls) \
95 template<typename Archive> \
96 inline void LOAD_FUNCTION_NAME(Archive& ar, cls& obj)
97
98#define SERIALIZE_EXTERN(cls) \
99 template<typename Archive> \
100 extern void SERIALIZE_FUNCTION_NAME(Archive& ar, cls& obj)
101
102#define SAVE_EXTERN(cls) \
103 template<typename Archive> \
104 extern void SAVE_FUNCTION_NAME(Archive& ar, cls const& obj)
105
106#define LOAD_EXTERN(cls) \
107 template<typename Archive> \
108 extern void LOAD_FUNCTION_NAME(Archive& ar, cls& obj)
109
110#define SERIALIZE(cls) \
111 template<typename Archive> \
112 void SERIALIZE_FUNCTION_NAME(Archive& ar, cls& obj)
113
114#define SAVE(cls) \
115 template<typename Archive> \
116 void SAVE_FUNCTION_NAME(Archive& ar, cls const& obj)
117
118#define LOAD(cls) \
119 template<typename Archive> \
120 void LOAD_FUNCTION_NAME(Archive& ar, cls& obj)
121
122#define SERIALIZE_INSTANTIATE(cls, Archive) template void SERIALIZE_FUNCTION_NAME(Archive& archive, cls& obj)
123
124#define SAVE_INSTANTIATE(cls, Archive) template void SAVE_FUNCTION_NAME(Archive& archive, cls const& obj)
125
126#define LOAD_INSTANTIATE(cls, Archive) template void LOAD_FUNCTION_NAME(Archive& archive, cls& obj)
127
128template<typename Archive>
129constexpr inline auto is_binary_archive() -> bool
130{
131 return false;
132}
133
134template<typename Archive, typename T>
135inline auto try_serialize_direct(Archive& ar,
136 ser20::NameValuePair<T>&& t,
137 const hpp::source_location& loc = hpp::source_location::current()) -> bool
138{
139 try
140 {
141 ar(std::forward<ser20::NameValuePair<T>>(t));
142 }
143 catch(const ser20::Exception& e)
144 {
145 if constexpr(is_binary_archive<Archive>())
146 {
147 serialization::log_warning(e.what(), loc);
148 }
149 return false;
150 }
151 return true;
152}
153
154template<typename F>
155inline auto serialize_check(const std::string& name, F&& serialize_callback) -> bool
156{
157 auto path_ctx = serialization::get_path_context();
158 if(path_ctx)
159 {
161 auto path = path_ctx->get_current_path();
162 if(!path_ctx->should_serialize_property(path))
163 {
164 return false;
165 }
166 return serialize_callback();
167 }
168 return serialize_callback();
169}
170
171
172template<typename Archive, typename T>
173inline auto try_serialize(Archive& ar,
174 ser20::NameValuePair<T>&& t,
175 const hpp::source_location& loc = hpp::source_location::current()) -> bool
176{
177 bool result = serialize_check(t.name, [&]() -> bool
178 {
179 return try_serialize_direct(ar, std::forward<ser20::NameValuePair<T>>(t), loc);
180 });
181
182 return result;
183}
184
185
186template<typename Archive, typename T>
187inline auto try_save(Archive& ar,
188 ser20::NameValuePair<T>&& t,
189 const hpp::source_location& loc = hpp::source_location::current()) -> bool
190{
191 return try_serialize(ar, std::forward<ser20::NameValuePair<T>>(t), loc);
192}
193
194template<typename Archive, typename T>
195inline auto try_load(Archive& ar,
196 ser20::NameValuePair<T>&& t,
197 const hpp::source_location& loc = hpp::source_location::current()) -> bool
198{
199 return try_serialize(ar, std::forward<ser20::NameValuePair<T>>(t), loc);
200}
201
std::string name
Definition hub.cpp:27
Definition yaml.hpp:46
void log_warning(const std::string &log_msg, const hpp::source_location &loc)
auto get_current_deserialization_path() -> std::string
std::function< void(const std::string &, const hpp::source_location &loc)> log_callback_t
void set_path_context(path_context *ctx)
auto get_path_context() -> path_context *
void set_warning_logger(const std::function< void(const std::string &, const hpp::source_location &loc)> &logger)
auto try_serialize(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
auto try_save(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
auto try_serialize_direct(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
auto serialize_check(const std::string &name, F &&serialize_callback) -> bool
constexpr auto is_binary_archive() -> bool
auto try_load(Archive &ar, ser20::NameValuePair< T > &&t, const hpp::source_location &loc=hpp::source_location::current()) -> bool
auto get_current_path() const -> std::string
void push_segment(const std::string &segment, bool ignore_next=false)
auto should_serialize_property(const std::string &property_path) const -> bool
std::function< bool(const std::string &)> should_serialize_property_callback
auto is_recording() const -> bool
std::vector< std::string > path_segments
path_segment_guard(const std::string &segment, bool ignore_next_push=false)
path_segment_guard & operator=(const path_segment_guard &)=delete
path_segment_guard(const path_segment_guard &)=delete
path_segment_guard(path_segment_guard &&)=delete
path_segment_guard & operator=(path_segment_guard &&)=delete