105 lines
2.3 KiB
Rust
105 lines
2.3 KiB
Rust
|
use std::marker::PhantomData;
|
||
|
|
||
|
use crate::{ComponentColumn, Fetch, Tick, DynTypeId, Query, world::World, 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>
|
||
|
}
|
||
|
|
||
|
// 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 {
|
||
|
type_id: DynTypeId::of::<T>(),
|
||
|
_phantom: PhantomData,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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.columns.iter().any(|c| c.info.type_id == 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.columns.iter().find(|c| c.info.type_id == 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>;
|
||
|
}
|