use std::{collections::{HashMap, VecDeque}, any::{Any, TypeId}}; use std::slice::Iter; use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, component::Component, query::QuerySimple}; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct EntityId(pub u64); /// The id of the entity for the Archetype. /// The Archetype struct uses this as the index in the component columns #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct ArchetypeEntityId(pub u64); #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Entity { id: EntityId, generation: u64, } pub struct Record { id: ArchetypeId, index: ArchetypeEntityId, } pub struct World { pub(crate) archetypes: HashMap, next_archetype_id: ArchetypeId, entity_index: HashMap, dead_entities: VecDeque, next_entity_id: EntityId, } impl World { pub fn new() -> Self { Self { archetypes: HashMap::new(), next_archetype_id: ArchetypeId(0), entity_index: HashMap::new(), dead_entities: VecDeque::new(), next_entity_id: EntityId(0), } } fn get_new_entity(&mut self) -> Entity { match self.dead_entities.pop_front() { Some(e) => e, None => { let new_id = self.next_entity_id; self.next_entity_id.0 += 1; Entity { id: new_id, generation: 0, } } } } pub fn spawn(&mut self, bundle: B) -> Entity where B: Bundle { let bundle_types = bundle.types(); let new_entity = self.get_new_entity(); // try to find an archetype let archetype = self.archetypes .values_mut() .find(|a| a.is_archetype_for(bundle_types.clone())); if let Some(archetype) = archetype { let arche_idx = archetype.add_entity(new_entity, bundle); // Create entity record and store it let record = Record { id: archetype.id, index: arche_idx, }; self.entity_index.insert(new_entity.id, record); } // create a new archetype if one isn't found else { // create archetype let new_arch_id = self.next_archetype_id.increment(); let mut archetype = Archetype::from_bundle_info(new_arch_id, bundle.info()); let entity_arch_id = archetype.add_entity(new_entity, bundle); // store archetype self.archetypes.insert(new_arch_id, archetype); // Create entity record and store it let record = Record { id: new_arch_id, // this is the first entity in the archetype index: entity_arch_id, }; self.entity_index.insert(new_entity.id, record); } new_entity } pub fn get_component(&self, entity: Entity) -> Option<&T> { let record = self.entity_index.get(&entity.id)?; let archetype = self.archetypes.get(&record.id)?; archetype.get_entity_component(record.index) } pub fn query(&self) -> impl Iterator { self.archetypes .iter() .filter_map(|(_, a)| a.get_component_column::()) .flatten() } pub fn query_better(&self) -> QuerySimple { let archetypes = self.archetypes.values().collect(); QuerySimple::new(archetypes) } /* pub fn query_m(&self) -> impl Iterator { self.archetypes .iter() .filter_map(|(_, a)| a.get_component_column::()) .flatten() } */ } #[cfg(test)] mod tests { use super::World; struct Vec2 { x: f32, y: f32, } #[test] fn spawning_entity() { let mut world = World::new(); let _e = world.spawn((Vec2 { x: 10.0, y: 15.0, }, )); } }