71 lines
2 KiB
Rust
71 lines
2 KiB
Rust
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
use super::asset::AssetFile;
|
|
use super::dir::AssetDir;
|
|
use std::collections::HashMap;
|
|
|
|
pub struct AssetManager {
|
|
base_assets: HashMap<String, Vec<u8>>,
|
|
mod_overrides: HashMap<String, Vec<u8>>,
|
|
}
|
|
|
|
impl Default for AssetManager {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl AssetManager {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
base_assets: HashMap::new(),
|
|
mod_overrides: HashMap::new(),
|
|
}
|
|
}
|
|
|
|
pub fn add_asset(&mut self, path: &str, data: Vec<u8>) {
|
|
self.base_assets.insert(path.to_string(), data);
|
|
}
|
|
|
|
pub fn add_mod_override(&mut self, path: &str, data: Vec<u8>) {
|
|
self.mod_overrides.insert(path.to_string(), data);
|
|
}
|
|
|
|
pub fn open(&self, filename: &str) -> Option<AssetFile> {
|
|
// 1. Check user mod overrides first (non-destructive mod engine)
|
|
if let Some(data) = self.mod_overrides.get(filename) {
|
|
tracing::info!("AssetManager: redirected '{}' to active user mod", filename);
|
|
return Some(AssetFile::new(data.clone()));
|
|
}
|
|
|
|
// 2. Fallback to base asset
|
|
if let Some(data) = self.base_assets.get(filename) {
|
|
return Some(AssetFile::new(data.clone()));
|
|
}
|
|
|
|
tracing::warn!("AssetManager: asset '{}' not found", filename);
|
|
None
|
|
}
|
|
|
|
pub fn open_dir(&self, dir_name: &str) -> AssetDir {
|
|
let prefix = if dir_name.is_empty() || dir_name == "." {
|
|
"".to_string()
|
|
} else if !dir_name.ends_with('/') {
|
|
format!("{}/", dir_name)
|
|
} else {
|
|
dir_name.to_string()
|
|
};
|
|
|
|
let mut files = Vec::new();
|
|
for key in self.base_assets.keys().chain(self.mod_overrides.keys()) {
|
|
if key.starts_with(&prefix) {
|
|
let rest = &key[prefix.len()..];
|
|
if !rest.contains('/') {
|
|
files.push(rest.to_string());
|
|
}
|
|
}
|
|
}
|
|
files.sort();
|
|
files.dedup();
|
|
AssetDir::new(files)
|
|
}
|
|
}
|