200 lines
5.4 KiB
C++
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
|