use std::collections::BTreeMap; use std::cmp::Ordering; use crate::render::{Mesh, Material, Light}; type Map = BTreeMap, T>; pub struct Manager { meshes: Map, materials: Map, lights: Map, counter: u64, } impl Manager { pub fn new() -> Self { Manager { meshes: BTreeMap::new(), materials: BTreeMap::new(), lights: BTreeMap::new(), counter: 0, } } fn map(&self) -> &Map { T::map(&self) } pub fn add(&mut self, r: T) -> ResourceID { let id = ResourceID { numerical: self.counter, phantom: std::marker::PhantomData, }; self.counter += 1; T::map_mut(self).insert(id, r); id } } pub trait Resource: Sized { fn map(rm: &Manager) -> ⤅ fn map_mut(rm: &mut Manager) -> &mut Map; } impl Resource for Light { fn map(rm: &Manager) -> &Map { &rm.lights } fn map_mut(rm: &mut Manager) -> &mut Map { &mut rm.lights } } impl Resource for Mesh { fn map(rm: &Manager) -> &Map { &rm.meshes } fn map_mut(rm: &mut Manager) -> &mut Map { &mut rm.meshes } } impl Resource for Material { fn map(rm: &Manager) -> &Map { &rm.materials } fn map_mut(rm: &mut Manager) -> &mut Map { &mut rm.materials } } pub struct ResourceID { numerical: u64, phantom: std::marker::PhantomData, } impl Clone for ResourceID { fn clone(&self) -> ResourceID { ResourceID { numerical: self.numerical.clone(), phantom: std::marker::PhantomData, } } } impl Copy for ResourceID {} impl ResourceID { pub fn get(self, rm: &Manager) -> &T { rm.map::().get(&self).unwrap() } } impl Ord for ResourceID { fn cmp(&self, other: &Self) -> Ordering { self.numerical.cmp(&other.numerical) } } impl PartialOrd for ResourceID { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl PartialEq for ResourceID { fn eq(&self, other: &Self) -> bool { self.numerical == other.numerical } } impl Eq for ResourceID {}