128 lines
3.2 KiB
Rust
128 lines
3.2 KiB
Rust
use std::collections::BTreeMap;
|
|
use std::cmp::Ordering;
|
|
|
|
use crate::render::{Mesh, Material, Light};
|
|
|
|
type Map<T> = BTreeMap<ResourceID<T>, T>;
|
|
|
|
pub struct Manager {
|
|
meshes: Map<Mesh>,
|
|
materials: Map<Material>,
|
|
lights: Map<Light>,
|
|
|
|
label_to_numeric: BTreeMap<String, u64>,
|
|
counter: u64,
|
|
}
|
|
impl ecs::Global for Manager {}
|
|
|
|
impl Manager {
|
|
pub fn new() -> Self {
|
|
Manager {
|
|
meshes: BTreeMap::new(),
|
|
materials: BTreeMap::new(),
|
|
lights: BTreeMap::new(),
|
|
|
|
label_to_numeric: BTreeMap::new(),
|
|
counter: 0,
|
|
}
|
|
}
|
|
|
|
fn map<T: Resource>(&self) -> &Map<T> {
|
|
T::map(&self)
|
|
}
|
|
|
|
pub fn add<T: Resource, S: ToString>(&mut self, r: T, label: Option<S>) -> ResourceID<T> {
|
|
let numeric = self.counter;
|
|
if let Some(label) = label {
|
|
self.label_to_numeric.insert(label.to_string(), numeric);
|
|
}
|
|
let id = ResourceID {
|
|
numeric,
|
|
phantom: std::marker::PhantomData,
|
|
};
|
|
|
|
self.counter += 1;
|
|
T::map_mut(self).insert(id, r);
|
|
id
|
|
}
|
|
|
|
pub fn by_label<T: Resource, S: ToString>(&self, label: S) -> Option<ResourceID<T>> {
|
|
let label = label.to_string();
|
|
let numeric = self.label_to_numeric.get(&label)?.clone();
|
|
let rid = ResourceID {
|
|
numeric,
|
|
phantom: std::marker::PhantomData,
|
|
};
|
|
if let None = T::map(self).get(&rid) {
|
|
return None
|
|
}
|
|
Some(rid)
|
|
}
|
|
}
|
|
|
|
pub trait Resource: Sized {
|
|
fn map(rm: &Manager) -> &Map<Self>;
|
|
fn map_mut(rm: &mut Manager) -> &mut Map<Self>;
|
|
}
|
|
|
|
impl Resource for Light {
|
|
fn map(rm: &Manager) -> &Map<Self> { &rm.lights }
|
|
fn map_mut(rm: &mut Manager) -> &mut Map<Self> { &mut rm.lights }
|
|
}
|
|
impl Resource for Mesh {
|
|
fn map(rm: &Manager) -> &Map<Self> { &rm.meshes }
|
|
fn map_mut(rm: &mut Manager) -> &mut Map<Self> { &mut rm.meshes }
|
|
}
|
|
impl Resource for Material {
|
|
fn map(rm: &Manager) -> &Map<Self> { &rm.materials }
|
|
fn map_mut(rm: &mut Manager) -> &mut Map<Self> { &mut rm.materials }
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct ResourceID<T: Resource> {
|
|
numeric: u64,
|
|
phantom: std::marker::PhantomData<T>,
|
|
}
|
|
|
|
impl mlua::UserData for ResourceID<Light> {}
|
|
impl mlua::UserData for ResourceID<Mesh> {}
|
|
impl mlua::UserData for ResourceID<Material> {}
|
|
|
|
impl <T: Resource> Clone for ResourceID<T> {
|
|
fn clone(&self) -> ResourceID<T> {
|
|
ResourceID {
|
|
numeric: self.numeric.clone(),
|
|
phantom: std::marker::PhantomData,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl <T: Resource> Copy for ResourceID<T> {}
|
|
|
|
impl <T: Resource> ResourceID<T> {
|
|
pub fn get(self, rm: &Manager) -> &T {
|
|
rm.map::<T>().get(&self).unwrap()
|
|
}
|
|
}
|
|
|
|
impl <T: Resource> Ord for ResourceID<T> {
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
self.numeric.cmp(&other.numeric)
|
|
}
|
|
}
|
|
|
|
impl <T: Resource> PartialOrd for ResourceID<T> {
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
Some(self.cmp(other))
|
|
}
|
|
}
|
|
|
|
impl <T: Resource> PartialEq for ResourceID<T> {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.numeric == other.numeric
|
|
}
|
|
}
|
|
|
|
impl <T: Resource> Eq for ResourceID<T> {}
|
|
|