29#include "sdl3_image/sdl_image.h"
31#include "third_party/nlohmann/json.hpp"
69 SYSTEM_LOG <<
"DataManager Shutdown - unloading all resources\n";
76 if (
id.
empty() || path.empty())
return false;
88 SYSTEM_LOG <<
"DataManager::PreloadTexture IMG_Load failed for '" << path <<
"' : " <<
SDL_GetError() <<
"\n";
99 SYSTEM_LOG <<
"DataManager::PreloadTexture SDL_CreateTextureFromSurface failed for '" << path <<
"' : " <<
SDL_GetError() <<
"\n";
110 auto res = std::make_shared<Resource>();
112 res->category = category;
115 res->sprite_texture =
tex;
128 SYSTEM_LOG <<
"DataManager: Loaded texture '" <<
id <<
"' from '" << path <<
"'\n";
142 auto res =
it->second;
143 if (
res->sprite_texture)
return res->sprite_texture;
155 res->sprite_texture =
tex;
159 return res->sprite_texture;
163 SYSTEM_LOG <<
"DataManager: Failed to create deferred texture for '" <<
id <<
"' : " <<
SDL_GetError() <<
"\n";
178 return it->second->sprite_texture;
197 outData.srcRect = { 0.0f, 0.0f,
static_cast<float>(
w),
static_cast<float>(
h) };
202 SYSTEM_LOG <<
"DataManager: GetSprite_data failed for '" <<
id <<
"' file/path '" << path <<
"' does not exists or is incorrect\n";
213 outData.srcRect = { 0.0f, 0.0f,
static_cast<float>(
w),
static_cast<float>(
h) };
217 SYSTEM_LOG <<
"DataManager: GetSpriteEditor_data failed for '" <<
id <<
"' file/path '" << path <<
"' does not exists or is incorrect\n";
226 auto res =
it->second;
228 if (
res->sprite_texture)
231 res->sprite_texture =
nullptr;
242 SYSTEM_LOG <<
"DataManager: Released resource '" <<
id <<
"'\n";
251 auto res =
kv.second;
252 if (
res->sprite_texture)
255 res->sprite_texture =
nullptr;
275 std::vector<std::string>
out;
281 if (
kv.second->type == type)
out.push_back(
kv.first);
288 std::vector<std::string>
out;
294 if (
kv.second->category == category)
out.push_back(
kv.first);
303 std::string
obj = objectName.empty() ? std::string(
"object") : objectName;
304 std::string path = std::string(
".") +
"/Gamedata/" +
game +
"/" +
obj +
".json";
310 if (filepath.empty())
return false;
312 auto pos = filepath.find_last_of(
"/\\");
313 if (
pos != std::string::npos)
315 std::string
dir = filepath.substr(0,
pos);
318 SYSTEM_LOG <<
"DataManager: Failed to ensure directory exists for '" <<
dir <<
"'\n";
323 std::ofstream
ofs(filepath.c_str(), std::ios::binary | std::ios::trunc);
324 if (!
ofs)
return false;
332 if (filepath.empty())
return false;
333 std::ifstream
ifs(filepath.c_str(), std::ios::binary);
334 if (!
ifs)
return false;
335 std::ostringstream
ss;
355 if (
dirpath.empty())
return false;
359 std::replace(path.begin(), path.end(),
'\\',
'/');
361 if (!path.empty() && path.back() ==
'/') path.pop_back();
362 if (path.empty())
return true;
368 if (!path.empty() && path[0] ==
'/') {
accum =
"/";
pos = 1; }
372 size_t next = path.find(
'/',
pos);
397 if (
next == std::string::npos)
break;
416 if (!
root.contains(
"system_resources"))
return true;
417 const auto&
arr =
root[
"system_resources"];
418 if (!
arr.is_array())
return false;
419 for (
size_t i = 0;
i <
arr.size(); ++
i)
422 if (!
item.is_object())
continue;
423 std::string
id =
item.contains(
"id") ?
item[
"id"].get<std::string>() : std::string();
424 std::string path =
item.contains(
"path") ?
item[
"path"].get<std::string>() : std::string();
425 std::string type =
item.contains(
"type") ?
item[
"type"].get<std::string>() : std::string();
426 if (
id.
empty() || path.empty())
continue;
427 if (type ==
"texture")
432 if (type ==
"sprite" || type ==
"animation")
442 catch (
const std::exception&
e)
444 SYSTEM_LOG <<
"DataManager: JSON parse error in PreloadSystemResources: " <<
e.what() <<
"\n";
456 const std::vector<std::string>&
paths,
463 for (
const auto& path :
paths)
465 if (path.empty())
continue;
468 std::string
id = path;
469 size_t lastSlash =
id.find_last_of(
"/\\");
479 SYSTEM_LOG <<
" -> Loaded texture: " << path <<
"\n";
497 SYSTEM_LOG <<
" x Failed to load texture: " << path <<
"\n";
504 SYSTEM_LOG <<
" x Failed to load texture: " << path <<
"\n";
512 const std::vector<std::string>&
paths,
519 for (
const auto& path :
paths)
521 if (path.empty())
continue;
524 std::string
id = path;
525 size_t lastSlash =
id.find_last_of(
"/\\");
535 SYSTEM_LOG <<
" -> Loaded sprite: " << path <<
"\n";
553 SYSTEM_LOG <<
" x Failed to load sprite: " << path <<
"\n";
560 SYSTEM_LOG <<
" x Failed to load sprite: " << path <<
"\n";
568 const std::vector<std::string>&
paths,
575 for (
const auto& path :
paths)
577 if (path.empty())
continue;
578 SYSTEM_LOG <<
" ⊙ Audio loading not yet implemented: " << path <<
"\n";
587 const std::vector<TilesetInfo>& tilesets,
593 for (
const auto& tileset : tilesets)
598 if (!tileset.isCollection && !tileset.imageFile.empty())
600 std::string
id = tileset.imageFile;
601 size_t lastSlash =
id.find_last_of(
"/\\");
609 SYSTEM_LOG <<
" -> Loaded tileset image: " << tileset.imageFile <<
"\n";
622 SYSTEM_LOG <<
" x Failed to load tileset image: " << tileset.imageFile <<
"\n";
632 for (
const auto& imagePath : tileset.individualImages)
634 std::string
id = imagePath;
635 size_t lastSlash =
id.find_last_of(
"/\\");
645 SYSTEM_LOG <<
" -> Loaded tile image: " << imagePath <<
"\n";
658 SYSTEM_LOG <<
" x Failed to load tile image: " << imagePath <<
"\n";
678 if (!tileset.sourceFile.empty())
698std::string DataManager::FindResourceRecursive_Windows(
const std::string&
filename,
const std::string&
rootDir)
const
Core ECS component definitions.
ComponentTypeID GetComponentTypeID_Static()
static SDL_Renderer * renderer
static std::string BuildGameDataPath(const std::string &videogameName, const std::string &objectName)
std::string FindResourceRecursive_Unix(const std::string &filename, const std::string &rootDir) const
bool PreloadSystemResources(const std::string &configFilePath)
Sprite * GetSprite(const std::string &id, const std::string &path, ResourceCategory category=ResourceCategory::GameEntity)
PreloadStats PreloadSprites(const std::vector< std::string > &paths, ResourceCategory category=ResourceCategory::GameEntity, bool enableFallbackScan=true)
PreloadStats PreloadTextures(const std::vector< std::string > &paths, ResourceCategory category=ResourceCategory::Level, bool enableFallbackScan=true)
bool m_enableFallbackScan
Sprite * GetTexture(const std::string &id) const
bool EnsureDirectoryExists(const std::string &dirpath) const
std::string FindResourceRecursive(const std::string &filename, const std::string &rootDir="GameData") const
bool SaveTextFile(const std::string &filepath, const std::string &content) const
static DataManager & GetInstance()
std::vector< std::string > ListResourcesByType(ResourceType type) const
bool HasResource(const std::string &id) const
bool LoadJSONForObject(const std::string &videogameName, const std::string &objectName, std::string &outJson) const
std::unordered_map< std::string, std::shared_ptr< Resource > > m_resources_
bool PreloadTexture(const std::string &id, const std::string &path, ResourceCategory category=ResourceCategory::System)
PreloadStats PreloadTilesets(const std::vector< TilesetInfo > &tilesets, bool enableFallbackScan=true)
bool SaveJSONForObject(const std::string &videogameName, const std::string &objectName, const std::string &jsonContent) const
bool ReleaseResource(const std::string &id)
PreloadStats PreloadAudioFiles(const std::vector< std::string > &paths, bool enableFallbackScan=true)
bool LoadTextFile(const std::string &filepath, std::string &outContent) const
bool PreloadSprite(const std::string &id, const std::string &path, ResourceCategory category=ResourceCategory::GameEntity)
std::vector< std::string > ListResourcesByCategory(ResourceCategory category) const
bool GetSprite_data(const std::string &id, const std::string &path, VisualSprite_data &outData)
bool GetSpriteEditor_data(const std::string &id, const std::string &path, VisualEditor_data &outData)
static SDL_Renderer * renderer
Main SDL renderer.
std::vector< std::string > failedPaths
std::map< std::string, std::string > fallbackPaths