diff options
Diffstat (limited to 'ecs/src/lib.rs')
| -rw-r--r-- | ecs/src/lib.rs | 73 | 
1 files changed, 71 insertions, 2 deletions
| diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index df46a5a..84009e0 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -1,6 +1,6 @@  #![deny(clippy::all, clippy::pedantic)] -use std::any::TypeId; +use std::any::{Any, TypeId};  use std::collections::{HashMap, HashSet};  use std::fmt::Debug;  use std::hash::Hash; @@ -8,7 +8,12 @@ use std::marker::PhantomData;  use std::slice::IterMut as SliceIterMut;  use crate::component::{Component, Sequence as ComponentSequence}; -use crate::system::{System, TypeErased as TypeErasedSystem}; +use crate::system::{ +    NoInitParamFlag as NoInitSystemParamFlag, +    Param as SystemParam, +    System, +    TypeErased as TypeErasedSystem, +};  pub mod component;  pub mod system; @@ -142,6 +147,70 @@ where      }  } +unsafe impl<'world, Comps> SystemParam<'world> for Query<'world, Comps> +where +    Comps: ComponentSequence, +{ +    type Flags = NoInitSystemParamFlag; +    type Input = (); + +    fn initialize<SystemImpl>(_system: &mut impl System<SystemImpl>, _input: Self::Input) +    { +    } + +    fn new<SystemImpl>( +        _system: &'world mut impl System<SystemImpl>, +        component_storage: &'world mut ComponentStorage, +    ) -> Self +    { +        Self::new(component_storage) +    } + +    fn is_compatible<Other: SystemParam<'world>>() -> bool +    { +        let other_comparable = Other::get_comparable(); + +        let Some(other_query_component_ids) = +            other_comparable.downcast_ref::<QueryComponentIds>() +        else { +            return true; +        }; + +        !other_query_component_ids.contains_component_in::<Comps>() +    } + +    fn get_comparable() -> Box<dyn Any> +    { +        Box::new(QueryComponentIds { +            component_type_ids: Comps::type_ids(), +        }) +    } +} + +#[derive(Debug)] +struct QueryComponentIds +{ +    component_type_ids: Vec<TypeId>, +} + +impl QueryComponentIds +{ +    fn contains_component_in<OtherComps>(&self) -> bool +    where +        OtherComps: ComponentSequence, +    { +        let other_component_type_ids = OtherComps::type_ids() +            .into_iter() +            .collect::<HashSet<TypeId>>(); + +        // TODO: Make this a bit smarter. Queries with a same component can be compatible +        // if one of the queries have a component the other one does not have +        self.component_type_ids +            .iter() +            .any(|component_type_id| other_component_type_ids.contains(component_type_id)) +    } +} +  pub struct QueryComponentIter<'world, Comps>  {      entity_iter: SliceIterMut<'world, Entity>, | 
