#pragma once #include // Para SDL_FRect #include // Para size_t #include // Para std::uint8_t #include // Para shared_ptr #include // Para string #include // Para move #include // Para vector #include "core/rendering/sprite/animated_sprite.hpp" // Para AnimationsFileBuffer #include "core/rendering/text.hpp" // Para Text, TextFile #include "core/rendering/texture.hpp" // Para Texture #include "core/system/demo.hpp" // Para DemoData namespace Ja { struct Music; struct Sound; } // namespace Ja // --- Clase Resource: gestiona todos los recursos del juego (singleton) --- class Resource { public: // --- Enum para el modo de carga --- enum class LoadingMode : std::uint8_t { PRELOAD, // Carga todos los recursos al inicio LAZY_LOAD // Carga los recursos bajo demanda }; // --- Métodos de singleton --- 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*; // Obtiene el sonido por nombre auto getMusic(const std::string& name) -> Ja::Music*; // Obtiene la música por nombre auto getTexture(const std::string& name) -> std::shared_ptr; // Obtiene la textura por nombre auto getTextFile(const std::string& name) -> std::shared_ptr; // Obtiene el fichero de texto por nombre auto getText(const std::string& name) -> std::shared_ptr; // Obtiene el objeto de texto por nombre auto getAnimation(const std::string& name) -> AnimationsFileBuffer&; // Obtiene la animación por nombre auto getDemoData(int index) -> DemoData&; // Obtiene los datos de demo por índice // --- Métodos de recarga de recursos --- void reload(); // Recarga todos los recursos // --- Cargador incremental --- // beginLoad prepara el estado; loadStep carga recursos hasta agotar el presupuesto; // devuelve true cuando ya no queda nada. renderProgress se llama una vez por frame // desde la escena Preload. void beginLoad(); auto loadStep(int budget_ms) -> bool; [[nodiscard]] auto isLoadDone() const -> bool; void renderProgress(); // --- Método para obtener el modo de carga actual --- [[nodiscard]] auto getLoadingMode() const -> LoadingMode { return loading_mode_; } private: // --- Estructuras para recursos individuales --- struct ResourceSound { std::string name; // Nombre del sonido Ja::Sound* sound; // Objeto con el sonido explicit ResourceSound(std::string name, Ja::Sound* sound = nullptr) : name(std::move(name)), sound(sound) {} }; struct ResourceMusic { std::string name; // Nombre de la música Ja::Music* music; // Objeto con la música explicit ResourceMusic(std::string name, Ja::Music* music = nullptr) : name(std::move(name)), music(music) {} }; struct ResourceTexture { std::string name; // Nombre de la textura std::shared_ptr texture; // Objeto con la textura explicit ResourceTexture(std::string name, std::shared_ptr texture = nullptr) : name(std::move(name)), texture(std::move(texture)) {} }; struct ResourceTextFile { std::string name; // Nombre del fichero std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto explicit ResourceTextFile(std::string name, std::shared_ptr text_file = nullptr) : name(std::move(name)), text_file(std::move(text_file)) {} }; struct ResourceText { std::string name; // Nombre del objeto std::shared_ptr text; // Objeto de texto explicit ResourceText(std::string name, std::shared_ptr text = nullptr) : name(std::move(name)), text(std::move(text)) {} }; struct ResourceAnimation { std::string name; // Nombre de la animación AnimationsFileBuffer animation; // Objeto con las animaciones explicit ResourceAnimation(std::string name, AnimationsFileBuffer animation = {}) : name(std::move(name)), animation(std::move(animation)) {} }; // --- Estructura para el progreso de carga --- struct ResourceCount { size_t total{0}; // Número total de recursos size_t loaded{0}; // Número de recursos cargados ResourceCount() = default; explicit ResourceCount(size_t total) : total(total) {} void add(size_t amount) { loaded += amount; } void increase() { loaded++; } [[nodiscard]] auto getPercentage() const -> float { return total > 0 ? static_cast(loaded) / static_cast(total) : 0.0F; } }; // --- Constantes para la barra de progreso de la pantalla de carga --- // BAR_WIDTH_RATIO: fracción del ancho de la pantalla ocupada por la barra (centrada) // 1.0 = ancho completo, 0.5 = la mitad del ancho // BAR_Y_RATIO: posición vertical del CENTRO de la barra en fracción de la altura // 0.0 = centro en el borde superior, 1.0 = centro en el borde inferior // BAR_HEIGHT: grosor de la barra en píxeles static constexpr float BAR_WIDTH_RATIO = 0.5F; static constexpr float BAR_Y_RATIO = 0.85F; static constexpr float BAR_HEIGHT = 5.0F; // --- Modo de carga --- LoadingMode loading_mode_; // --- Vectores de recursos --- std::vector sounds_; // Vector con los sonidos std::vector musics_; // Vector con las músicas std::vector textures_; // Vector con las texturas std::vector text_files_; // Vector con los ficheros de texto std::vector texts_; // Vector con los objetos de texto std::vector animations_; // Vector con las animaciones std::vector demos_; // Vector con los ficheros de datos para el modo demostración // --- Progreso de carga --- ResourceCount loading_count_; // Contador de recursos cargados std::shared_ptr loading_text_; // Texto para escribir en pantalla std::string loading_resource_name_; // Nombre del recurso que se está cargando SDL_FRect loading_wired_rect_; SDL_FRect loading_full_rect_; // --- Estado del cargador incremental --- enum class LoadStage : std::uint8_t { SOUNDS, MUSICS, TEXTURES, TEXT_FILES, ANIMATIONS, DEMO_DATA, CREATE_TEXT, CREATE_TEXT_TEXTURES, CREATE_PLAYER_TEXTURES, DONE }; LoadStage stage_{LoadStage::DONE}; size_t stage_index_{0}; bool saved_vsync_{false}; // Vsync previo a beginLoad, restaurado por finishBoot/load // --- Métodos internos de carga y gestió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 createPlayerTextures(); // Crea las texturas de jugadores con todas sus variantes de paleta void createTextTextures(); // 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 static auto loadSoundLazy(const std::string& name) -> Ja::Sound*; // Carga un sonido específico bajo demanda static auto loadMusicLazy(const std::string& name) -> Ja::Music*; // Carga una música específica bajo demanda static auto loadTextureLazy(const std::string& name) -> std::shared_ptr; // Carga una textura específica bajo demanda static 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 static 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 void updateLoadingProgress(std::string name); // Actualiza el progreso de carga void initProgressBar(); // Inicializa los rectangulos que definen la barra de progreso void updateProgressBar(); // Actualiza la barra de estado // Avança una etapa que descarrega una llista d'assets: si `stage_index_` desborda la mida, // salta a `next_stage`; si no, crida `load_one` per a l'element actual i incrementa. void advanceListLoadStage(const std::vector& list, void (Resource::*load_one)(size_t), LoadStage next_stage); // --- Helpers del cargador incremental (cargan un único recurso) --- void loadOneSound(size_t idx); void loadOneMusic(size_t idx); void loadOneTexture(size_t idx); void loadOneTextFile(size_t idx); void loadOneAnimation(size_t idx); void loadOneDemoData(size_t idx); // --- Constructores y destructor privados (singleton) --- explicit Resource(LoadingMode mode); // Constructor privado con modo de carga ~Resource(); // Destructor privado // --- Instancia singleton --- static Resource* instance; // Instancia única de Resource };