#include "asset.h" #include // for SDL_RWFromFile, SDL_RWclose, SDL_RWops #include // for SDL_max #include // for size_t #include // for basic_ostream, operator<<, cout, endl // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Asset *Asset::asset = nullptr; // [SINGLETON] Crearemos el objeto asset con esta función estática void Asset::init(std::string executable_path) { Asset::asset = new Asset(executable_path); } // [SINGLETON] Destruiremos el objeto asset con esta función estática void Asset::destroy() { delete Asset::asset; } // [SINGLETON] Con este método obtenemos el objeto asset y podemos trabajar con él Asset *Asset::get() { return Asset::asset; } // Constructor Asset::Asset(std::string executable_path) { executable_path_ = executable_path.substr(0, executable_path.find_last_of("\\/")); longest_name_ = 0; } // Añade un elemento a la lista void Asset::add(std::string file, AssetType type, bool required, bool absolute) { AssetItem ai; ai.file = absolute ? file : executable_path_ + file; ai.type = type; ai.required = required; file_list_.push_back(ai); const std::string file_name = file.substr(file.find_last_of("\\/") + 1); longest_name_ = SDL_max(longest_name_, file_name.size()); } // Devuelve el fichero de un elemento de la lista a partir de una cadena std::string Asset::get(std::string text) const { for (auto f : file_list_) { const size_t last_index = f.file.find_last_of("/") + 1; const std::string file = f.file.substr(last_index, std::string::npos); if (file == text) { return f.file; } } #ifdef VERBOSE std::cout << "Warning: file " << text.c_str() << " not found" << std::endl; #endif return ""; } // Comprueba que existen todos los elementos bool Asset::check() const { bool success = true; #ifdef VERBOSE std::cout << "\n** Checking files" << std::endl; std::cout << "Executable path is: " << executable_path_ << std::endl; std::cout << "Sample filepath: " << file_list_.back().file << std::endl; #endif // Comprueba la lista de ficheros clasificandolos 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 (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) { #ifdef VERBOSE std::cout << "\n>> " << getTypeName(static_cast(type)).c_str() << " FILES" << std::endl; #endif for (auto f : file_list_) { if (f.required && f.type == static_cast(type)) { success &= checkFile(f.file); } } } } // Resultado #ifdef VERBOSE std::cout << (success ? "\n** All files OK.\n" : "\n** A file is missing. Exiting.\n") << std::endl; #endif return success; } // Comprueba que existe un fichero bool Asset::checkFile(std::string path) const { bool success = false; std::string result = "ERROR"; // Comprueba si existe el fichero const std::string file_name = path.substr(path.find_last_of("\\/") + 1); SDL_RWops *file = SDL_RWFromFile(path.c_str(), "rb"); if (file != nullptr) { result = "OK"; success = true; SDL_RWclose(file); } #ifdef VERBOSE std::cout.setf(std::ios::left, std::ios::adjustfield); std::cout << "Checking file: "; std::cout.width(longest_name_ + 2); std::cout.fill('.'); std::cout << file_name + " "; std::cout << " [" + result + "]" << std::endl; #endif return success; } // Devuelve el nombre del tipo de recurso std::string Asset::getTypeName(AssetType type) const { switch (type) { case AssetType::BITMAP: return "BITMAP"; break; case AssetType::MUSIC: return "MUSIC"; break; case AssetType::SOUND: return "SOUND"; break; case AssetType::FONT: return "FONT"; break; case AssetType::LANG: return "LANG"; break; case AssetType::DATA: return "DATA"; break; case AssetType::ANIMATION: return "ANIMATION"; break; case AssetType::PALETTE: return "PALETTE"; break; case AssetType::ITEM: return "ITEM"; break; default: return "ERROR"; break; } } // 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; }