1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
use std::any::{ Any, TypeId }; use std::cell::{ RefCell, RefMut }; use std::collections::HashMap; use super::component::{ Component, ComponentStorage }; pub type EntityId = usize; pub struct ResourceManager { current_entity: RefCell<EntityId>, resources: HashMap<TypeId, Box<RefCell<dyn Any>>>, } impl ResourceManager { pub fn new() -> ResourceManager { let resources = HashMap::new(); let current_entity = RefCell::new(0); ResourceManager { current_entity, resources } } pub fn create_entity(&self) -> EntityBuilder { let mut id = self.current_entity.borrow_mut(); let builder = EntityBuilder::new(*id, self); *id += 1; builder } pub fn insert<R: Resource>(&mut self, resource: R) { self.resources.insert(TypeId::of::<R>(), Box::new(RefCell::new(resource))); } pub fn fetch_mut<R: Resource>(&self) -> RefMut<R> { let ref_mut = self.resources.get(&TypeId::of::<R>()) .unwrap() .as_ref() .borrow_mut(); RefMut::map(ref_mut, |r| r.downcast_mut::<R>().unwrap()) } pub fn fetch_mut_storage<C: Component>(&self) -> RefMut<C::Storage> { self.fetch_mut::<C::Storage>() } pub fn register_component<C: Component>(&mut self) { let component_storage = C::Storage::new(None); self.insert(component_storage); } pub fn is_registered<R: Resource>(&self) -> bool { match self.resources.get(&TypeId::of::<R>()) { Some(_) => true, None => false, } } pub fn len(&self) -> usize { self.resources.len() } } pub trait Resource: Any + 'static {} impl<R: Any + 'static> Resource for R {} pub struct EntityBuilder<'a> { id: EntityId, resources: &'a ResourceManager, } impl<'a> EntityBuilder<'a> { pub fn new(id: EntityId, resources: &ResourceManager) -> EntityBuilder { EntityBuilder { id, resources } } pub fn with<C: Component>(self, component: C) -> EntityBuilder<'a> { let mut storage = self.resources.fetch_mut_storage::<C>(); storage.add(component as C, self.id); self } pub fn build(self) -> EntityId { self.id } }