// Copyright 2016 Matthew Collins // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use crate::types::bit::Set as BSet; use crate::types::hash::FNVHash; use std::any::{Any, TypeId}; use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::hash::BuildHasherDefault; use std::marker::PhantomData; use std::mem; use std::ptr; use crate::render; use crate::world; /// Used to reference an entity. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Entity { id: usize, generation: u32, } /// Used to access compoents on an entity in an efficient /// way. pub struct Key { id: usize, _t: PhantomData, } impl Clone for Key { fn clone(&self) -> Self { Key { id: self.id, _t: PhantomData, } } } impl Copy for Key {} /// Used to search for entities with the requested components. pub struct Filter { bits: BSet, } impl Default for Filter { fn default() -> Self { Self::new() } } impl Filter { /// Creates an empty filter which matches everything pub fn new() -> Filter { Filter { bits: BSet::new(0) } } /// Adds the component to the filter. pub fn with(mut self, key: Key) -> Self { if self.bits.capacity() <= key.id { self.bits.resize(key.id + 1); } self.bits.set(key.id, true); self } } /// A system processes entities pub trait System { fn filter(&self) -> &Filter; fn update( &mut self, m: &mut Manager, world: &mut world::World, renderer: &mut render::Renderer, ); fn entity_added( &mut self, _m: &mut Manager, _e: Entity, _world: &mut world::World, _renderer: &mut render::Renderer, ) { } fn entity_removed( &mut self, _m: &mut Manager, _e: Entity, _world: &mut world::World, _renderer: &mut render::Renderer, ) { } } #[derive(Clone)] struct EntityState { last_components: BSet, components: BSet, removed: bool, } /// Stores and manages a collection of entities. #[derive(Default)] pub struct Manager { num_components: usize, entities: Vec<(Option, u32)>, free_entities: Vec, components: Vec>, component_ids: RefCell>>, systems: Option>>, render_systems: Option>>, changed_entity_components: HashSet>, } impl Manager { /// Creates a new manager. pub fn new() -> Manager { Manager { num_components: 0, entities: vec![( Some(EntityState { last_components: BSet::new(0), components: BSet::new(0), removed: false, }), 0, )], // Has the world entity pre-defined free_entities: vec![], components: vec![], component_ids: RefCell::new(HashMap::with_hasher(BuildHasherDefault::default())), systems: Some(vec![]), render_systems: Some(vec![]), changed_entity_components: HashSet::with_hasher(BuildHasherDefault::default()), } } /// Returns the world entity. This should never be removed. pub fn get_world(&self) -> Entity { Entity { id: 0, generation: 0, } } /// Adds a system which will be called every tick pub fn add_system(&mut self, s: S) { self.systems.as_mut().unwrap().push(Box::new(s)); } /// Adds a system which will be called every frame pub fn add_render_system(&mut self, s: S) { self.render_systems.as_mut().unwrap().push(Box::new(s)); } /// Ticks all tick systems pub fn tick(&mut self, world: &mut world::World, renderer: &mut render::Renderer) { self.process_entity_changes(world, renderer); let mut systems = self.systems.take().unwrap(); for sys in &mut systems { sys.update(self, world, renderer); } self.systems = Some(systems); self.process_entity_changes(world, renderer); } /// Ticks all render systems pub fn render_tick(&mut self, world: &mut world::World, renderer: &mut render::Renderer) { self.process_entity_changes(world, renderer); let mut systems = self.render_systems.take().unwrap(); for sys in &mut systems { sys.update(self, world, renderer); } self.render_systems = Some(systems); self.process_entity_changes(world, renderer); } fn process_entity_changes( &mut self, world: &mut world::World, renderer: &mut render::Renderer, ) { let changes = self.changed_entity_components.clone(); self.changed_entity_components = HashSet::with_hasher(BuildHasherDefault::default()); for entity in changes { let (cur, state) = { let state = self.entities[entity.id].0.as_mut().unwrap(); let cur = state.components.clone(); let orig = state.clone(); state.components.or(&state.last_components); (cur, orig) }; self.trigger_add_for_systems( entity, &state.last_components, &state.components, world, renderer, ); self.trigger_add_for_render_systems( entity, &state.last_components, &state.components, world, renderer, ); self.trigger_remove_for_systems( entity, &state.last_components, &state.components, world, renderer, ); self.trigger_remove_for_render_systems( entity, &state.last_components, &state.components, world, renderer, ); for i in 0..self.components.len() { if !state.components.get(i) && state.last_components.get(i) { let components = self.components.get_mut(i).and_then(|v| v.as_mut()).unwrap(); components.remove(entity.id); } } { let state = self.entities[entity.id].0.as_mut().unwrap(); state.components = cur; state.last_components = state.components.clone(); } if state.removed { self.free_entities.push(entity.id); self.entities[entity.id].0 = None; } } } /// Returns all entities matching the filter pub fn find(&self, filter: &Filter) -> Vec { let mut ret = vec![]; // Skip the world entity. for (i, &(ref set, gen)) in self.entities[1..].iter().enumerate() { if let Some(set) = set.as_ref() { if !set.removed && set.components.includes_set(&filter.bits) { ret.push(Entity { id: i + 1, generation: gen, }); } } } ret } /// Allocates a new entity without any components. pub fn create_entity(&mut self) -> Entity { if let Some(id) = self.free_entities.pop() { let entity = &mut self.entities[id]; entity.0 = Some(EntityState { last_components: BSet::new(self.num_components), components: BSet::new(self.num_components), removed: false, }); entity.1 += 1; return Entity { id, generation: entity.1, }; } let id = self.entities.len(); self.entities.push(( Some(EntityState { last_components: BSet::new(self.num_components), components: BSet::new(self.num_components), removed: false, }), 0, )); Entity { id, generation: 0 } } /// Deallocates an entity and frees its components pub fn remove_entity(&mut self, e: Entity) { if let Some(set) = self.entities[e.id].0.as_mut() { set.components = BSet::new(self.components.len()); set.removed = true; self.changed_entity_components.insert(e); } } /// Deallocates all entities/components excluding the world entity pub fn remove_all_entities( &mut self, world: &mut world::World, renderer: &mut render::Renderer, ) { for (id, e) in self.entities[1..].iter_mut().enumerate() { if let Some(set) = e.0.as_mut() { set.components = BSet::new(self.components.len()); set.removed = true; self.changed_entity_components.insert(Entity { id: id + 1, generation: e.1, }); } } self.process_entity_changes(world, renderer); } /// Returns whether an entity reference is valid. pub fn is_entity_valid(&self, e: Entity) -> bool { match self.entities.get(e.id) { Some(val) => val.1 == e.generation && val.0.is_some(), None => false, } } /// Gets a key for the component type. Creates one /// if the component has never been referenced before. pub fn get_key(&self) -> Key { let mut ids = self.component_ids.borrow_mut(); let next_id = ids.len(); let id = ids.entry(TypeId::of::()).or_insert(next_id); Key { id: *id, _t: PhantomData, } } /// Adds the component to the target entity /// # Panics /// Panics when the target entity doesn't exist pub fn add_component(&mut self, entity: Entity, key: Key, val: T) { if self.components.len() <= key.id { while self.components.len() <= key.id { self.components.push(None); } } if self.components[key.id].is_none() { self.components[key.id] = Some(ComponentMem::new::()); self.num_components += 1; for &mut (ref mut set, _) in &mut self.entities { if let Some(set) = set.as_mut() { set.last_components.resize(self.num_components); set.components.resize(self.num_components); } } } let mut e = self.entities.get_mut(entity.id); let set = match e { Some(ref mut val) => { if val.1 == entity.generation { &mut val.0 } else { panic!("Missing entity") } } None => panic!("Missing entity"), }; let set = match set.as_mut() { Some(val) => val, None => panic!("Missing entity"), }; if set.components.get(key.id) != set.last_components.get(key.id) { panic!("Double change within a single tick"); } if set.components.get(key.id) { panic!("Duplicate add"); } set.components.set(key.id, true); self.changed_entity_components.insert(entity); let components = self .components .get_mut(key.id) .and_then(|v| v.as_mut()) .unwrap(); components.add(entity.id, val); } fn trigger_add_for_systems( &mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer, ) { let mut systems = self.systems.take().unwrap(); for sys in &mut systems { if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) { sys.entity_added(self, e, world, renderer); } } self.systems = Some(systems); } fn trigger_add_for_render_systems( &mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer, ) { let mut systems = self.render_systems.take().unwrap(); for sys in &mut systems { if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) { sys.entity_added(self, e, world, renderer); } } self.render_systems = Some(systems); } /// Same as `add_component` but doesn't require a key. Using a key /// is better for frequent lookups. pub fn add_component_direct(&mut self, entity: Entity, val: T) { let key = self.get_key(); self.add_component(entity, key, val); } /// Removes the component to the target entity. Returns whether anything /// was removed. /// # Panics /// Panics when the target entity doesn't exist pub fn remove_component(&mut self, entity: Entity, key: Key) -> bool { if self.components.len() <= key.id { return false; } if self.components[key.id].is_none() { return false; } let mut e = self.entities.get_mut(entity.id); let set = match e { Some(ref mut val) => { if val.1 == entity.generation { &mut val.0 } else { panic!("Missing entity") } } None => panic!("Missing entity"), }; let set = match set.as_mut() { Some(val) => val, None => panic!("Missing entity"), }; if set.components.get(key.id) != set.last_components.get(key.id) { panic!("Double change within a single tick"); } if !set.components.get(key.id) { return false; } set.components.set(key.id, false); self.changed_entity_components.insert(entity); // Actual removal is delayed until ticking finishes true } fn trigger_remove_for_systems( &mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer, ) { let mut systems = self.systems.take().unwrap(); for sys in &mut systems { if !new_set.includes_set(&sys.filter().bits) && old_set.includes_set(&sys.filter().bits) { sys.entity_removed(self, e, world, renderer); } } self.systems = Some(systems); } fn trigger_remove_for_render_systems( &mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer, ) { let mut systems = self.render_systems.take().unwrap(); for sys in &mut systems { if !new_set.includes_set(&sys.filter().bits) && old_set.includes_set(&sys.filter().bits) { sys.entity_removed(self, e, world, renderer); } } self.render_systems = Some(systems); } /// Same as `remove_component` but doesn't require a key. Using a key /// is better for frequent lookups. pub fn remove_component_direct(&mut self, entity: Entity) -> bool { let key = self.get_key(); self.remove_component::(entity, key) } /// Returns the given component that the key points to if it exists. pub fn get_component<'a, 'b: 'a, T>(&'a self, entity: Entity, key: Key) -> Option<&'b T> { let components = match self.components.get(key.id).and_then(|v| v.as_ref()) { Some(val) => val, None => return None, }; let set = match self.entities.get(entity.id).as_ref() { Some(val) => { if val.1 == entity.generation { &val.0 } else { return None; } } None => return None, }; if !set.as_ref().map_or(false, |v| v.components.get(key.id)) { return None; } Some(unsafe { mem::transmute::<&T, &T>(components.get(entity.id)) }) } /// Same as `get_component` but doesn't require a key. Using a key /// is better for frequent lookups. pub fn get_component_direct<'a, 'b: 'a, T: Any>(&'a self, entity: Entity) -> Option<&'b T> { let key = self.get_key(); self.get_component(entity, key) } /// Returns the given component that the key points to if it exists. pub fn get_component_mut<'a, 'b: 'a, T>( &'a mut self, entity: Entity, key: Key, ) -> Option<&'b mut T> { let components = match self.components.get_mut(key.id).and_then(|v| v.as_mut()) { Some(val) => val, None => return None, }; let set = match self.entities.get(entity.id).as_ref() { Some(val) => { if val.1 == entity.generation { &val.0 } else { return None; } } None => return None, }; if !set.as_ref().map_or(false, |v| v.components.get(key.id)) { return None; } Some(unsafe { mem::transmute::<&mut T, &mut T>(components.get_mut(entity.id)) }) } /// Same as `get_component_mut` but doesn't require a key. Using a key /// is better for frequent lookups. pub fn get_component_mut_direct<'a, 'b: 'a, T: Any>( &'a mut self, entity: Entity, ) -> Option<&'b mut T> { let key = self.get_key(); self.get_component_mut(entity, key) } } const COMPONENTS_PER_BLOCK: usize = 64; struct ComponentMem { data: Vec, BSet, usize)>>, component_size: usize, drop_func: Box, } impl ComponentMem { fn new() -> ComponentMem { ComponentMem { data: vec![], component_size: mem::size_of::(), drop_func: Box::new(|data| unsafe { let mut val = mem::MaybeUninit::::uninit(); ptr::copy(data as *mut T, val.as_mut_ptr(), 1); mem::drop(val); }), } } fn add(&mut self, index: usize, val: T) { while self.data.len() < (index / COMPONENTS_PER_BLOCK) + 1 { self.data.push(None); } let idx = index / COMPONENTS_PER_BLOCK; let rem = index % COMPONENTS_PER_BLOCK; if self.data[idx].is_none() { self.data[idx] = Some(( vec![0; self.component_size * COMPONENTS_PER_BLOCK], BSet::new(COMPONENTS_PER_BLOCK), 0, )); } let data = self.data[idx].as_mut().unwrap(); let start = rem * self.component_size; data.2 += 1; data.1.set(rem, true); unsafe { ptr::write(data.0.as_mut_ptr().add(start) as *mut T, val); } } fn remove(&mut self, index: usize) { let idx = index / COMPONENTS_PER_BLOCK; let rem = index % COMPONENTS_PER_BLOCK; let count = { let data = self.data[idx].as_mut().unwrap(); let start = rem * self.component_size; data.1.set(rem, false); // We don't have access to the actual type in this method so // we use the drop_func which stores the type in its closure // to handle the dropping for us. unsafe { (self.drop_func)(data.0.as_mut_ptr().add(start)); } data.2 -= 1; data.2 }; if count == 0 { self.data[idx] = None; } } fn get(&self, index: usize) -> &T { let idx = index / COMPONENTS_PER_BLOCK; let rem = index % COMPONENTS_PER_BLOCK; let data = self.data[idx].as_ref().unwrap(); let start = rem * self.component_size; unsafe { &*(data.0.as_ptr().add(start) as *const T) } } fn get_mut(&mut self, index: usize) -> &mut T { let idx = index / COMPONENTS_PER_BLOCK; let rem = index % COMPONENTS_PER_BLOCK; let data = self.data[idx].as_mut().unwrap(); let start = rem * self.component_size; unsafe { &mut *(data.0.as_mut_ptr().add(start) as *mut T) } } } impl Drop for ComponentMem { fn drop(&mut self) { for data in &mut self.data { if let Some(data) = data.as_mut() { for i in 0..COMPONENTS_PER_BLOCK { if data.1.get(i) { let start = i * self.component_size; unsafe { (self.drop_func)(data.0.as_mut_ptr().add(start)); } } } } } } }