galaxy 1.0.0
Real-Time C++23 Game Programming Framework. Built on data-driven design principles and agile software engineering.
Loading...
Searching...
No Matches
SceneManager.cpp
Go to the documentation of this file.
1
7
8#include <nlohmann/json.hpp>
9
10#include "SceneManager.hpp"
11
12namespace galaxy
13{
15 : StateMachine {}
16 {
17 }
18
23
25 {
26 if (this != &w)
27 {
28 StateMachine::operator=(std::move(w));
29 }
30
31 return *this;
32 }
33
38
39 void SceneManager::on_event(SDL_Event& event)
40 {
41 if (auto scene = top())
42 {
43 scene->on_event(event);
44 }
45 }
46
48 {
49 if (auto scene = top())
50 {
51 scene->update(m_entity_manager);
52 }
53 }
54
56 {
57 if (auto scene = top())
58 {
59 scene->render();
60 }
61 }
62
64 {
65 pop_all();
66
67 m_stack.clear();
68 m_storage.clear();
69 }
70
71 nlohmann::json SceneManager::serialize()
72 {
73 nlohmann::json json = "{\"scenes\":{}}"_json;
74
75 for (auto& [id, scene] : m_storage)
76 {
77 json["scenes"][scene->name()] = scene->serialize();
78 }
79
80 for (auto i = 0; i < m_stack.size(); i++)
81 {
82 json["stack"][std::to_string(i)] = m_stack[i]->name();
83 }
84
85 /*
86 auto& em = entt::locator<meta::EntityFactory>::value();
87 json["entities"] = nlohmann::json::array();
88 for (const auto& [entity] : m_registry.m_entt.view<entt::entity>(entt::exclude<flags::NotSerializable>).each())
89 {
90 json["entities"].push_back(em.serialize_entity(entity, m_registry.m_entt));
91 }
92 */
93
94 return json;
95 }
96
97 void SceneManager::deserialize(const nlohmann::json& json)
98 {
99 /*auto& em = entt::locator<meta::EntityFactory>::value();
100
101 pop_all();
102 clear();
103
104 const auto& scenes = json.at("scenes");
105 m_scenes.reserve(scenes.size());
106 for (const auto& [name, data] : scenes.items())
107 {
108 auto scene = create(name);
109 if (scene)
110 {
111 scene->deserialize(data);
112 }
113 }
114
115 const auto& stack = json.at("stack");
116 m_stack.reserve(stack.size());
117 for (const auto& [index, name] : stack.items())
118 {
119 const auto hash = math::fnv1a(name.get<std::string>().c_str());
120 m_stack.insert(m_stack.begin() + std::stoi(index), m_scenes[hash]);
121 }
122
123 const auto& entity_json = json.at("entities");
124 for (const auto& data : entity_json)
125 {
126 const auto entity = em.deserialize_entity(data, m_registry.m_entt);
127
128 if (!m_registry.m_entt.all_of<components::Tag>(entity))
129 {
130 auto& tag = m_registry.m_entt.emplace<components::Tag>(entity);
131 tag.m_tag = "Untagged";
132 }
133 }*/
134 }
135} // namespace galaxy
136
137/*
138void SceneManager::load_app(const std::string& appdata_file)
139 {
140 const auto data = core::ServiceLocator<fs::VirtualFileSystem>::ref().read(appdata_file);
141 if (!data.empty())
142 {
143 const auto decoded_zlib = math::decode_zlib(data);
144 if (!decoded_zlib.empty())
145
146 {
147 const auto decoded_base64 = math::decode_base64(decoded_zlib);
148 if (!decoded_base64.empty())
149 {
150 const auto parsed = nlohmann::json::parse(decoded_base64);
151
152 if (!parsed.empty())
153 {
154 deserialize(parsed);
155 }
156 else
157 {
158 GALAXY_LOG(GALAXY_ERROR, "Failed to parse scenemanger JSON data from memory.");
159 }
160 }
161 else
162 {
163 GALAXY_LOG(GALAXY_ERROR, "Failed to decode base64 appdata '{0}'.", appdata_file);
164 }
165 }
166 else
167 {
168 GALAXY_LOG(GALAXY_ERROR, "Failed to decode zlib appdata '{0}'.", appdata_file);
169 }
170 }
171 else
172 {
173 GALAXY_LOG(GALAXY_ERROR, "Failed to load appdata '{0}'.", appdata_file);
174 }
175 }
176
177 void SceneManager::save_app(const std::string& file)
178 {
179 const auto json = serialize();
180
181 if (!json::write(file, json))
182 {
183 GALAXY_LOG(GALAXY_ERROR, "Failed to save '{0}' to disk.", file);
184 }
185 }
186
187 void SceneManager::update()
188 {
189 for (auto&& system : m_systems)
190 {
191 system->update(m_current->m_registry.m_entt);
192
193 if (m_current->m_world.get_active())
194 {
195 system->update(m_current->m_world.get_active()->m_registry.m_entt);
196 }
197 }
198 }
199
200 void SceneManager::only_update_rendering()
201 {
202 if ((m_rendersystem_index >= 0 && m_rendersystem_index < m_systems.size()) && m_current != nullptr)
203 {
204 m_systems[m_rendersystem_index]->update(m_current->m_registry.m_entt);
205
206 if (m_current->m_world.get_active())
207 {
208 m_systems[m_rendersystem_index]->update(m_current->m_world.get_active()->m_registry.m_entt);
209 }
210 }
211 }
212
213 nlohmann::json SceneManager::serialize()
214 {
215 nlohmann::json json = "{\"scenes\":{}}"_json;
216
217 for (auto& [name, scene] : m_scenes)
218 {
219 json["scenes"][scene->m_name] = scene->serialize();
220 }
221
222 if (m_current)
223 {
224 json["current"] = m_current->m_name;
225 }
226
227 return json;
228 }
229
230 void SceneManager::deserialize(const nlohmann::json& json)
231 {
232 clear();
233
234 const auto& scenes = json.at("scenes");
235
236 m_scenes.reserve(scenes.size());
237 for (const auto& [name, data] : scenes.items())
238 {
239 auto scene = add(name);
240 if (scene)
241 {
242 scene->deserialize(data);
243 }
244 }
245
246 if (json.contains("current"))
247 {
248 set_scene(json.at("current"));
249 }
250 }
251
252 void SceneManager::load_app(const std::string& appdata_file)
253 {
254 std::ifstream in(appdata_file, std::ifstream::in);
255
256 std::stringstream buffer;
257 buffer << in.rdbuf();
258
259 auto data = buffer.str();
260 if (!data.empty())
261 {
262 if constexpr (!GALAXY_DEBUG_BUILD)
263 {
264 data = math::decode_zlib(data);
265 if (!data.empty())
266 {
267 data = math::decode_base64(data);
268 if (data.empty())
269 {
270 GALAXY_LOG(GALAXY_ERROR, "Failed to decode base64 appdata '{0}'.", appdata_file);
271 }
272 }
273 else
274 {
275 GALAXY_LOG(GALAXY_ERROR, "Failed to decode zlib appdata '{0}'.", appdata_file);
276 }
277
278 if (data.empty())
279 {
280 return;
281 }
282 }
283
284 const auto parsed = nlohmann::json::parse(data);
285
286 if (!parsed.empty())
287 {
288 deserialize(parsed);
289 }
290 else
291 {
292 GALAXY_LOG(GALAXY_ERROR, "Failed to parse scenemanger JSON data from memory.");
293 }
294 }
295 else
296 {
297 GALAXY_LOG(GALAXY_ERROR, "Failed to load appdata '{0}'.", appdata_file);
298 }
299 }
300
301 void SceneManager::save_app(const std::string& file)
302 {
303 const auto json = serialize();
304 auto data = json::dump(json);
305
306 if constexpr (!GALAXY_DEBUG_BUILD)
307 {
308 data = math::encode_base64(data);
309 if (!data.empty())
310 {
311 data = math::encode_zlib(data);
312 if (data.empty())
313 {
314 GALAXY_LOG(GALAXY_ERROR, "Failed to encode scenemanager to zlib '{0}'.", file);
315 }
316 }
317 else
318 {
319 GALAXY_LOG(GALAXY_ERROR, "Failed to encode scenemanager to base64 '{0}'.", file);
320 }
321
322 if (data.empty())
323 {
324 return;
325 }
326 }
327
328 auto& fs = entt::locator<fs::VirtualFileSystem>::value();
329 if (!fs.write(data, file))
330 {
331 GALAXY_LOG(GALAXY_ERROR, "Failed to save '{0}' to disk.", file);
332 }
333 }
334
335
336*/
State machine for managing scenes.
void update()
Process events and updates.
void on_event(SDL_Event &event)
Handle an event for a scene.
virtual ~SceneManager()
Destructor.
void clear()
Removes all data.
nlohmann::json serialize()
Serializes object.
void deserialize(const nlohmann::json &json)
Deserializes from object.
EntityManager m_entity_manager
Entities belonging to all scenes.
SceneManager & operator=(SceneManager &&)
Move assignment operator.
void render()
Render scenes.
SceneManager() noexcept
Constructor.
A finite state machine.
StateMachine< Stored > & operator=(StateMachine< Stored > &&)
Move assignment operator.
std::shared_ptr< Stored > top() const noexcept
Application.hpp galaxy.
STL namespace.