bevy-trait-query 0.19.0

Implementation of trait queries for the bevy game engine
Documentation
use alloc::boxed::Box;
use bevy_ecs::component::ComponentId;
use bevy_ecs::prelude::World;

use crate::{
    TraitQuery,
    trait_registry::{TraitImplMeta, TraitImplRegistry},
};

#[doc(hidden)]
pub struct TraitQueryState<Trait: ?Sized> {
    pub(crate) components: Box<[ComponentId]>,
    pub(crate) meta: Box<[TraitImplMeta<Trait>]>,
}

impl<Trait: ?Sized + TraitQuery> TraitQueryState<Trait> {
    pub(crate) fn init(world: &mut World) -> Self {
        #[cold]
        fn missing_registry<T: ?Sized + 'static>() -> TraitImplRegistry<T> {
            #[cfg(feature = "trace")]
            tracing::warn!(
                "no components found matching `{}`, did you forget to register them?",
                core::any::type_name::<T>()
            );
            TraitImplRegistry::<T>::default()
        }

        let mut registry = world.get_resource_or_insert_with(missing_registry);
        registry.seal();
        Self {
            components: registry.components.clone().into_boxed_slice(),
            meta: registry.meta.clone().into_boxed_slice(),
        }
    }

    #[inline]
    pub(crate) fn matches_component_set_any(
        &self,
        set_contains_id: &impl Fn(ComponentId) -> bool,
    ) -> bool {
        self.components.iter().copied().any(set_contains_id)
    }

    #[inline]
    pub(crate) fn matches_component_set_one(
        &self,
        set_contains_id: &impl Fn(ComponentId) -> bool,
    ) -> bool {
        let match_count = self
            .components
            .iter()
            .filter(|&&c| set_contains_id(c))
            .count();
        match_count == 1
    }
}