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