use fxhash::FxHasher;
use std::{collections::HashMap, hash::Hasher, marker::PhantomData};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Handle<T> { pub hash: u64, pub data: PhantomData<T> }
impl <T> Handle<T> {
fn new(hash: u64) -> Self { Self { hash, data: PhantomData::default() } }
}
#[derive(Debug, Clone)]
pub struct ResourceCache<T> {
assets: HashMap<u64, T>,
}
impl<T> ResourceCache<T> {
pub fn new() -> Self { Self { assets: HashMap::new() } }
pub fn hash_path(path: String) -> u64 {
let mut hasher = FxHasher::default();
hasher.write(path.as_bytes());
return hasher.finish();
}
pub fn load<F>(&mut self, path: impl Into<String>, load: F) -> Handle<T> where F: Fn() -> T {
let hash = Self::hash_path(path.into());
if self.assets.contains_key(&hash) {
return Handle::new(hash);
} else {
self.assets.insert(hash, load());
return Handle::new(hash);
}
}
pub fn get(&self, handle: &Handle<T>) -> Option<&T> { self.assets.get(&handle.hash) }
pub fn get_mut(&mut self, handle: &Handle<T>) -> Option<&mut T> { self.assets.get_mut(&handle.hash) }
pub fn insert(&mut self, hash: u64, value: T) { self.assets.insert(hash, value); }
pub fn replace(&mut self, handle: &Handle<T>, value: T) { self.assets.insert(handle.hash, value); }
}