#include "asset.h" #include // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError #include // Para find_if, max #include // Para basic_ifstream, ifstream #include // Para allocator, string, char_traits, operator+ #include "utils.h" // Para getFileName // Singleton Asset *Asset::instance_ = nullptr; // Inicializa la instancia única del singleton void Asset::init(const std::string &executable_path) { Asset::instance_ = new Asset(executable_path); } // Libera la instancia void Asset::destroy() { delete Asset::instance_; } // Obtiene la instancia Asset *Asset::get() { return Asset::instance_; } // Añade un elemento a la lista void Asset::add(const std::string &file, AssetType type, bool required, bool absolute) { file_list_.emplace_back(absolute ? file : executable_path_ + file, type, required); longest_name_ = std::max(longest_name_, static_cast(file_list_.back().file.size())); } // Devuelve la ruta completa a un fichero a partir de una cadena std::string Asset::get(const std::string &text) const { auto it = std::find_if(file_list_.begin(), file_list_.end(), [&text](const auto &f) { return getFileName(f.file) == text; }); if (it != file_list_.end()) { return it->file; } else { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Warning: file %s not found", text.c_str()); return ""; } } // Comprueba que existen todos los elementos bool Asset::check() const { bool success = true; SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** CHECKING FILES"); // Comprueba la lista de ficheros clasificándolos por tipo for (int type = 0; type < static_cast(AssetType::MAX_ASSET_TYPE); ++type) { // Comprueba si hay ficheros de ese tipo bool any = false; for (const auto &f : file_list_) { if (f.required && f.type == static_cast(type)) { any = true; } } // Si hay ficheros de ese tipo, comprueba si existen if (any) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> %s FILES", getTypeName(static_cast(type)).c_str()); for (const auto &f : file_list_) { if (f.required && f.type == static_cast(type)) { success &= checkFile(f.file); } } if (success) SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, " All files are OK."); } } // Resultado if (success) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** CHECKING FILES COMPLETED.\n"); } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "\n** CHECKING FILES FAILED.\n"); } return success; } // Comprueba que existe un fichero bool Asset::checkFile(const std::string &path) const { std::ifstream file(path); bool success = file.good(); file.close(); if (!success) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Checking file: %s [ ERROR ]", getFileName(path).c_str()); } return success; } // Devuelve el nombre del tipo de recurso std::string Asset::getTypeName(AssetType type) const { switch (type) { case AssetType::BITMAP: return "BITMAP"; case AssetType::MUSIC: return "MUSIC"; case AssetType::SOUND: return "SOUND"; case AssetType::FONT: return "FONT"; case AssetType::LANG: return "LANG"; case AssetType::DATA: return "DATA"; case AssetType::ANIMATION: return "ANIMATION"; case AssetType::PALETTE: return "PALETTE"; case AssetType::ITEM: return "ITEM"; default: return "ERROR"; } } // Devuelve la lista de recursos de un tipo std::vector Asset::getListByType(AssetType type) const { std::vector list; for (auto f : file_list_) { if (f.type == type) { list.push_back(f.file); } } return list; }