113 lines
2.4 KiB
Rust
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>;
|
|
} |