Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
TemplateManager.cpp
Go to the documentation of this file.
1/*
2 * Olympe Blueprint Editor - Template Manager Implementation
3 */
4
5#include "TemplateManager.h"
6#include <fstream>
7#include <sstream>
8#include <iomanip>
9#include <iostream>
10#include <random>
11#ifndef _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
12#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
13#endif
14#include <experimental/filesystem>
15
16namespace fs = std::experimental::filesystem;
17
18namespace Olympe
19{
20 // ========================================================================
21 // BlueprintTemplate Implementation
22 // ========================================================================
23
25 : createdDate(0)
26 , modifiedDate(0)
27 {
28 }
29
31 {
32 json j;
33 j["id"] = id;
34 j["name"] = name;
35 j["description"] = description;
36 j["category"] = category;
37 j["author"] = author;
38 j["version"] = version;
39 j["thumbnailPath"] = thumbnailPath;
40 j["createdDate"] = static_cast<double>(createdDate);
41 j["modifiedDate"] = static_cast<double>(modifiedDate);
42 j["blueprintData"] = blueprintData;
43
44 return j;
45 }
46
48 {
50
51 if (j.contains("id")) tpl.id = j["id"].get<std::string>();
52 if (j.contains("name")) tpl.name = j["name"].get<std::string>();
53 if (j.contains("description")) tpl.description = j["description"].get<std::string>();
54 if (j.contains("category")) tpl.category = j["category"].get<std::string>();
55 if (j.contains("author")) tpl.author = j["author"].get<std::string>();
56 if (j.contains("version")) tpl.version = j["version"].get<std::string>();
57 if (j.contains("thumbnailPath")) tpl.thumbnailPath = j["thumbnailPath"].get<std::string>();
58 if (j.contains("createdDate")) tpl.createdDate = static_cast<time_t>(j["createdDate"].get<double>());
59 if (j.contains("modifiedDate")) tpl.modifiedDate = static_cast<time_t>(j["modifiedDate"].get<double>());
60 if (j.contains("blueprintData")) tpl.blueprintData = j["blueprintData"];
61
62 return tpl;
63 }
64
65 bool BlueprintTemplate::SaveToFile(const std::string& filepath) const
66 {
67 try
68 {
69 std::ofstream file(filepath);
70 if (!file.is_open())
71 {
72 std::cerr << "Failed to open file for writing: " << filepath << std::endl;
73 return false;
74 }
75
76 json j = ToJson();
77 file << j.dump(4); // Pretty print with 4-space indent
78 file.close();
79
80 return true;
81 }
82 catch (const std::exception& e)
83 {
84 std::cerr << "Error saving template to file: " << e.what() << std::endl;
85 return false;
86 }
87 }
88
90 {
91 try
92 {
93 std::ifstream file(filepath);
94 if (!file.is_open())
95 {
96 std::cerr << "Failed to open template file: " << filepath << std::endl;
97 return BlueprintTemplate();
98 }
99
100 json j;
101 std::stringstream buffer;
102 buffer << file.rdbuf();
103 j = json::parse(buffer.str());
104
105 return FromJson(j);
106 }
107 catch (const std::exception& e)
108 {
109 std::cerr << "Error loading template from file: " << e.what() << std::endl;
110 return BlueprintTemplate();
111 }
112 }
113
114 // ========================================================================
115 // TemplateManager Implementation
116 // ========================================================================
117
123
125 : m_Initialized(false)
126 {
127 }
128
132
134 {
136 m_Templates.clear();
137 m_LastError.clear();
138
139 // Ensure templates directory exists
141 {
142 m_LastError = "Failed to create templates directory: " + m_TemplatesPath;
143 std::cerr << m_LastError << std::endl;
144 }
145
146 // Load all templates from directory
148
149 m_Initialized = true;
150 }
151
153 {
154 m_Templates.clear();
155 m_Initialized = false;
156 }
157
159 {
161 m_Templates.clear();
162 m_LastError.clear();
163
164 if (!fs::exists(templatesPath))
165 {
166 m_LastError = "Templates directory does not exist: " + templatesPath;
167 std::cerr << m_LastError << std::endl;
168 return false;
169 }
170
172 return true;
173 }
174
176 {
177 if (tpl.id.empty())
178 {
179 m_LastError = "Template ID is empty";
180 return false;
181 }
182
183 // Construct filename from template ID
184 std::string filename = tpl.id + ".json";
185 std::string filepath = m_TemplatesPath + "/" + filename;
186
187 // Save to file
188 if (!tpl.SaveToFile(filepath))
189 {
190 m_LastError = "Failed to save template to file: " + filepath;
191 return false;
192 }
193
194 // Update in-memory catalog
195 // Check if template already exists
196 bool found = false;
197 for (auto& existingTpl : m_Templates)
198 {
199 if (existingTpl.id == tpl.id)
200 {
202 found = true;
203 break;
204 }
205 }
206
207 // If not found, add to catalog
208 if (!found)
209 {
210 m_Templates.push_back(tpl);
211 }
212
213 return true;
214 }
215
217 {
218 if (templateId.empty())
219 {
220 m_LastError = "Template ID is empty";
221 return false;
222 }
223
224 // Find template in catalog
225 auto it = std::find_if(m_Templates.begin(), m_Templates.end(),
226 [&templateId](const BlueprintTemplate& tpl) {
227 return tpl.id == templateId;
228 });
229
230 if (it == m_Templates.end())
231 {
232 m_LastError = "Template not found: " + templateId;
233 return false;
234 }
235
236 // Delete file
237 std::string filename = templateId + ".json";
238 std::string filepath = m_TemplatesPath + "/" + filename;
239
240 try
241 {
242 if (fs::exists(filepath))
243 {
244 fs::remove(filepath);
245 }
246 }
247 catch (const std::exception& e)
248 {
249 m_LastError = "Failed to delete template file: " + std::string(e.what());
250 std::cerr << m_LastError << std::endl;
251 return false;
252 }
253
254 // Remove from catalog
255 m_Templates.erase(it);
256
257 return true;
258 }
259
264
265 const BlueprintTemplate* TemplateManager::FindTemplate(const std::string& id) const
266 {
267 for (const auto& tpl : m_Templates)
268 {
269 if (tpl.id == id)
270 {
271 return &tpl;
272 }
273 }
274 return nullptr;
275 }
276
277 std::vector<BlueprintTemplate> TemplateManager::GetTemplatesByCategory(const std::string& category) const
278 {
279 std::vector<BlueprintTemplate> result;
280
281 for (const auto& tpl : m_Templates)
282 {
283 if (tpl.category == category)
284 {
285 result.push_back(tpl);
286 }
287 }
288
289 return result;
290 }
291
292 std::vector<std::string> TemplateManager::GetAllCategories() const
293 {
294 std::vector<std::string> categories;
295
296 for (const auto& tpl : m_Templates)
297 {
298 // Check if category already exists in list
299 if (std::find(categories.begin(), categories.end(), tpl.category) == categories.end())
300 {
301 categories.push_back(tpl.category);
302 }
303 }
304
305 return categories;
306 }
307
309 {
311 if (!tpl)
312 {
313 m_LastError = "Template not found: " + templateId;
314 return false;
315 }
316
317 // Copy blueprint data from template
318 targetBlueprint = tpl->blueprintData;
319
320 return true;
321 }
322
324 const json& blueprint,
325 const std::string& name,
326 const std::string& description,
327 const std::string& category,
328 const std::string& author)
329 {
331
332 tpl.id = GenerateUUID();
333 tpl.name = name;
334 tpl.description = description;
335 tpl.category = category;
336 tpl.author = author;
337 tpl.version = "1.0";
338 tpl.blueprintData = blueprint;
339 tpl.thumbnailPath = "";
340 tpl.createdDate = std::time(nullptr);
341 tpl.modifiedDate = tpl.createdDate;
342
343 return tpl;
344 }
345
347 {
348 // Simple UUID generation using random hex values
349 std::random_device rd;
350 std::mt19937 gen(rd());
351 std::uniform_int_distribution<> dis(0, 15);
352
353 const char* hexChars = "0123456789abcdef";
354 std::string uuid;
355
356 for (int i = 0; i < 8; i++) uuid += hexChars[dis(gen)];
357 uuid += "-";
358 for (int i = 0; i < 4; i++) uuid += hexChars[dis(gen)];
359 uuid += "-";
360 for (int i = 0; i < 4; i++) uuid += hexChars[dis(gen)];
361 uuid += "-";
362 for (int i = 0; i < 4; i++) uuid += hexChars[dis(gen)];
363 uuid += "-";
364 for (int i = 0; i < 12; i++) uuid += hexChars[dis(gen)];
365
366 return uuid;
367 }
368
370 {
371 if (!fs::exists(m_TemplatesPath) || !fs::is_directory(m_TemplatesPath))
372 {
373 return;
374 }
375
376 try
377 {
378 for (const auto& entry : fs::directory_iterator(m_TemplatesPath))
379 {
380 // Correction : utiliser fs::is_regular_file(entry.path()) au lieu de entry.is_regular_file()
381 if (fs::is_regular_file(entry.path()) && entry.path().extension() == ".json")
382 {
384
385 // Only add if successfully loaded (has ID)
386 if (!tpl.id.empty())
387 {
388 m_Templates.push_back(tpl);
389 }
390 }
391 }
392 }
393 catch (const std::exception& e)
394 {
395 m_LastError = "Error scanning template directory: " + std::string(e.what());
396 std::cerr << m_LastError << std::endl;
397 }
398 }
399
400 bool TemplateManager::EnsureDirectoryExists(const std::string& path)
401 {
402 try
403 {
404 if (!fs::exists(path))
405 {
406 fs::create_directories(path);
407 }
408 return true;
409 }
410 catch (const std::exception& e)
411 {
412 std::cerr << "Failed to create directory: " << path << " - " << e.what() << std::endl;
413 return false;
414 }
415 }
416}
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
static std::mt19937 gen(rd())
static std::random_device rd
TemplateManager - Manages blueprint templates Singleton manager for template catalog and operations.
bool SaveTemplate(const BlueprintTemplate &tpl)
void Initialize(const std::string &templatesPath="Blueprints/Templates")
std::string GenerateUUID() const
bool DeleteTemplate(const std::string &templateId)
std::vector< BlueprintTemplate > m_Templates
bool EnsureDirectoryExists(const std::string &path)
std::vector< BlueprintTemplate > GetTemplatesByCategory(const std::string &category) const
bool ApplyTemplateToBlueprint(const std::string &templateId, json &targetBlueprint)
static TemplateManager & Instance()
const BlueprintTemplate * FindTemplate(const std::string &id) const
bool LoadTemplates(const std::string &templatesPath)
BlueprintTemplate CreateTemplateFromBlueprint(const json &blueprint, const std::string &name, const std::string &description, const std::string &category, const std::string &author="User")
std::vector< std::string > GetAllCategories() const
nlohmann::json json
BlueprintTemplate - Template metadata and data Stores a complete blueprint that can be reused as a te...
static BlueprintTemplate LoadFromFile(const std::string &filepath)
static BlueprintTemplate FromJson(const json &j)
bool SaveToFile(const std::string &filepath) const