edict 0.6.1

Experimental entity-component-system library
Documentation
use core::any::TypeId;

use crate::{
    archetype::Archetype,
    component::ComponentInfo,
    entity::{EntityId, EntityLoc, Location},
    system::QueryArg,
};

use super::{
    Access, AsQuery, DefaultQuery, Fetch, ImmutableQuery, IntoQuery, Query, SendQuery, WriteAlias,
};

/// [`Fetch`] type for the [`Entities`] query.
pub struct EntitiesFetch<'a> {
    archetype: u32,
    entities: &'a [EntityId],
}

unsafe impl<'a> Fetch<'a> for EntitiesFetch<'a> {
    type Item = EntityLoc<'a>;

    #[inline(always)]
    fn dangling() -> Self {
        EntitiesFetch {
            archetype: u32::MAX,
            entities: &[],
        }
    }

    #[inline(always)]
    unsafe fn get_item(&mut self, idx: u32) -> EntityLoc<'a> {
        let id = *self.entities.get_unchecked(idx as usize);
        EntityLoc::from_parts(id, Location::new(self.archetype, idx))
    }
}

marker_type! {
    /// Queries entity ids.
    pub struct Entities;
}

impl AsQuery for Entities {
    type Query = Self;
}

impl IntoQuery for Entities {
    #[inline(always)]
    fn into_query(self) -> Self {
        self
    }
}

impl DefaultQuery for Entities {
    #[inline(always)]
    fn default_query() -> Self {
        Entities
    }
}

impl QueryArg for Entities {
    #[inline(always)]
    fn new() -> Self {
        Entities
    }
}

unsafe impl Query for Entities {
    type Fetch<'a> = EntitiesFetch<'a>;
    type Item<'a> = EntityLoc<'a>;

    const MUTABLE: bool = false;

    #[inline(always)]
    fn component_access(&self, _comp: &ComponentInfo) -> Result<Option<Access>, WriteAlias> {
        Ok(None)
    }

    #[inline(always)]
    fn visit_archetype(&self, _archetype: &Archetype) -> bool {
        true
    }

    #[inline(always)]
    unsafe fn access_archetype(&self, _archetype: &Archetype, _f: impl FnMut(TypeId, Access)) {}

    #[inline(always)]
    unsafe fn fetch<'a>(
        &self,
        arch_idx: u32,
        archetype: &'a Archetype,
        _epoch: crate::epoch::EpochId,
    ) -> EntitiesFetch<'a> {
        EntitiesFetch {
            archetype: arch_idx,
            entities: archetype.entities(),
        }
    }

    #[inline(always)]
    fn reserved_entity_item<'a>(&self, id: EntityId, idx: u32) -> Option<EntityLoc<'a>>
    where
        EntityId: 'a,
    {
        Some(EntityLoc::from_parts(id, Location::reserved(idx)))
    }
}

unsafe impl ImmutableQuery for Entities {}
unsafe impl SendQuery for Entities {}