30#include "sdl3_image/sdl_image.h"
32#include "third_party/nlohmann/json.hpp"
70 SYSTEM_LOG <<
"DataManager Shutdown - unloading all resources\n";
77 if (
id.
empty() || path.empty())
return false;
89 SYSTEM_LOG <<
"DataManager::PreloadTexture IMG_Load failed for '" << path <<
"' : " <<
SDL_GetError() <<
"\n";
100 SYSTEM_LOG <<
"DataManager::PreloadTexture SDL_CreateTextureFromSurface failed for '" << path <<
"' : " <<
SDL_GetError() <<
"\n";
111 auto res = std::make_shared<Resource>();
113 res->category = category;
116 res->sprite_texture =
tex;
129 SYSTEM_LOG <<
"DataManager: Loaded texture '" <<
id <<
"' from '" << path <<
"'\n";
143 auto res =
it->second;
144 if (
res->sprite_texture)
return res->sprite_texture;
156 res->sprite_texture =
tex;
160 return res->sprite_texture;
164 SYSTEM_LOG <<
"DataManager: Failed to create deferred texture for '" <<
id <<
"' : " <<
SDL_GetError() <<
"\n";
179 return it->second->sprite_texture;
198 outData.srcRect = { 0.0f, 0.0f,
static_cast<float>(w),
static_cast<float>(h) };
203 SYSTEM_LOG <<
"DataManager: GetSprite_data failed for '" <<
id <<
"' file/path '" << path <<
"' does not exists or is incorrect\n";
214 outData.srcRect = { 0.0f, 0.0f,
static_cast<float>(w),
static_cast<float>(h) };
218 SYSTEM_LOG <<
"DataManager: GetSpriteEditor_data failed for '" <<
id <<
"' file/path '" << path <<
"' does not exists or is incorrect\n";
227 auto res =
it->second;
229 if (
res->sprite_texture)
232 res->sprite_texture =
nullptr;
243 SYSTEM_LOG <<
"DataManager: Released resource '" <<
id <<
"'\n";
252 auto res =
kv.second;
253 if (
res->sprite_texture)
256 res->sprite_texture =
nullptr;
276 std::vector<std::string>
out;
282 if (
kv.second->type == type)
out.push_back(
kv.first);
289 std::vector<std::string>
out;
295 if (
kv.second->category == category)
out.push_back(
kv.first);
304 std::string
obj = objectName.empty() ? std::string(
"object") : objectName;
305 std::string path = std::string(
".") +
"/Gamedata/" +
game +
"/" +
obj +
".json";
311 if (filepath.empty())
return false;
313 auto pos = filepath.find_last_of(
"/\\");
314 if (
pos != std::string::npos)
316 std::string
dir = filepath.substr(0,
pos);
319 SYSTEM_LOG <<
"DataManager: Failed to ensure directory exists for '" <<
dir <<
"'\n";
324 std::ofstream
ofs(filepath.c_str(), std::ios::binary | std::ios::trunc);
325 if (!
ofs)
return false;
333 if (filepath.empty())
return false;
334 std::ifstream
ifs(filepath.c_str(), std::ios::binary);
335 if (!
ifs)
return false;
336 std::ostringstream
ss;
356 if (
dirpath.empty())
return false;
360 std::replace(path.begin(), path.end(),
'\\',
'/');
362 if (!path.empty() && path.back() ==
'/') path.pop_back();
363 if (path.empty())
return true;
369 if (!path.empty() && path[0] ==
'/') {
accum =
"/";
pos = 1; }
373 size_t next = path.find(
'/',
pos);
398 if (
next == std::string::npos)
break;
417 if (!
root.contains(
"system_resources"))
return true;
418 const auto&
arr =
root[
"system_resources"];
419 if (!
arr.is_array())
return false;
420 for (
size_t i = 0;
i <
arr.size(); ++
i)
423 if (!
item.is_object())
continue;
424 std::string
id =
item.contains(
"id") ?
item[
"id"].get<std::string>() : std::string();
425 std::string path =
item.contains(
"path") ?
item[
"path"].get<std::string>() : std::string();
426 std::string type =
item.contains(
"type") ?
item[
"type"].get<std::string>() : std::string();
427 if (
id.
empty() || path.empty())
continue;
428 if (type ==
"texture")
433 if (type ==
"sprite" || type ==
"animation")
443 catch (
const std::exception&
e)
445 SYSTEM_LOG <<
"DataManager: JSON parse error in PreloadSystemResources: " <<
e.what() <<
"\n";
457 const std::vector<std::string>&
paths,
464 for (
const auto& path :
paths)
466 if (path.empty())
continue;
469 std::string
id = path;
470 size_t lastSlash =
id.find_last_of(
"/\\");
480 SYSTEM_LOG <<
" -> Loaded texture: " << path <<
"\n";
498 SYSTEM_LOG <<
" x Failed to load texture: " << path <<
"\n";
505 SYSTEM_LOG <<
" x Failed to load texture: " << path <<
"\n";
513 const std::vector<std::string>&
paths,
520 for (
const auto& path :
paths)
522 if (path.empty())
continue;
525 std::string
id = path;
526 size_t lastSlash =
id.find_last_of(
"/\\");
536 SYSTEM_LOG <<
" -> Loaded sprite: " << path <<
"\n";
554 SYSTEM_LOG <<
" x Failed to load sprite: " << path <<
"\n";
561 SYSTEM_LOG <<
" x Failed to load sprite: " << path <<
"\n";
569 const std::vector<std::string>&
paths,
576 for (
const auto& path :
paths)
578 if (path.empty())
continue;
579 SYSTEM_LOG <<
" ⊙ Audio loading not yet implemented: " << path <<
"\n";
588 const std::vector<TilesetInfo>& tilesets,
594 for (
const auto& tileset : tilesets)
599 if (!tileset.isCollection && !tileset.imageFile.empty())
601 std::string
id = tileset.imageFile;
602 size_t lastSlash =
id.find_last_of(
"/\\");
610 SYSTEM_LOG <<
" -> Loaded tileset image: " << tileset.imageFile <<
"\n";
623 SYSTEM_LOG <<
" x Failed to load tileset image: " << tileset.imageFile <<
"\n";
633 for (
const auto& imagePath : tileset.individualImages)
635 std::string
id = imagePath;
636 size_t lastSlash =
id.find_last_of(
"/\\");
646 SYSTEM_LOG <<
" -> Loaded tile image: " << imagePath <<
"\n";
659 SYSTEM_LOG <<
" x Failed to load tile image: " << imagePath <<
"\n";
679 if (!tileset.sourceFile.empty())
699std::string DataManager::FindResourceRecursive_Windows(
const std::string&
filename,
const std::string&
rootDir)
const
842 <<
"' -> '" <<
found <<
"' (recursive search in Blueprints)\n";
851 <<
"' -> '" <<
found <<
"' (recursive search in Gamedata)\n";
866 std::vector<std::string> result;
882 result.push_back(
findData.cFileName);
913 SYSTEM_LOG <<
"[DataManager] Found " << result.size() <<
" .bt.json files in: " <<
directory <<
"\n";
927 std::string
browseDir = currentPath.empty() ?
"./Gamedata" : currentPath;
975 SYSTEM_LOG <<
"[DataManager] Opened file picker modal for file type: "
976 <<
static_cast<int>(
fileType) <<
"\n";
1029 SYSTEM_LOG <<
"[DataManager] Opened Save As modal for file type: " <<
static_cast<int>(
fileType) <<
"\n";
Core ECS component definitions.
ComponentTypeID GetComponentTypeID_Static()
Centralized file picker modal for all file selection operations (Phase 40).
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)
std::string GetSelectedFileFromModal() const
Retrieves the selected file from the file picker modal.
bool IsFilePickerModalOpen() const
Checks if the file picker modal is currently visible.
PreloadStats PreloadTextures(const std::vector< std::string > &paths, ResourceCategory category=ResourceCategory::Level, bool enableFallbackScan=true)
std::string OpenFilePickerModal(Olympe::FilePickerType fileType, const std::string ¤tPath="")
Opens a centralized file picker modal for the specified file type.
bool m_enableFallbackScan
std::string SelectBehaviorTreeFile(const std::string ¤tPath="") const
Opens a file browser dialog for selecting a behavior tree file.
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
void CloseSaveFilePickerModal()
Closes the Save As file picker modal.
bool HasResource(const std::string &id) const
bool LoadJSONForObject(const std::string &videogameName, const std::string &objectName, std::string &outJson) const
void CloseFilePickerModal()
Closes the file picker modal without user selection.
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)
void RenderSaveFilePickerModal()
Renders the Save As file picker modal UI.
std::unique_ptr< Olympe::SaveFilePickerModal > m_saveFilePickerModal
bool LoadTextFile(const std::string &filepath, std::string &outContent) const
bool PreloadSprite(const std::string &id, const std::string &path, ResourceCategory category=ResourceCategory::GameEntity)
bool IsSaveFilePickerModalOpen() const
Checks if the Save As file picker modal is currently visible.
void RenderFilePickerModal()
Renders the file picker modal if one is open.
std::string ResolveFilePath(const std::string &relativePath) const
std::vector< std::string > GetBehaviorTreeFiles(const std::string &directory="./Gamedata") const
Lists all .bt.json behavior tree files in a directory.
std::vector< std::string > ListResourcesByCategory(ResourceCategory category) const
void OpenSaveFilePickerModal(Olympe::SaveFileType fileType, const std::string &directory, const std::string &suggestedFilename="")
Opens the Save As file picker modal.
std::string GetSelectedSaveFile() const
Retrieves the selected file from the Save As modal.
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)
std::unique_ptr< Olympe::FilePickerModal > m_filePickerModal
static SDL_Renderer * renderer
Main SDL renderer.
FilePickerType
Supported file types for the centralized file picker modal.
SaveFileType
Supported file types for the centralized save modal.
std::vector< std::string > failedPaths
std::map< std::string, std::string > fallbackPaths