Files
pollo/source/core/resources/resource_loader.cpp
2025-11-23 11:44:31 +01:00

200 lines
5.4 KiB
C++

// resource_loader.cpp
// Resource loader implementation
#include "resource_loader.hpp"
#include <filesystem>
#include <fstream>
#include <iostream>
namespace Resource {
// Get singleton instance
auto Loader::get() -> Loader& {
static Loader instance_;
return instance_;
}
// Initialize with a pack file
auto Loader::initialize(const std::string& pack_file, bool enable_fallback)
-> bool {
if (initialized_) {
std::cout << "Loader: Already initialized\n";
return true;
}
fallback_to_files_ = enable_fallback;
// Try to load the pack file
if (!pack_file.empty() && fileExistsOnFilesystem(pack_file)) {
std::cout << "Loader: Loading pack file: " << pack_file << '\n';
resource_pack_ = std::make_unique<Pack>();
if (resource_pack_->loadPack(pack_file)) {
std::cout << "Loader: Pack loaded successfully\n";
initialized_ = true;
return true;
}
std::cerr << "Loader: Failed to load pack file\n";
resource_pack_.reset();
} else {
std::cout << "Loader: Pack file not found: " << pack_file << '\n';
}
// If pack loading failed and fallback is disabled, fail
if (!fallback_to_files_) {
std::cerr << "Loader: Pack required but not found (fallback disabled)\n";
return false;
}
// Otherwise, fallback to filesystem
std::cout << "Loader: Using filesystem fallback\n";
initialized_ = true;
return true;
}
// Load a resource
auto Loader::loadResource(const std::string& filename) -> std::vector<uint8_t> {
if (!initialized_) {
std::cerr << "Loader: Not initialized\n";
return {};
}
// Try pack first if available
if (resource_pack_ && resource_pack_->isLoaded()) {
if (resource_pack_->hasResource(filename)) {
auto data = resource_pack_->getResource(filename);
if (!data.empty()) {
return data;
}
std::cerr << "Loader: Failed to extract from pack: " << filename
<< '\n';
}
}
// Fallback to filesystem if enabled
if (fallback_to_files_) {
return loadFromFilesystem(filename);
}
std::cerr << "Loader: Resource not found: " << filename << '\n';
return {};
}
// Check if a resource exists
auto Loader::resourceExists(const std::string& filename) -> bool {
if (!initialized_) {
return false;
}
// Check pack first
if (resource_pack_ && resource_pack_->isLoaded()) {
if (resource_pack_->hasResource(filename)) {
return true;
}
}
// Check filesystem if fallback enabled
if (fallback_to_files_) {
return fileExistsOnFilesystem(filename);
}
return false;
}
// Check if pack is loaded
auto Loader::isPackLoaded() const -> bool {
return resource_pack_ && resource_pack_->isLoaded();
}
// Get pack statistics
auto Loader::getPackResourceCount() const -> size_t {
if (resource_pack_ && resource_pack_->isLoaded()) {
return resource_pack_->getResourceCount();
}
return 0;
}
// Cleanup
void Loader::shutdown() {
resource_pack_.reset();
initialized_ = false;
std::cout << "Loader: Shutdown complete\n";
}
// Load from filesystem
auto Loader::loadFromFilesystem(const std::string& filepath)
-> std::vector<uint8_t> {
std::ifstream file(filepath, std::ios::binary | std::ios::ate);
if (!file) {
return {};
}
std::streamsize file_size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> data(file_size);
if (!file.read(reinterpret_cast<char*>(data.data()), file_size)) {
std::cerr << "Loader: Failed to read file: " << filepath << '\n';
return {};
}
return data;
}
// Check if file exists on filesystem
auto Loader::fileExistsOnFilesystem(const std::string& filepath) -> bool {
return std::filesystem::exists(filepath);
}
// Validate pack integrity
auto Loader::validatePack() const -> bool {
if (!initialized_ || !resource_pack_ || !resource_pack_->isLoaded()) {
std::cerr << "Loader: Cannot validate - pack not loaded\n";
return false;
}
// Calculate pack checksum
uint32_t checksum = resource_pack_->calculatePackChecksum();
if (checksum == 0) {
std::cerr << "Loader: Pack checksum is zero (invalid)\n";
return false;
}
std::cout << "Loader: Pack checksum: 0x" << std::hex << checksum << std::dec
<< '\n';
std::cout << "Loader: Pack validation successful\n";
return true;
}
// Load assets.yaml from pack
auto Loader::loadAssetsConfig() const -> std::string {
if (!initialized_ || !resource_pack_ || !resource_pack_->isLoaded()) {
std::cerr << "Loader: Cannot load assets config - pack not loaded\n";
return "";
}
// Try to load config/assets.yaml from pack
std::string config_path = "config/assets.yaml";
if (!resource_pack_->hasResource(config_path)) {
std::cerr << "Loader: assets.yaml not found in pack: " << config_path << '\n';
return "";
}
auto data = resource_pack_->getResource(config_path);
if (data.empty()) {
std::cerr << "Loader: Failed to load assets.yaml from pack\n";
return "";
}
// Convert bytes to string
std::string config_content(data.begin(), data.end());
std::cout << "Loader: Loaded assets.yaml from pack (" << data.size()
<< " bytes)\n";
return config_content;
}
} // namespace Resource