ecs: fix filters

This commit is contained in:
SeanOMik 2024-03-08 00:19:23 -05:00 committed by SeanOMik
parent 7db913d15b
commit c3de9e77db
7 changed files with 97 additions and 3 deletions

View File

@ -177,10 +177,10 @@ where
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'!");
let col = NonNull::from(col);
// TODO: find a way to get the component column mutable with a borrowed archetype so its tick can be updated.
// the fetcher needs to tick the entities tick in the archetype
let col = NonNull::from(col);
FetchBorrowMut {
col,

View File

@ -0,0 +1,40 @@
use std::marker::PhantomData;
use crate::{query::{AsQuery, Query}, Archetype, Component, DynTypeId, World};
#[derive(Default)]
pub struct Has<C: Component> {
_marker: PhantomData<C>
}
impl<C: Component> Copy for Has<C> {}
impl<C: Component> Clone for Has<C> {
fn clone(&self) -> Self {
Self { _marker: self._marker.clone() }
}
}
impl<C: Component> Query for Has<C> {
type Item<'a> = ();
type Fetch<'a> = ();
fn new() -> Self {
Has {
_marker: PhantomData
}
}
fn can_visit_archetype(&self, archetype: &Archetype) -> bool {
archetype.has_column(DynTypeId::of::<C>())
}
unsafe fn fetch<'a>(&self, _world: &'a World, _: &'a Archetype, _: crate::Tick) -> Self::Fetch<'a> {
()
}
}
impl<C: Component> AsQuery for Has<C> {
type Query = Self;
}

View File

@ -0,0 +1,5 @@
pub mod has_component;
pub use has_component::*;
pub mod or;
pub use or::*;

View File

@ -0,0 +1,40 @@
use crate::{query::{AsQuery, Query}, Archetype, World};
#[derive(Default)]
pub struct Or<Q1: AsQuery, Q2: AsQuery> {
left: Q1::Query,
right: Q2::Query,
}
impl<Q1: AsQuery, Q2: AsQuery> Copy for Or<Q1, Q2> {}
impl<Q1: AsQuery, Q2: AsQuery> Clone for Or<Q1, Q2> {
fn clone(&self) -> Self {
Self { left: self.left.clone(), right: self.right.clone() }
}
}
impl<Q1: AsQuery, Q2: AsQuery> Query for Or<Q1, Q2> {
type Item<'a> = ();
type Fetch<'a> = ();
fn new() -> Self {
Or {
left: Q1::Query::new(),
right: Q2::Query::new(),
}
}
fn can_visit_archetype(&self, archetype: &Archetype) -> bool {
self.left.can_visit_archetype(archetype) || self.right.can_visit_archetype(archetype)
}
unsafe fn fetch<'a>(&self, _world: &'a World, _: &'a Archetype, _: crate::Tick) -> Self::Fetch<'a> {
()
}
}
impl<Q1: AsQuery, Q2: AsQuery> AsQuery for Or<Q1, Q2> {
type Query = Self;
}

View File

@ -29,6 +29,8 @@ pub use world::*;
pub mod dynamic;
pub mod filter;
/// A [`Fetch`]er implementation gets data out of an archetype.
pub trait Fetch<'a> {
/// The type that this Fetch yields

View File

@ -90,7 +90,7 @@ where
fn next(&mut self) -> Option<Self::Item> {
loop {
if Q::ALWAYS_FETCHES && F::ALWAYS_FETCHES {
if Q::ALWAYS_FETCHES {
// only fetch this query once.
// fetcher gets set to Some after this `next` call.
if self.fetcher.is_none() {

View File

@ -254,6 +254,13 @@ impl World {
v.into_iter()
}
/// View into the world for a set of entities that satisfy the queries.
pub fn filtered_view_iter<Q: AsQuery, F: AsQuery>(&self) -> ViewIter<Q::Query, F::Query> {
let archetypes = self.archetypes.values().collect();
let v = ViewState::new(self, Q::Query::new(), F::Query::new(), archetypes);
v.into_iter()
}
pub fn dynamic_view(&self) -> DynamicView {
DynamicView::new(self)
}