lyra-engine/lyra-ecs/src/query/tick.rs

113 lines
2.4 KiB
Rust

use std::marker::PhantomData;
use crate::{ComponentColumn, Tick, DynTypeId, World};
use super::{Query, Fetch, AsQuery};
#[derive(Clone, Copy, Debug, Default)]
pub struct TickOf<T> {
tick: Tick,
_phantom: PhantomData<T>,
}
impl<T> std::ops::Deref for TickOf<T> {
type Target = Tick;
fn deref(&self) -> &Self::Target {
&self.tick
}
}
/// Fetcher for borrowing components from archetypes.
pub struct FetchTickOf<'a, T> {
col: &'a ComponentColumn,
_phantom: PhantomData<&'a T>
}
impl<'a, T> Fetch<'a> for FetchTickOf<'a, T>
where
T: 'a,
{
type Item = Tick;
fn dangling() -> Self {
unreachable!()
}
unsafe fn get_item(&mut self, entity: crate::world::ArchetypeEntityId) -> Self::Item {
self.col.entity_ticks[entity.0 as usize]
}
}
/// A Query for borrowing components from archetypes.
///
/// Since [`AsQuery`] is implemented for `&T`, you can use this query like this:
/// ```nobuild
/// for ts in world.view::<&T>() {
/// println!("Got a &T!");
/// }
/// ```
pub struct QueryTickOf<T> {
type_id: DynTypeId,
_phantom: PhantomData<T>
}
impl<T: 'static> Default for QueryTickOf<T> {
fn default() -> Self {
Self {
type_id: DynTypeId::of::<T>(),
_phantom: PhantomData,
}
}
}
// manually implemented to avoid a Copy bound on T
impl<T> Copy for QueryTickOf<T> {}
// manually implemented to avoid a Clone bound on T
impl<T> Clone for QueryTickOf<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T: 'static> QueryTickOf<T> {
pub fn new() -> Self {
Self::default()
}
}
impl<T> Query for QueryTickOf<T>
where
T: 'static
{
type Item<'a> = Tick;
type Fetch<'a> = FetchTickOf<'a, T>;
fn new() -> Self {
QueryTickOf::<T>::new()
}
fn can_visit_archetype(&self, archetype: &crate::archetype::Archetype) -> bool {
archetype.has_column(self.type_id)
}
unsafe fn fetch<'a>(&self, _world: &'a World, archetype: &'a crate::archetype::Archetype, _tick: crate::Tick) -> Self::Fetch<'a> {
let col = archetype.get_column(self.type_id)
.expect("You ignored 'can_visit_archetype'!");
FetchTickOf {
col,
_phantom: PhantomData,
}
}
}
impl<T: 'static> AsQuery for QueryTickOf<T> {
type Query = Self;
}
impl<T: 'static> AsQuery for TickOf<T> {
type Query = QueryTickOf<T>;
}