96 lines
2.6 KiB
Rust
96 lines
2.6 KiB
Rust
use std::{any::TypeId, cell::Ref, marker::PhantomData};
|
|
|
|
use crate::{query::{AsQuery, Fetch, Query}, Archetype, ComponentColumn, Entity, World};
|
|
|
|
use super::{Relation, RelationOriginComponent};
|
|
|
|
pub struct FetchRelatePair<'a, T> {
|
|
col: &'a ComponentColumn,
|
|
arch: &'a Archetype,
|
|
_phantom: PhantomData<&'a T>
|
|
}
|
|
|
|
impl<'a, R> Fetch<'a> for FetchRelatePair<'a, R>
|
|
where
|
|
R: Relation,
|
|
{
|
|
type Item = (Entity, Ref<'a, R>, Entity);
|
|
|
|
fn dangling() -> Self {
|
|
unreachable!()
|
|
}
|
|
|
|
unsafe fn get_item(&mut self, entity: crate::world::ArchetypeEntityId) -> Self::Item {
|
|
let comp: Ref<RelationOriginComponent<R>> = self.col.get(entity.0 as usize);
|
|
let rel_target = comp.target;
|
|
let rel_origin = self.arch.entity_at_index(entity).unwrap();
|
|
|
|
let comp = Ref::map(comp, |r| &r.relation);
|
|
(rel_origin, comp, rel_target)
|
|
}
|
|
}
|
|
|
|
pub struct QueryRelatePair<R> {
|
|
_marker: PhantomData<R>,
|
|
}
|
|
|
|
impl<R> Copy for QueryRelatePair<R> {}
|
|
|
|
impl<R> Clone for QueryRelatePair<R> {
|
|
fn clone(&self) -> Self {
|
|
*self
|
|
}
|
|
}
|
|
|
|
impl<R> QueryRelatePair<R> {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
_marker: PhantomData
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<R> Query for QueryRelatePair<R>
|
|
where
|
|
R: Relation + 'static
|
|
{
|
|
type Item<'a> = (Entity, Ref<'a, R>, Entity);
|
|
|
|
type Fetch<'a> = FetchRelatePair<'a, R>;
|
|
|
|
fn new() -> Self {
|
|
QueryRelatePair::<R>::new()
|
|
}
|
|
|
|
fn can_visit_archetype(&self, archetype: &crate::archetype::Archetype) -> bool {
|
|
let tyid = crate::DynTypeId::Rust(TypeId::of::<RelationOriginComponent<R>>());
|
|
archetype.has_column(tyid)
|
|
}
|
|
|
|
unsafe fn fetch<'a>(&self, _world: &'a World, archetype: &'a crate::archetype::Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
|
|
let _ = tick;
|
|
let col = archetype.get_column(TypeId::of::<RelationOriginComponent<R>>())
|
|
.expect("You ignored 'can_visit_archetype'!");
|
|
|
|
FetchRelatePair {
|
|
col,
|
|
arch: archetype,
|
|
_phantom: PhantomData,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A query that fetches the origin, and target of a relation of type `R`.
|
|
///
|
|
/// It provides it as a tuple in the following format: `(origin, relation, target)`.
|
|
/// Similar to [`RelatesTo`](super::RelatesTo), you can use
|
|
/// [`ViewState::relate_pair`](crate::relation::ViewState::relate_pair) to get a view that
|
|
/// fetches the pair, or unlike [`RelatesTo`](super::RelatesTo), you can do the common
|
|
/// procedure of using [`World::view`].
|
|
pub struct RelatePair<R: Relation> {
|
|
_marker: PhantomData<R>,
|
|
}
|
|
|
|
impl<R: Relation> AsQuery for RelatePair<R> {
|
|
type Query = QueryRelatePair<R>;
|
|
}
|