use std::any::{type_name, TypeId}; use std::collections::HashSet; use crate::component::{Component, IsOptional as ComponentIsOptional}; use crate::lock::Lock; use crate::type_name::TypeName; use crate::EntityComponent; #[derive(Debug, Default)] pub struct ComponentStorage { entities: Vec, } impl ComponentStorage { pub fn find_entity_with_components( &self, start_index: usize, component_type_ids: &[(TypeId, ComponentIsOptional)], ) -> Option<(usize, &[EntityComponent])> { // TODO: This is a really dumb and slow way to do this. Refactor the world // to store components in archetypes self.entities .iter() .enumerate() .skip(start_index) .find(move |(_index, entity)| { let entity_components = entity .components .iter() .map(|component| component.id) .collect::>(); if component_type_ids .iter() .filter(|(_, is_optional)| *is_optional == ComponentIsOptional::No) .all(|(component_type_id, _)| { entity_components.contains(component_type_id) }) { return true; } false }) .map(|(index, entity)| (index, &*entity.components)) } pub fn push_entity( &mut self, components: impl IntoIterator>, ) { self.entities.push(Entity { components: components .into_iter() .map(|component| EntityComponent { id: (*component).type_id(), name: component.type_name(), component: Lock::new(component), }) .collect(), }); } } impl TypeName for ComponentStorage { fn type_name(&self) -> &'static str { type_name::() } } #[derive(Debug, Default)] struct Entity { components: Vec, }