use std::{collections::{HashMap, VecDeque}, any::{Any, TypeId}}; use std::slice::Iter; use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, component::Component}; #[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); pub struct Entity { id: EntityId, generation: u64, } struct Record { id: ArchetypeId, index: ArchetypeEntityId, } pub struct World { 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 { // take components from the bundle and add it to the archetype let columns = bundle.take_components(); let arche_idx = archetype.add_entity(columns); // 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 { let columns = bundle.take_components(); // create archetype let new_arch_id = self.next_archetype_id.increment(); let archetype = Archetype::from_columns(new_arch_id, columns); // 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: ArchetypeEntityId(0), }; 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_component(record.index) } pub fn query(&self) -> impl Iterator { self.archetypes .iter() .filter_map(|(_, a)| a.get_component_column::()) .flatten() } /* pub fn query_m(&self) -> impl Iterator { self.archetypes .iter() .filter_map(|(_, a)| a.get_component_column::()) .flatten() } */ }