Implement query borrow and borrow mut for all &T and &mut T

This commit is contained in:
SeanOMik 2023-11-25 19:58:14 -05:00
parent 92e284e625
commit 2e53156b0d
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
6 changed files with 139 additions and 50 deletions

View File

@ -8,6 +8,9 @@ mod component;
mod query; mod query;
mod component_info; mod component_info;
#[cfg(test)]
mod tests;
#[derive(Debug)] #[derive(Debug)]
pub struct Position2d(i32, i32); pub struct Position2d(i32, i32);
@ -28,10 +31,6 @@ fn main() {
println!("\nstart of querying!\n"); println!("\nstart of querying!\n");
/* for pos in world.query::<Position2d>() {
println!("Queried Position2d: {:?}", pos);
} */
let mut q = world.query_better(); let mut q = world.query_better();
q.with_component::<Position2d>(); q.with_component::<Position2d>();

View File

@ -1,6 +1,8 @@
use std::{marker::PhantomData, any::TypeId, ptr::NonNull}; use std::{marker::PhantomData, any::TypeId, ptr::NonNull};
use super::{Fetch, Query}; use crate::component::Component;
use super::{Fetch, Query, AsQuery, IntoQuery, DefaultQuery};
pub struct FetchBorrow<'a, T> { pub struct FetchBorrow<'a, T> {
ptr: NonNull<u8>, ptr: NonNull<u8>,
@ -35,6 +37,15 @@ pub struct QueryBorrow<T> {
_phantom: PhantomData<T> _phantom: PhantomData<T>
} }
impl<T: 'static> QueryBorrow<T> {
pub fn new() -> Self {
Self {
type_id: TypeId::of::<T>(),
_phantom: PhantomData,
}
}
}
impl<T> Query for QueryBorrow<T> impl<T> Query for QueryBorrow<T>
where where
T: 'static T: 'static
@ -60,6 +71,26 @@ where
} }
} }
impl<T: 'static> AsQuery for QueryBorrow<T> {
type Query = Self;
}
impl<T: 'static> DefaultQuery for QueryBorrow<T> {
fn default_query() -> Self {
QueryBorrow::<T>::new()
}
}
impl<T: 'static> AsQuery for &T {
type Query = QueryBorrow<T>;
}
impl<T: 'static> DefaultQuery for &T {
fn default_query() -> QueryBorrow<T> {
QueryBorrow::<T>::new()
}
}
pub struct FetchBorrowMut<'a, T> { pub struct FetchBorrowMut<'a, T> {
ptr: NonNull<u8>, ptr: NonNull<u8>,
size: usize, size: usize,
@ -93,6 +124,15 @@ pub struct QueryBorrowMut<T> {
_phantom: PhantomData<T> _phantom: PhantomData<T>
} }
impl<T: 'static> QueryBorrowMut<T> {
pub fn new() -> Self {
Self {
type_id: TypeId::of::<T>(),
_phantom: PhantomData,
}
}
}
impl<T> Query for QueryBorrowMut<T> impl<T> Query for QueryBorrowMut<T>
where where
T: 'static T: 'static
@ -118,29 +158,34 @@ where
} }
} }
impl<T: 'static> AsQuery for QueryBorrowMut<T> {
type Query = Self;
}
impl<T: 'static> DefaultQuery for QueryBorrowMut<T> {
fn default_query() -> Self {
QueryBorrowMut::<T>::new()
}
}
impl<T: 'static> AsQuery for &mut T {
type Query = QueryBorrowMut<T>;
}
impl<T: 'static> DefaultQuery for &mut T {
fn default_query() -> QueryBorrowMut<T> {
QueryBorrowMut::<T>::new()
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::any::TypeId; use std::any::TypeId;
use crate::{world::World, archetype::Archetype, query::View}; use crate::{world::World, archetype::Archetype, query::View, tests::Vec2};
use super::{QueryBorrow, QueryBorrowMut}; use super::{QueryBorrow, QueryBorrowMut};
#[derive(Clone, Copy, Debug, Default)]
struct Vec2 {
x: f32,
y: f32,
}
impl Vec2 {
pub fn new(x: f32, y: f32) -> Self {
Self {
x,
y,
}
}
}
/// Creates a world with two entities, one at Vec(10, 50) and /// Creates a world with two entities, one at Vec(10, 50) and
/// the other at Vec2(25, 30). /// the other at Vec2(25, 30).
fn prepare_world() -> World { fn prepare_world() -> World {

View File

@ -1,6 +1,6 @@
use crate::{world::Entity, archetype::{Archetype, ArchetypeId}}; use crate::{world::Entity, archetype::{Archetype, ArchetypeId}};
use super::{Fetch, Query}; use super::{Fetch, Query, DefaultQuery, AsQuery};
pub struct EntitiesFetch<'a> { pub struct EntitiesFetch<'a> {
entities: &'a [Entity], entities: &'a [Entity],
@ -37,4 +37,14 @@ impl Query for Entities {
entities: &archetype.entities, entities: &archetype.entities,
} }
} }
} }
/* impl AsQuery for Entities {
type Query = Entities;
}
impl DefaultQuery for Entities {
fn default_query() -> Self {
Entities
}
} */

View File

@ -111,27 +111,26 @@ pub trait Query {
unsafe fn fetch<'a>(&self, arch_id: ArchetypeId, archetype: &'a Archetype) -> Self::Fetch<'a>; unsafe fn fetch<'a>(&self, arch_id: ArchetypeId, archetype: &'a Archetype) -> Self::Fetch<'a>;
} }
/// A trait for getting the query of a type.
pub trait AsQuery {
/// The query for this type
type Query: Query;
}
pub trait IntoQuery {
fn into_query(self) -> Self;
}
pub trait DefaultQuery: AsQuery {
fn default_query() -> Self::Query;
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{world::World, archetype::Archetype}; use crate::{world::World, archetype::Archetype, tests::Vec2};
use super::{View, Entities}; use super::{View, Entities};
#[derive(Clone, Copy, Debug, Default)]
struct Vec2 {
x: f32,
y: f32,
}
impl Vec2 {
pub fn new(x: f32, y: f32) -> Self {
Self {
x,
y,
}
}
}
#[test] #[test]
fn simple_view() { fn simple_view() {
let mut world = World::new(); let mut world = World::new();

16
lyra-ecs/src/tests.rs Normal file
View File

@ -0,0 +1,16 @@
/// This source file includes some common things that tests are using.
#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
pub struct Vec2 {
pub x: f32,
pub y: f32,
}
impl Vec2 {
pub fn new(x: f32, y: f32) -> Self {
Self {
x,
y,
}
}
}

View File

@ -1,7 +1,7 @@
use std::{collections::{HashMap, VecDeque}, any::{Any, TypeId}}; use std::{collections::{HashMap, VecDeque}, any::{Any, TypeId}};
use std::slice::Iter; use std::slice::Iter;
use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, component::Component, query::QuerySimple}; use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, component::Component, query::{QuerySimple, ViewIter, IntoQuery, View, AsQuery, DefaultQuery}};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct EntityId(pub u64); pub struct EntityId(pub u64);
@ -109,11 +109,10 @@ impl World {
archetype.get_entity_component(record.index) archetype.get_entity_component(record.index)
} }
pub fn query<T: Component>(&self) -> impl Iterator<Item = &T> { pub fn view<'a, T: 'static + Component + DefaultQuery>(&'a self) -> ViewIter<'a, T::Query> {
self.archetypes let archetypes = self.archetypes.values().collect();
.iter() let v = View::new(T::default_query(), archetypes);
.filter_map(|(_, a)| a.get_component_column::<T>()) v.into_iter()
.flatten()
} }
pub fn query_better(&self) -> QuerySimple { pub fn query_better(&self) -> QuerySimple {
@ -131,12 +130,9 @@ impl World {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::World; use crate::tests::Vec2;
struct Vec2 { use super::World;
x: f32,
y: f32,
}
#[test] #[test]
fn spawning_entity() { fn spawning_entity() {
@ -146,4 +142,28 @@ mod tests {
y: 15.0, y: 15.0,
}, )); }, ));
} }
#[test]
fn query_entities() {
let mut world = World::new();
world.spawn((Vec2 {
x: 10.0,
y: 15.0,
}, ));
world.spawn((Vec2 {
x: 152.0,
y: 3585.0,
}, ));
world.spawn((Vec2 {
x: 235.0,
y: 734.0,
}, ));
let mut count = 0;
for pos in world.view::<&Vec2>() {
println!("Found entity at {:?}", pos);
count += 1;
}
assert!(count == 3);
}
} }