SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
Serializable.cpp
Go to the documentation of this file.
3#include <fstream>
4#include <sstream>
5
6namespace YAML {
7 /// Lets YAML::Node hold a std::any for int/float/string; anything else throws.
8 template <>
9 struct convert<std::any> {
10 static Node encode(const std::any& rhs) {
11 Node node;
12 if (rhs.type() == typeid(int)) {
13 node = std::any_cast<int>(rhs);
14 } else if (rhs.type() == typeid(float)) {
15 node = std::any_cast<float>(rhs);
16 } else if (rhs.type() == typeid(std::string)) {
17 node = std::any_cast<std::string>(rhs);
18 } else {
19 throw std::runtime_error("Unsupported type for YAML serialization");
20 }
21 return node;
22 }
23
24 static bool decode(const Node& node, std::any& rhs) {
25 try {
26 if (node.IsScalar()) {
27 std::string value = node.as<std::string>();
28 rhs = value; // Store as std::any(std::string)
29 return true;
30 }
31 } catch (...) {
32 return false;
33 }
34 return false;
35 }
36 };
37}
38
39namespace Sleak {
40
41 /// ISerializationContext backed by an in-memory key/value map. WriteToStream
42 /// and ReadFromStream are stubs and always throw.
44 public:
45 std::unordered_map<std::string, std::any> Data;
46
47 void Write(const std::string& key, const std::any& value) override {
48 Data[key] = value;
49 }
50
51 std::any Read(const std::string& key) const override {
52 auto it = Data.find(key);
53 if (it == Data.end()) {
54 throw std::runtime_error("Key not found: " + key);
55 }
56 return it->second;
57 }
58
59 void WriteToStream(std::ostream& stream) const override {
60 for (const auto& [key, value] : Data) {
61 // (Implementation depends on the data types)
62 }
63 throw Sleak::NotImplementedException("This method is not completed yet");
64 }
65
66 void ReadFromStream(std::istream& stream) override {
67 // (Implementation depends on the data types)
68 throw Sleak::NotImplementedException("This method is not completed yet");
69 }
70 };
71
72 /// ISerializationContext backed by nlohmann::json.
74 public:
75 nlohmann::json JsonData;
76
77 void Write(const std::string& key, const std::any& value) override {
78 if (value.type() == typeid(int)) {
79 JsonData[key] = std::any_cast<int>(value);
80 } else if (value.type() == typeid(float)) {
81 JsonData[key] = std::any_cast<float>(value);
82 } else if (value.type() == typeid(std::string)) {
83 JsonData[key] = std::any_cast<std::string>(value);
84 }
85 // Add more type conversions as needed
86 }
87
88 std::any Read(const std::string& key) const override {
89 if (!JsonData.contains(key)) {
90 throw std::runtime_error("Key not found: " + key);
91 }
92 return JsonData[key];
93 }
94
95 void WriteToStream(std::ostream& stream) const override {
96 stream << JsonData.dump(4); // Pretty-print JSON
97 }
98
99 void ReadFromStream(std::istream& stream) override {
100 stream >> JsonData;
101 }
102 };
103
104 /// ISerializationContext backed by a YAML::Node.
106 public:
107 YAML::Node YamlData;
108
109 void Write(const std::string& key, const std::any& value) override {
110 if (value.type() == typeid(int)) {
111 YamlData[key] = std::any_cast<int>(value);
112 } else if (value.type() == typeid(float)) {
113 YamlData[key] = std::any_cast<float>(value);
114 } else if (value.type() == typeid(std::string)) {
115 YamlData[key] = std::any_cast<std::string>(value);
116 }
117 // Add more type conversions as needed
118 }
119
120 std::any Read(const std::string& key) const override {
121 if (!YamlData[key]) {
122 throw std::runtime_error("Key not found: " + key);
123 }
124 return YamlData[key].as<std::any>();
125 }
126
127 void WriteToStream(std::ostream& stream) const override {
128 stream << YamlData;
129 }
130
131 void ReadFromStream(std::istream& stream) override {
132 YamlData = YAML::Load(stream);
133 }
134 };
135
136 // Serializable methods
137 void Serializable::SerializeToFile(const std::string& filePath) const {
138 auto format = SerializationFactory::DetectFormat(filePath);
139 auto context = SerializationFactory::CreateContext(format);
140
141 std::ofstream file(filePath);
142 if (!file.is_open()) {
143 throw std::runtime_error("Failed to open file for writing: " + filePath);
144 }
145
146 Serialize(std::move(context));
147 context->WriteToStream(file);
148 }
149
150 void Serializable::DeserializeFromFile(const std::string& filePath) {
151 auto format = SerializationFactory::DetectFormat(filePath);
152 auto context = SerializationFactory::CreateContext(format);
153
154 std::ifstream file(filePath);
155 if (!file.is_open()) {
156 throw std::runtime_error("Failed to open file for reading: " + filePath);
157 }
158
159 context->ReadFromStream(file);
160 Deserialize(std::move(context));
161 }
162
163 // SerializationFactory methods
165 if (filePath.ends_with(".bin")) {
167 } else if (filePath.ends_with(".json")) {
169 } else if (filePath.ends_with(".yaml") || filePath.ends_with(".yml")) {
170 return SerializationFormat::YAML;
171 }
173 }
174
175 std::unique_ptr<ISerializationContext> SerializationFactory::CreateContext(SerializationFormat format) {
176 switch (format) {
178 return std::make_unique<BinarySerializationContext>();
180 return std::make_unique<JsonSerializationContext>();
181 case SerializationFormat::YAML:
182 return std::make_unique<YamlSerializationContext>();
183 default:
184 throw std::runtime_error("Unsupported serialization format.");
185 }
186 }
187
188} // namespace Sleak
void Write(const std::string &key, const std::any &value) override
std::any Read(const std::string &key) const override
void WriteToStream(std::ostream &stream) const override
void ReadFromStream(std::istream &stream) override
std::unordered_map< std::string, std::any > Data
Interface for serialization contexts.
ISerializationContext backed by nlohmann::json.
void ReadFromStream(std::istream &stream) override
void Write(const std::string &key, const std::any &value) override
void WriteToStream(std::ostream &stream) const override
std::any Read(const std::string &key) const override
void DeserializeFromFile(const std::string &filePath)
Deserializes the object from a file.
void SerializeToFile(const std::string &filePath) const
Serializes the object to a file.
virtual void Serialize(std::unique_ptr< ISerializationContext > context) const =0
Serializes the object using the specified context.
virtual void Deserialize(std::unique_ptr< ISerializationContext > context)=0
Deserializes the object using the specified context.
static std::unique_ptr< ISerializationContext > CreateContext(SerializationFormat format)
Builds the context implementation matching format.
static SerializationFormat DetectFormat(const std::string &filePath)
Picks a format from filePath's extension (.bin/.json/.yaml/.yml).
ISerializationContext backed by a YAML::Node.
void Write(const std::string &key, const std::any &value) override
std::any Read(const std::string &key) const override
void ReadFromStream(std::istream &stream) override
void WriteToStream(std::ostream &stream) const override
SerializationFormat
Root namespace for everything the engine exposes.
Definition Camera.hpp:10