Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
Serialization.h
Go to the documentation of this file.
1/* Serialization.h
2 JSON (de)serialization helpers for VideoGame, World, Level, Sector, Quest system.
3 Uses minimal nlohmann::json subset from Source/third_party/nlohmann/json.hpp
4*/
5#pragma once
6
7#include "third_party/nlohmann/json.hpp"
8#include "VideoGame.h"
9#include "World.h"
10#include "Level.h"
11#include "Sector.h"
12#include "CollisionMap.h"
13#include "GraphicMap.h"
14#include "QuestManager.h"
15#include "Quest.h"
16#include "Objective.h"
17#include "Task.h"
18
19#include <fstream>
20#include <iostream>
21#include <string>
22
23using nlohmann::json;
24
25// Task
26inline void to_json(json& j, Task const& t)
27{
28 j = json::object();
29 j["description"] = t.description;
30 j["completed"] = t.completed;
31}
32inline void from_json(json const& j, Task& t)
33{
34 if (j.contains("description")) t.description = j["description"].get<std::string>();
35 if (j.contains("completed")) t.completed = j["completed"].get<bool>();
36}
37
38// Objective
39inline void to_json(json& j, Objective const& o)
40{
41 j = json::object();
42 j["title"] = o.title;
43 j["tasks"] = json::array();
44 for (auto const& tp : o.tasks) j["tasks"].push_back(*tp);
45}
46inline void from_json(json const& j, Objective& o)
47{
48 if (j.contains("title")) o.title = j["title"].get<std::string>();
49 if (j.contains("tasks") && j["tasks"].is_array()) {
50 for (size_t i=0;i< j["tasks"].size();++i) {
51 Task t;
52 from_json(j["tasks"][i], t);
53 o.tasks.push_back(std::unique_ptr<Task>(new Task(t)));
54 }
55 }
56}
57
58// Quest
59inline void to_json(json& j, Quest const& q)
60{
61 j = json::object();
62 j["name"] = q.name;
63 j["objectives"] = json::array();
64 for (auto const& op : q.objectives) j["objectives"].push_back(*op);
65}
66inline void from_json(json const& j, Quest& q)
67{
68 if (j.contains("name")) q.name = j["name"].get<std::string>();
69 if (j.contains("objectives") && j["objectives"].is_array()) {
70 for (size_t i=0;i< j["objectives"].size();++i) {
72 from_json(j["objectives"][i], o);
73 q.objectives.push_back(std::unique_ptr<Objective>(new Objective(o)));
74 }
75 }
76}
77
78// QuestManager
79inline void to_json(json& j, QuestManager const& m)
80{
81 j = json::object();
82 j["quests"] = json::array();
83 for (auto const& qp : m.GetQuests()) j["quests"].push_back(*qp);
84}
85inline void from_json(json const& j, QuestManager& m)
86{
87 // clear existing quests? (singleton) - not implemented here
88 if (j.contains("quests") && j["quests"].is_array()) {
89 for (size_t i=0;i< j["quests"].size();++i) {
90 Quest q;
91 from_json(j["quests"][i], q);
92 m.AddQuest(std::unique_ptr<Quest>(new Quest(q)));
93 }
94 }
95}
96
97// CollisionMap
98inline void to_json(json& j, CollisionMap const& c)
99{
100 j = json::object();
101 j["data"] = json::array();
102 for (int v : c.data) j["data"].push_back(v);
103}
104inline void from_json(json const& j, CollisionMap& c)
105{
106 if (j.contains("data") && j["data"].is_array()) {
107 c.data.clear();
108 for (size_t i=0;i< j["data"].size();++i) c.data.push_back(j["data"][i].get<int>());
109 }
110}
111
112// GraphicMap
113inline void to_json(json& j, GraphicMap const& g)
114{
115 j = json::object();
116 j["elements"] = json::array();
117 for (auto const& e : g.elements) j["elements"].push_back(e);
118}
119inline void from_json(json const& j, GraphicMap& g)
120{
121 if (j.contains("elements") && j["elements"].is_array()) {
122 g.elements.clear();
123 for (size_t i=0;i< j["elements"].size();++i) g.elements.push_back(j["elements"][i].get<std::string>());
124 }
125}
126
127// Sector
128inline void to_json(json& j, Sector const& s)
129{
130 j = json::object();
131 j["name"] = s.name;
132 if (s.collision) j["collision"] = *s.collision; else j["collision"] = nullptr;
133 if (s.graphics) j["graphics"] = *s.graphics; else j["graphics"] = nullptr;
134}
135inline void from_json(json const& j, Sector& s)
136{
137 if (j.contains("name")) s.name = j["name"].get<std::string>();
138 if (j.contains("collision") && !j["collision"].is_null()) {
139 s.collision = std::unique_ptr<CollisionMap>(new CollisionMap());
140 from_json(j["collision"], *s.collision);
141 }
142 if (j.contains("graphics") && !j["graphics"].is_null()) {
143 s.graphics = std::unique_ptr<GraphicMap>(new GraphicMap());
144 from_json(j["graphics"], *s.graphics);
145 }
146}
147
148// Level
149inline void to_json(json& j, Level const& l)
150{
151 j = json::object();
152 j["name"] = l.name;
153 j["sectors"] = json::array();
154 for (auto const& sp : l.sectors) j["sectors"].push_back(*sp);
155}
156inline void from_json(json const& j, Level& l)
157{
158 if (j.contains("name")) l.name = j["name"].get<std::string>();
159 if (j.contains("sectors") && j["sectors"].is_array()) {
160 for (size_t i=0;i< j["sectors"].size();++i) {
161 Sector s;
162 from_json(j["sectors"][i], s);
163 l.sectors.push_back(std::unique_ptr<Sector>(new Sector(s)));
164 }
165 }
166}
167
168// World
169inline void to_json(json& j, World const& w)
170{
171 j = json::object();
172 j["name"] = w.name;
173 j["levels"] = json::array();
174 for (auto const& lp : w.GetLevels()) j["levels"].push_back(*lp);
175}
176inline void from_json(json const& j, World& w)
177{
178 if (j.contains("name")) w.name = j["name"].get<std::string>();
179 if (j.contains("levels") && j["levels"].is_array()) {
180 for (size_t i=0;i< j["levels"].size();++i) {
181 Level l;
182 from_json(j["levels"][i], l);
183 w.AddLevel(std::unique_ptr<Level>(new Level(l)));
184 }
185 }
186}
187
188// VideoGame
189inline void to_json(json& j, VideoGame const& vg)
190{
191 j = json::object();
192 j["schema_version"] =1;
193 j["type"] = "VideoGame";
194 j["rules"] = vg.GetRules().name;
195 j["world"] = vg.GetWorld();
196 // QuestManager singleton
197 j["quests"] = json::array();
198 for (auto const& qp : QuestManager::Get().GetQuests()) j["quests"].push_back(*qp);
199}
200inline void from_json(json const& j, VideoGame& vg)
201{
202 if (j.contains("rules")) vg.GetRules().name = j["rules"].get<std::string>();
203 if (j.contains("world")) {
204 World w;
205 from_json(j["world"], w);
206 vg.GetWorld() = std::move(w); // won't compile for unique_ptr reference; handled via clear/add
207 }
208 if (j.contains("quests") && j["quests"].is_array()) {
209 for (size_t i=0;i< j["quests"].size();++i) {
210 Quest q;
211 from_json(j["quests"][i], q);
212 QuestManager::Get().AddQuest(std::unique_ptr<Quest>(new Quest(q)));
213 }
214 }
215}
216
217// File I/O helpers
218inline bool SaveToFile(const json& j, const std::string& path)
219{
220 std::ofstream ofs(path);
221 if (!ofs) return false;
222 ofs << j.dump(2);
223 return true;
224}
225inline bool LoadFromFile(json& j, const std::string& path)
226{
227 std::ifstream ifs(path);
228 if (!ifs) return false;
229 std::ostringstream ss;
230 ss << ifs.rdbuf();
231 try {
232 j = json::parse(ss.str());
233 } catch (std::exception& e) {
234 std::cerr << "JSON parse error: " << e.what() << std::endl;
235 return false;
236 }
237 return true;
238}
toVisit push_back(childId)
nlohmann::json json
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
bool SaveToFile(const json &j, const std::string &path)
void from_json(json const &j, Task &t)
void to_json(json &j, Task const &t)
bool LoadFromFile(json &j, const std::string &path)
World and ECS Manager for Olympe Engine.
std::vector< std::string > elements
Definition GraphicMap.h:16
Definition Level.h:13
static QuestManager & Get()
void AddQuest(std::unique_ptr< Quest > q)
const std::vector< std::unique_ptr< Quest > > & GetQuests() const
Definition Quest.h:14
Definition Task.h:11
Core ECS manager and world coordinator.
Definition World.h:210
nlohmann::json json