From cadd8fd2939dfce888c8a00f00f3f0e98923d31b Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 10 Aug 2025 15:58:56 +0200 Subject: [PATCH] Afegit sistema de carrega de recursos on_demand --- source/director.cpp | 8 +- source/resource.cpp | 487 +++++++++++++++++++++++++++++++++++--------- source/resource.h | 73 ++++--- 3 files changed, 447 insertions(+), 121 deletions(-) diff --git a/source/director.cpp b/source/director.cpp index 3236eeb..2d08a97 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -98,9 +98,11 @@ void Director::init() { Lang::setLanguage(Options::settings.language); // Carga el archivo de idioma Screen::init(); // Inicializa la pantalla y el sistema de renderizado Audio::init(); // Activa el sistema de audio - Resource::init(); // Inicializa el sistema de gestión de recursos - // bindInputs(); // Asigna los controles a la entrada del sistema - +#ifdef _DEBUG + Resource::init(Resource::LoadingMode::LAZY_LOAD); // Inicializa el sistema de gestión de recursos +#else + Resource::init(Resource::LoadingMode::PRELOAD); // Inicializa el sistema de gestión de recursos +#endif ServiceMenu::init(); // Inicializa el menú de servicio Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones Screen::get()->getSingletons(); // Obtiene los punteros al resto de singletones diff --git a/source/resource.cpp b/source/resource.cpp index f271992..1f8fd9b 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -5,6 +5,7 @@ #include // Para find_if, max #include // Para array #include // Para exit +#include // Para printWithDots #include // Para runtime_error #include // Para move @@ -21,23 +22,371 @@ struct JA_Music_t; // lines 11-11 struct JA_Sound_t; // lines 12-12 +// Declaraciones de funciones que necesitas implementar en otros archivos +extern AnimationsFileBuffer loadAnimationsFromFile(const std::string &filename); +extern DemoData loadDemoDataFromFile(const std::string &filename); + // Singleton Resource *Resource::instance = nullptr; -// Inicializa la instancia única del singleton -void Resource::init() { Resource::instance = new Resource(); } +// Inicializa la instancia única del singleton con modo de carga +void Resource::init(LoadingMode mode) { + Resource::instance = new Resource(mode); +} // Libera la instancia -void Resource::destroy() { delete Resource::instance; } +void Resource::destroy() { + delete Resource::instance; + Resource::instance = nullptr; +} // Obtiene la instancia auto Resource::get() -> Resource * { return Resource::instance; } -// Constructor -Resource::Resource() : loading_text_(Screen::get()->getText()) { load(); } +// Constructor con modo de carga +Resource::Resource(LoadingMode mode) + : loading_mode_(mode), loading_text_(nullptr) { + if (loading_mode_ == LoadingMode::PRELOAD) { + loading_text_ = Screen::get()->getText(); + load(); + } else { + // En modo lazy, cargamos lo mínimo indispensable + initResourceLists(); + loadEssentialResources(); + } +} // Destructor -Resource::~Resource() { clear(); } +Resource::~Resource() { + clear(); +} + +// Carga los recursos esenciales que siempre se necesitan (modo lazy) +void Resource::loadEssentialResources() { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading essential resources for lazy mode"); + + // Cargar recursos de texto básicos que se usan para crear texturas + loadTextFilesQuiet(); // <- VERSIÓN SILENCIOSA + loadEssentialTextures(); // Ya es silenciosa + createText(); // Crear objetos de texto + createTextures(); // Crear texturas generadas (game_text_xxx) + + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Essential resources loaded"); +} + +// Carga los ficheros de texto del juego (versión silenciosa) +void Resource::loadTextFilesQuiet() { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> TEXT FILES (quiet load)"); + auto list = Asset::get()->getListByType(Asset::Type::FONT); + + for (const auto &l : list) { + auto name = getFileName(l); + // Buscar en nuestra lista y cargar directamente + auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t) { return t.name == name; }); + if (it != text_files_.end()) { + it->text_file = Text::loadFile(l); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Text file loaded: %s", name.c_str()); + } + } +} + +// Carga solo las texturas esenciales (fuentes) +void Resource::loadEssentialTextures() { + const std::vector essential_textures = { + "04b_25.png", + "04b_25_2x.png", + "04b_25_metal.png", + "04b_25_grey.png", + "04b_25_flat.png", + "04b_25_reversed.png", + "04b_25_flat_2x.png", + "04b_25_reversed_2x.png", + "8bithud.png", + "aseprite.png", + "smb2.png", + "smb2_grad.png"}; + + auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); + + for (const auto &file : texture_list) { + auto name = getFileName(file); + // Solo cargar texturas esenciales + if (std::find(essential_textures.begin(), essential_textures.end(), name) != essential_textures.end()) { + // Buscar en nuestra lista y cargar + auto it = std::find_if(textures_.begin(), textures_.end(), [&name](const auto &t) { return t.name == name; }); + if (it != textures_.end()) { + it->texture = std::make_shared(Screen::get()->getRenderer(), file); + } + } + } +} + +// Inicializa las listas de recursos sin cargar el contenido (modo lazy) +void Resource::initResourceLists() { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Initializing resource lists for lazy loading"); + + // Inicializa lista de sonidos + auto sound_list = Asset::get()->getListByType(Asset::Type::SOUND); + sounds_.clear(); + for (const auto &file : sound_list) { + sounds_.emplace_back(getFileName(file)); + } + + // Inicializa lista de músicas + auto music_list = Asset::get()->getListByType(Asset::Type::MUSIC); + musics_.clear(); + for (const auto &file : music_list) { + musics_.emplace_back(getFileName(file)); + } + + // Inicializa lista de texturas + auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); + textures_.clear(); + for (const auto &file : texture_list) { + textures_.emplace_back(getFileName(file)); + } + + // Inicializa lista de ficheros de texto + auto text_file_list = Asset::get()->getListByType(Asset::Type::FONT); + text_files_.clear(); + for (const auto &file : text_file_list) { + text_files_.emplace_back(getFileName(file)); + } + + // Inicializa lista de animaciones + auto animation_list = Asset::get()->getListByType(Asset::Type::ANIMATION); + animations_.clear(); + for (const auto &file : animation_list) { + animations_.emplace_back(getFileName(file)); + } + + // Los demos se cargan directamente sin mostrar progreso (son pocos y pequeños) + loadDemoDataQuiet(); + + // Inicializa lista de objetos de texto (sin cargar el contenido) + const std::vector text_objects = { + "04b_25", + "04b_25_2x", + "04b_25_metal", + "04b_25_grey", + "04b_25_flat", + "04b_25_reversed", + "04b_25_flat_2x", + "04b_25_reversed_2x", + "8bithud", + "aseprite", + "smb2", + "smb2_grad"}; + + texts_.clear(); + for (const auto &text_name : text_objects) { + texts_.emplace_back(text_name); // Constructor con nullptr por defecto + } + + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Resource lists initialized for lazy loading"); +} + +// Obtiene el sonido a partir de un nombre (con carga perezosa) +auto Resource::getSound(const std::string &name) -> JA_Sound_t * { + auto it = std::find_if(sounds_.begin(), sounds_.end(), [&name](const auto &s) { return s.name == name; }); + + if (it != sounds_.end()) { + // Si está en modo lazy y no se ha cargado aún, lo carga ahora + if (loading_mode_ == LoadingMode::LAZY_LOAD && it->sound == nullptr) { + it->sound = loadSoundLazy(name); + } + return it->sound; + } + + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Sonido no encontrado %s", name.c_str()); + throw std::runtime_error("Sonido no encontrado: " + name); +} + +// Obtiene la música a partir de un nombre (con carga perezosa) +auto Resource::getMusic(const std::string &name) -> JA_Music_t * { + auto it = std::find_if(musics_.begin(), musics_.end(), [&name](const auto &m) { return m.name == name; }); + + if (it != musics_.end()) { + // Si está en modo lazy y no se ha cargado aún, lo carga ahora + if (loading_mode_ == LoadingMode::LAZY_LOAD && it->music == nullptr) { + it->music = loadMusicLazy(name); + } + return it->music; + } + + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Música no encontrada %s", name.c_str()); + throw std::runtime_error("Música no encontrada: " + name); +} + +// Obtiene la textura a partir de un nombre (con carga perezosa) +auto Resource::getTexture(const std::string &name) -> std::shared_ptr { + auto it = std::find_if(textures_.begin(), textures_.end(), [&name](const auto &t) { return t.name == name; }); + + if (it != textures_.end()) { + // Si está en modo lazy y no se ha cargado aún, lo carga ahora + if (loading_mode_ == LoadingMode::LAZY_LOAD && it->texture == nullptr) { + it->texture = loadTextureLazy(name); + } + return it->texture; + } + + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Imagen no encontrada %s", name.c_str()); + throw std::runtime_error("Imagen no encontrada: " + name); +} + +// Obtiene el fichero de texto a partir de un nombre (con carga perezosa) +auto Resource::getTextFile(const std::string &name) -> std::shared_ptr { + auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t) { return t.name == name; }); + + if (it != text_files_.end()) { + // Si está en modo lazy y no se ha cargado aún, lo carga ahora + if (loading_mode_ == LoadingMode::LAZY_LOAD && it->text_file == nullptr) { + it->text_file = loadTextFileLazy(name); + } + return it->text_file; + } + + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: TextFile no encontrado %s", name.c_str()); + throw std::runtime_error("TextFile no encontrado: " + name); +} + +// Obtiene el objeto de texto a partir de un nombre (con carga perezosa) +auto Resource::getText(const std::string &name) -> std::shared_ptr { + auto it = std::find_if(texts_.begin(), texts_.end(), [&name](const auto &t) { return t.name == name; }); + + if (it != texts_.end()) { + // Si está en modo lazy y no se ha cargado aún, lo carga ahora + if (loading_mode_ == LoadingMode::LAZY_LOAD && it->text == nullptr) { + it->text = loadTextLazy(name); + } + return it->text; + } + + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Text no encontrado %s", name.c_str()); + throw std::runtime_error("Text no encontrado: " + name); +} + +// Obtiene la animación a partir de un nombre (con carga perezosa) +auto Resource::getAnimation(const std::string &name) -> AnimationsFileBuffer & { + auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto &a) { return a.name == name; }); + + if (it != animations_.end()) { + // Si está en modo lazy y no se ha cargado aún (vector vacío), lo carga ahora + if (loading_mode_ == LoadingMode::LAZY_LOAD && it->animation.empty()) { + it->animation = loadAnimationLazy(name); + } + return it->animation; + } + + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Animación no encontrada %s", name.c_str()); + throw std::runtime_error("Animación no encontrada: " + name); +} + +// Obtiene el fichero con los datos para el modo demostración a partir de un índice +auto Resource::getDemoData(int index) -> DemoData & { + return demos_.at(index); +} + +// --- Métodos de carga perezosa --- + +auto Resource::loadSoundLazy(const std::string &name) -> JA_Sound_t * { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading sound lazily: %s", name.c_str()); +#ifndef NO_AUDIO + auto sound_list = Asset::get()->getListByType(Asset::Type::SOUND); + for (const auto &file : sound_list) { + if (getFileName(file) == name) { + return JA_LoadSound(file.c_str()); + } + } +#endif + return nullptr; +} + +auto Resource::loadMusicLazy(const std::string &name) -> JA_Music_t * { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading music lazily: %s", name.c_str()); +#ifndef NO_AUDIO + auto music_list = Asset::get()->getListByType(Asset::Type::MUSIC); + for (const auto &file : music_list) { + if (getFileName(file) == name) { + return JA_LoadMusic(file.c_str()); + } + } +#endif + return nullptr; +} + +auto Resource::loadTextureLazy(const std::string &name) -> std::shared_ptr { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading texture lazily: %s", name.c_str()); + auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); + for (const auto &file : texture_list) { + if (getFileName(file) == name) { + return std::make_shared(Screen::get()->getRenderer(), file); + } + } + return nullptr; +} + +auto Resource::loadTextFileLazy(const std::string &name) -> std::shared_ptr { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading text file lazily: %s", name.c_str()); + auto text_file_list = Asset::get()->getListByType(Asset::Type::FONT); + for (const auto &file : text_file_list) { + if (getFileName(file) == name) { + return Text::loadFile(file); + } + } + return nullptr; +} + +auto Resource::loadTextLazy(const std::string &name) -> std::shared_ptr { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading text object lazily: %s", name.c_str()); + + // Mapeo de objetos de texto a sus recursos + struct TextMapping { + std::string key; + std::string texture_file; + std::string text_file; + }; + + const std::vector text_mappings = { + {"04b_25", "04b_25.png", "04b_25.txt"}, + {"04b_25_2x", "04b_25_2x.png", "04b_25_2x.txt"}, + {"04b_25_metal", "04b_25_metal.png", "04b_25.txt"}, + {"04b_25_grey", "04b_25_grey.png", "04b_25.txt"}, + {"04b_25_flat", "04b_25_flat.png", "04b_25.txt"}, + {"04b_25_reversed", "04b_25_reversed.png", "04b_25.txt"}, + {"04b_25_flat_2x", "04b_25_flat_2x.png", "04b_25_2x.txt"}, + {"04b_25_reversed_2x", "04b_25_reversed_2x.png", "04b_25_2x.txt"}, + {"8bithud", "8bithud.png", "8bithud.txt"}, + {"aseprite", "aseprite.png", "aseprite.txt"}, + {"smb2", "smb2.png", "smb2.txt"}, + {"smb2_grad", "smb2_grad.png", "smb2.txt"}}; + + for (const auto &mapping : text_mappings) { + if (mapping.key == name) { + // Cargar las dependencias automáticamente + auto texture = getTexture(mapping.texture_file); // Esto cargará la textura si no está cargada + auto text_file = getTextFile(mapping.text_file); // Esto cargará el archivo de texto si no está cargado + + if (texture && text_file) { + return std::make_shared(texture, text_file); + } + } + } + + return nullptr; +} + +auto Resource::loadAnimationLazy(const std::string &name) -> AnimationsFileBuffer { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Loading animation lazily: %s", name.c_str()); + auto animation_list = Asset::get()->getListByType(Asset::Type::ANIMATION); + for (const auto &file : animation_list) { + if (getFileName(file) == name) { + return loadAnimationsFromFile(file); + } + } + // Si no se encuentra, retorna vector vacío + return AnimationsFileBuffer{}; +} // Vacia todos los vectores de recursos void Resource::clear() { @@ -84,91 +433,25 @@ void Resource::load() { // Recarga todos los recursos (limpia y vuelve a cargar) void Resource::reload() { clear(); - load(); + if (loading_mode_ == LoadingMode::PRELOAD) { + load(); + } else { + initResourceLists(); + } } // Recarga solo las texturas y paletas void Resource::reloadTextures() { - loadTextures(); - addPalettes(); - createTextures(); -} - -// Obtiene el sonido a partir de un nombre. Lanza excepción si no existe. -auto Resource::getSound(const std::string &name) -> JA_Sound_t * { - auto it = std::find_if(sounds_.begin(), sounds_.end(), [&name](const auto &s) { return s.name == name; }); - - if (it != sounds_.end()) { - return it->sound; + if (loading_mode_ == LoadingMode::PRELOAD) { + loadTextures(); + addPalettes(); + createTextures(); + } else { + // En modo lazy, limpiamos las texturas cargadas para forzar recarga + for (auto &texture : textures_) { + texture.texture = nullptr; + } } - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Sonido no encontrado %s", name.c_str()); - throw std::runtime_error("Sonido no encontrado: " + name); -} - -// Obtiene la música a partir de un nombre. Lanza excepción si no existe. -auto Resource::getMusic(const std::string &name) -> JA_Music_t * { - auto it = std::find_if(musics_.begin(), musics_.end(), [&name](const auto &m) { return m.name == name; }); - - if (it != musics_.end()) { - return it->music; - } - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Música no encontrada %s", name.c_str()); - throw std::runtime_error("Música no encontrada: " + name); -} - -// Obtiene la textura a partir de un nombre. Lanza excepción si no existe. -auto Resource::getTexture(const std::string &name) -> std::shared_ptr { - auto it = std::find_if(textures_.begin(), textures_.end(), [&name](const auto &t) { return t.name == name; }); - - if (it != textures_.end()) { - return it->texture; - } - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Imagen no encontrada %s", name.c_str()); - throw std::runtime_error("Imagen no encontrada: " + name); -} - -// Obtiene el fichero de texto a partir de un nombre. Lanza excepción si no existe. -auto Resource::getTextFile(const std::string &name) -> std::shared_ptr { - auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t) { return t.name == name; }); - - if (it != text_files_.end()) { - return it->text_file; - } - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: TextFile no encontrado %s", name.c_str()); - throw std::runtime_error("TextFile no encontrado: " + name); -} - -// Obtiene el objeto de texto a partir de un nombre. Lanza excepción si no existe. -auto Resource::getText(const std::string &name) -> std::shared_ptr { - auto it = std::find_if(texts_.begin(), texts_.end(), [&name](const auto &t) { return t.name == name; }); - - if (it != texts_.end()) { - return it->text; - } - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Text no encontrado %s", name.c_str()); - throw std::runtime_error("Text no encontrado: " + name); -} - -// Obtiene la animación a partir de un nombre. Lanza excepción si no existe. -auto Resource::getAnimation(const std::string &name) -> AnimationsFileBuffer & { - auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto &a) { return a.name == name; }); - - if (it != animations_.end()) { - return it->animation; - } - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Animación no encontrada %s", name.c_str()); - throw std::runtime_error("Animación no encontrada: " + name); -} - -// Obtiene el fichero con los datos para el modo demostración a partir de un índice -auto Resource::getDemoData(int index) -> DemoData & { - return demos_.at(index); } // Carga los sonidos del juego @@ -182,6 +465,8 @@ void Resource::loadSounds() { updateLoadingProgress(name); #ifndef NO_AUDIO sounds_.emplace_back(name, JA_LoadSound(l.c_str())); +#else + sounds_.emplace_back(name, nullptr); #endif printWithDots("Sound : ", name, "[ LOADED ]"); } @@ -198,6 +483,8 @@ void Resource::loadMusics() { updateLoadingProgress(name); #ifndef NO_AUDIO musics_.emplace_back(name, JA_LoadMusic(l.c_str())); +#else + musics_.emplace_back(name, nullptr); #endif printWithDots("Music : ", name, "[ LOADED ]"); } @@ -441,13 +728,16 @@ void Resource::checkEvents() { } } -// Actualiza el progreso de carga, muestra la barra y procesa eventos -void Resource::updateLoadingProgress(std::string name) { - loading_resource_name_ = name; - loading_count_.increase(); - updateProgressBar(); - renderProgress(); - checkEvents(); +// Carga los datos para el modo demostración (sin mostrar progreso) +void Resource::loadDemoDataQuiet() { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> DEMO FILES (quiet load)"); + + constexpr std::array DEMO_FILES = {"demo1.bin", "demo2.bin"}; + + for (const auto &file : DEMO_FILES) { + demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get(file))); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Demo file loaded: %s", file); + } } // Inicializa los rectangulos que definen la barra de progreso @@ -464,7 +754,16 @@ void Resource::initProgressBar() { loading_full_rect_ = {X_PADDING, BAR_Y_POSITION, FULL_BAR_WIDTH, BAR_HEIGHT}; } +// Actualiza el progreso de carga, muestra la barra y procesa eventos +void Resource::updateLoadingProgress(std::string name) { + loading_resource_name_ = name; + loading_count_.increase(); + updateProgressBar(); + renderProgress(); + checkEvents(); +} + // Actualiza la barra de estado void Resource::updateProgressBar() { loading_full_rect_.w = loading_wired_rect_.w * loading_count_.getPercentage(); -} \ No newline at end of file +} diff --git a/source/resource.h b/source/resource.h index 55680f9..a8e4efc 100644 --- a/source/resource.h +++ b/source/resource.h @@ -19,10 +19,16 @@ struct JA_Sound_t; // --- Clase Resource: gestiona todos los recursos del juego (singleton) --- class Resource { public: + // --- Enum para el modo de carga --- + enum class LoadingMode { + PRELOAD, // Carga todos los recursos al inicio + LAZY_LOAD // Carga los recursos bajo demanda + }; + // --- Métodos de singleton --- - static void init(); // Inicializa el objeto Resource - static void destroy(); // Libera el objeto Resource - static auto get() -> Resource *; // Obtiene el puntero al objeto Resource + static void init(LoadingMode mode = LoadingMode::PRELOAD); // Inicializa el objeto Resource con modo de carga + static void destroy(); // Libera el objeto Resource + static auto get() -> Resource *; // Obtiene el puntero al objeto Resource // --- Métodos de acceso a recursos --- auto getSound(const std::string &name) -> JA_Sound_t *; // Obtiene el sonido por nombre @@ -37,13 +43,16 @@ class Resource { void reload(); // Recarga todos los recursos void reloadTextures(); // Recarga solo las texturas + // --- Método para obtener el modo de carga actual --- + auto getLoadingMode() const -> LoadingMode { return loading_mode_; } + private: // --- Estructuras para recursos individuales --- struct ResourceSound { std::string name; // Nombre del sonido JA_Sound_t *sound; // Objeto con el sonido - ResourceSound(std::string name, JA_Sound_t *sound) + ResourceSound(std::string name, JA_Sound_t *sound = nullptr) : name(std::move(name)), sound(sound) {} }; @@ -51,7 +60,7 @@ class Resource { std::string name; // Nombre de la música JA_Music_t *music; // Objeto con la música - ResourceMusic(std::string name, JA_Music_t *music) + ResourceMusic(std::string name, JA_Music_t *music = nullptr) : name(std::move(name)), music(music) {} }; @@ -59,7 +68,7 @@ class Resource { std::string name; // Nombre de la textura std::shared_ptr texture; // Objeto con la textura - ResourceTexture(std::string name, std::shared_ptr texture) + ResourceTexture(std::string name, std::shared_ptr texture = nullptr) : name(std::move(name)), texture(std::move(texture)) {} }; @@ -67,7 +76,7 @@ class Resource { std::string name; // Nombre del fichero std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto - ResourceTextFile(std::string name, std::shared_ptr text_file) + ResourceTextFile(std::string name, std::shared_ptr text_file = nullptr) : name(std::move(name)), text_file(std::move(text_file)) {} }; @@ -75,7 +84,7 @@ class Resource { std::string name; // Nombre del objeto std::shared_ptr text; // Objeto de texto - ResourceText(std::string name, std::shared_ptr text) + ResourceText(std::string name, std::shared_ptr text = nullptr) : name(std::move(name)), text(std::move(text)) {} }; @@ -83,7 +92,7 @@ class Resource { std::string name; // Nombre de la animación AnimationsFileBuffer animation; // Objeto con las animaciones - ResourceAnimation(std::string name, AnimationsFileBuffer animation) + ResourceAnimation(std::string name, AnimationsFileBuffer animation = {}) : name(std::move(name)), animation(std::move(animation)) {} }; @@ -102,6 +111,9 @@ class Resource { } }; + // --- Modo de carga --- + LoadingMode loading_mode_; + // --- Vectores de recursos --- std::vector sounds_; // Vector con los sonidos std::vector musics_; // Vector con las músicas @@ -119,19 +131,32 @@ class Resource { SDL_FRect loading_full_rect_; // --- Métodos internos de carga y gestión --- - void loadSounds(); // Carga los sonidos - void loadMusics(); // Carga las músicas - void loadTextures(); // Carga las texturas - void loadTextFiles(); // Carga los ficheros de texto - void loadAnimations(); // Carga las animaciones - void loadDemoData(); // Carga los datos para el modo demostración - void addPalettes(); // Añade paletas a las texturas - void createTextures(); // Crea las texturas a partir de los datos cargados - void createText(); // Crea los objetos de texto - void clear(); // Vacía todos los vectores de recursos - void load(); // Carga todos los recursos - void clearSounds(); // Vacía el vector de sonidos - void clearMusics(); // Vacía el vector de músicas + void loadSounds(); // Carga los sonidos + void loadMusics(); // Carga las músicas + void loadTextures(); // Carga las texturas + void loadTextFiles(); // Carga los ficheros de texto + void loadAnimations(); // Carga las animaciones + void loadDemoData(); // Carga los datos para el modo demostración + void loadDemoDataQuiet(); // Carga los datos de demo sin mostrar progreso (para modo lazy) + void loadEssentialResources(); // Carga recursos esenciales en modo lazy + void loadEssentialTextures(); // Carga solo las texturas esenciales (fuentes) + void loadTextFilesQuiet(); // Carga ficheros de texto sin mostrar progreso (para modo lazy) + void addPalettes(); // Añade paletas a las texturas + void createTextures(); // Crea las texturas a partir de los datos cargados + void createText(); // Crea los objetos de texto + void clear(); // Vacía todos los vectores de recursos + void load(); // Carga todos los recursos + void clearSounds(); // Vacía el vector de sonidos + void clearMusics(); // Vacía el vector de músicas + + // --- Métodos para carga perezosa --- + void initResourceLists(); // Inicializa las listas de recursos sin cargar el contenido + auto loadSoundLazy(const std::string &name) -> JA_Sound_t *; // Carga un sonido específico bajo demanda + auto loadMusicLazy(const std::string &name) -> JA_Music_t *; // Carga una música específica bajo demanda + auto loadTextureLazy(const std::string &name) -> std::shared_ptr; // Carga una textura específica bajo demanda + auto loadTextFileLazy(const std::string &name) -> std::shared_ptr; // Carga un fichero de texto específico bajo demanda + auto loadTextLazy(const std::string &name) -> std::shared_ptr; // Carga un objeto de texto específico bajo demanda + auto loadAnimationLazy(const std::string &name) -> AnimationsFileBuffer; // Carga una animación específica bajo demanda // --- Métodos internos para gestionar el progreso --- void calculateTotalResources(); // Calcula el número de recursos para cargar @@ -142,8 +167,8 @@ class Resource { void updateProgressBar(); // Actualiza la barra de estado // --- Constructores y destructor privados (singleton) --- - Resource(); // Constructor privado - ~Resource(); // Destructor privado + explicit Resource(LoadingMode mode); // Constructor privado con modo de carga + ~Resource(); // Destructor privado // --- Instancia singleton --- static Resource *instance; // Instancia única de Resource