Implement query for tuples of query types

This commit is contained in:
SeanOMik 2023-11-26 00:56:30 -05:00
parent 2e53156b0d
commit 2c718231ed
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
10 changed files with 260 additions and 251 deletions

View File

@ -1,6 +1,6 @@
use std::{any::{Any, TypeId, type_name}, ptr::{NonNull, self}, alloc::{self, Layout, alloc}, mem::size_of};
use std::{any::TypeId, ptr::{NonNull, self}, alloc::{self, Layout, alloc}};
use crate::{world::{Entity, ArchetypeEntityId}, bundle::Bundle, component::Component, component_info::ComponentInfo};
use crate::{world::{Entity, ArchetypeEntityId}, bundle::Bundle, component_info::ComponentInfo};
pub struct ComponentColumn {
pub data: NonNull<u8>,
@ -9,6 +9,7 @@ pub struct ComponentColumn {
pub entry_size: usize,
}
#[allow(dead_code)]
impl ComponentColumn {
/// Creates an invalid component column. Do not attempt to use it.
pub unsafe fn dangling() -> Self {
@ -45,19 +46,6 @@ impl ComponentColumn {
}
}
/// Creates an empty column of the same type
pub unsafe fn create_empty(&self, capacity: usize) -> Self {
let data = ComponentColumn::alloc(self.info.layout, capacity);
let size = self.info.layout.size();
Self {
data,
capacity,
info: self.info.clone(),
entry_size: size,
}
}
/// Set a component from pointer at an entity index.
///
/// # Safety
@ -117,46 +105,6 @@ pub struct Archetype {
const DEFAULT_CAPACITY: usize = 32;
impl Archetype {
/// Create a new archetype from another archetype and add a column
pub fn new_archetype_add<T: Component>(new_id: ArchetypeId, archetype: &Archetype) -> Archetype {
let mut columns: Vec<_> = archetype
.columns
.iter()
.map(|c| unsafe { c.create_empty(DEFAULT_CAPACITY) })
.collect();
// Make sure a column for the new component does not exist
assert_ne!(true, columns.iter().any(|c| c.info.type_id == TypeId::of::<T>()) );
columns.push(unsafe { ComponentColumn::new(ComponentInfo::new::<T>(), DEFAULT_CAPACITY) });
Archetype {
id: new_id,
entities: Vec::new(),
columns,
}
}
/// Create a new archetype from another archetype and remove a column
pub fn new_archetype_remove<T: Component>(new_id: ArchetypeId, archetype: &Archetype) -> Archetype {
let mut columns: Vec<_> = archetype
.columns
.iter()
.map(|c| unsafe { c.create_empty(DEFAULT_CAPACITY) })
.collect();
let idx = columns
.iter()
.position(|column| column.info.type_id == TypeId::of::<T>())
.unwrap();
columns.remove(idx);
Archetype {
id: new_id,
entities: Vec::new(),
columns,
}
}
pub fn from_bundle_info(new_id: ArchetypeId, bundle_info: Vec<ComponentInfo>) -> Archetype {
let columns = bundle_info.into_iter().map(|i| {
unsafe { ComponentColumn::new(i, DEFAULT_CAPACITY) }
@ -169,21 +117,6 @@ impl Archetype {
}
}
pub fn get_component_mut<T: Component>(&mut self, entity: ArchetypeEntityId) -> Option<&mut T> {
todo!()
}
pub fn get_entity_component<T: Component>(&self, entity: ArchetypeEntityId) -> Option<&T> {
let type_id = TypeId::of::<T>();
self.columns.iter().find(|c| c.info.type_id == type_id)
.map(|c| unsafe { c.get(entity.0 as usize) })
}
pub fn get_component_column<T: Component>(&self) -> Option<&Vec<T>> {
todo!()
}
/// Add an entity and its component bundle to the Archetype
///
/// # Safety:
@ -196,7 +129,7 @@ impl Archetype {
let entity_index = self.entities.len();
self.entities.push(entity);
bundle.takefn(|data, type_id, size| {
bundle.take(|data, type_id, _size| {
let col = self.columns.iter_mut().find(|c| c.info.type_id == type_id).unwrap();
unsafe { col.set_at(entity_index, data); }
});
@ -204,7 +137,7 @@ impl Archetype {
ArchetypeEntityId(entity_index as u64)
}
/// returns a boolean indicating whether this archetype can store the TypeIds given
/// Returns a boolean indicating whether this archetype can store the TypeIds given
pub(crate) fn is_archetype_for(&self, types: Vec<TypeId>) -> bool {
self.columns.iter().all(|c| types.contains(&c.info.type_id))
}

View File

@ -1,27 +1,22 @@
use std::{any::{TypeId, Any}, cell::Ref, ptr::NonNull, mem::size_of};
use std::{any::{TypeId, Any}, ptr::NonNull, mem::size_of};
use crate::{archetype::{ComponentColumn, Archetype}, component::Component, component_info::ComponentInfo};
use crate::{component::Component, component_info::ComponentInfo};
pub trait Bundle {
// Get a list of type ids that this bundle is storing
fn types(&self) -> Vec<TypeId>;
/// Take components into a list.
/// The return value could be seen as a list of a list of components, but that inner list
/// only contains a single value to make it easier to add it to an archetype.
//fn take_components(self) -> Vec<Box<dyn ComponentColumn>>;
//fn from_component_columns(columns: Vec<&Box<dyn ComponentColumn>>) -> Self;
//fn from_archetype(archetype: &Archetype) -> Self;
/// Get a list of type ids that this bundle is storing
fn type_ids(&self) -> Vec<TypeId>;
/// Get ComponentInfo's for the components in this bundle
fn info(&self) -> Vec<ComponentInfo>;
/// Take the bundle by calling the closure with pointers to each component, its type and size.
/// The closure is expected to take ownership of the pointer.
fn takefn(self, cb: impl FnMut(NonNull<u8>, TypeId, usize));
fn take(self, f: impl FnMut(NonNull<u8>, TypeId, usize));
}
// The macro below can implement this for us, but this is here for development
impl<C1: Component> Bundle for (C1,) {
fn types(&self) -> Vec<TypeId> {
fn type_ids(&self) -> Vec<TypeId> {
vec![self.0.type_id()]
}
@ -29,51 +24,50 @@ impl<C1: Component> Bundle for (C1,) {
vec![ComponentInfo::new::<C1>()]
}
fn takefn(self, mut cb: impl FnMut(NonNull<u8>, TypeId, usize)) {
fn take(self, mut f: impl FnMut(NonNull<u8>, TypeId, usize)) {
let (c1, ) = self;
cb(NonNull::from(&c1).cast(), TypeId::of::<C1>(), size_of::<C1>());
f(NonNull::from(&c1).cast(), TypeId::of::<C1>(), size_of::<C1>());
}
}
/* macro_rules! impl_bundle_tuple {
( $(($name: ident, $index: tt))+ ) => (
macro_rules! impl_bundle_tuple {
( $($name: ident),+ ) => (
#[allow(non_snake_case)]
impl<$($name: Component),+> Bundle for ($($name,)+) {
fn types(&self) -> Vec<TypeId> {
vec![$(self.$index.type_id()),+]
fn type_ids(&self) -> Vec<TypeId> {
// these names wont follow rust convention, but its a macro so deal with it
let ($($name),+) = self;
vec![$($name.type_id()),+]
}
fn take_components(self) -> Vec<Box<dyn ComponentColumn>> {
vec![$(Box::new(vec![self.$index])),+]
fn info(&self) -> Vec<ComponentInfo> {
vec![$(ComponentInfo::new::<$name>()),+]
}
fn from_component_columns(columns: Vec<&Box<dyn ComponentColumn>>) -> Self {
let mut chains = Vec::new();
fn take(self, mut f: impl FnMut(NonNull<u8>, TypeId, usize)) {
// these names wont follow rust convention, but its a macro so deal with it
let ($($name),+) = self;
for col in columns.iter() {
col.
}
todo!()
$(f(NonNull::from(&$name).cast(), TypeId::of::<$name>(), size_of::<$name>());)+
}
}
);
} */
}
// hopefully 16 components in a bundle is enough
//impl_bundle_tuple! { (C1, 0) }
/* impl_bundle_tuple! { (C1, 0) (C2, 1) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) (C8, 7) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) (C8, 7) (C9, 8) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) (C8, 7) (C9, 8) (C10, 9) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) (C8, 7) (C9, 8) (C10, 9) (C11, 10) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) (C8, 7) (C9, 8) (C10, 9) (C11, 10) (C12, 11) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) (C8, 7) (C9, 8) (C10, 9) (C11, 10) (C12, 11) (C13, 12) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) (C8, 7) (C9, 8) (C10, 9) (C11, 10) (C12, 11) (C13, 12) (C14, 13) }
impl_bundle_tuple! { (C1, 0) (C2, 1) (C3, 2) (C4, 3) (C5, 4) (C6, 5) (C7, 6) (C8, 7) (C9, 8) (C10, 9) (C11, 10) (C12, 11) (C13, 12) (C14, 13) (C15, 14) }
*/
impl_bundle_tuple! { C1, C2 }
impl_bundle_tuple! { C1, C2, C3 }
impl_bundle_tuple! { C1, C2, C3, C4 }
impl_bundle_tuple! { C1, C2, C3, C4, C5 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 }
impl_bundle_tuple! { C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16 }

View File

@ -16,25 +16,7 @@ pub struct Position2d(i32, i32);
fn main() {
let mut world = World::new();
let pos = Position2d(50, 50);
let e = world.spawn((pos,));
if let Some(pos) = world.get_component::<Position2d>(e) {
println!("Got Position2d: {:?}", pos);
} else {
println!("no component found :(");
}
let pos = Position2d(836, 348);
let _e = world.spawn((pos,));
println!("\nstart of querying!\n");
let mut q = world.query_better();
q.with_component::<Position2d>();
for pos in q.run::<Position2d>() {
println!("Queried Position2d: {:?}", pos);
}
}

View File

@ -1,8 +1,6 @@
use std::{marker::PhantomData, any::TypeId, ptr::NonNull};
use crate::component::Component;
use super::{Fetch, Query, AsQuery, IntoQuery, DefaultQuery};
use super::{Fetch, Query, AsQuery, DefaultQuery};
pub struct FetchBorrow<'a, T> {
ptr: NonNull<u8>,
@ -16,7 +14,7 @@ where
{
type Item = &'a T;
fn create_empty() -> Self {
fn dangling() -> Self {
FetchBorrow {
ptr: NonNull::dangling(),
size: 0,
@ -103,7 +101,7 @@ where
{
type Item = &'a mut T;
fn create_empty() -> Self {
fn dangling() -> Self {
FetchBorrowMut {
ptr: NonNull::dangling(),
size: 0,

View File

@ -1,6 +1,6 @@
use crate::{world::Entity, archetype::{Archetype, ArchetypeId}};
use super::{Fetch, Query, DefaultQuery, AsQuery};
use super::{Fetch, Query};
pub struct EntitiesFetch<'a> {
entities: &'a [Entity],
@ -14,7 +14,7 @@ impl<'a> Fetch<'a> for EntitiesFetch<'a> {
e
}
fn create_empty() -> Self {
fn dangling() -> Self {
Self {
entities: &[],
}
@ -29,22 +29,14 @@ impl Query for Entities {
type Fetch<'a> = EntitiesFetch<'a>;
fn can_visit_archetype(&self, archetype: &Archetype) -> bool {
let _ = archetype; // ignore unused warnings
true
}
unsafe fn fetch<'a>(&self, arch_id: ArchetypeId, archetype: &'a Archetype) -> Self::Fetch<'a> {
let _ = arch_id; // ignore unused warnings
EntitiesFetch {
entities: &archetype.entities,
}
}
}
/* impl AsQuery for Entities {
type Query = Entities;
}
impl DefaultQuery for Entities {
fn default_query() -> Self {
Entities
}
} */
}

View File

@ -1,85 +1,19 @@
use std::{any::{TypeId, Any}, cell::RefCell, rc::Rc, collections::{HashMap, VecDeque}, io::Read, slice::Iter, ops::Range};
use crate::{archetype::{Archetype, ComponentColumn, ArchetypeId}, bundle::Bundle, component::Component, world::{Record, EntityId, ArchetypeEntityId}};
use crate::{archetype::{Archetype, ArchetypeId}, world::ArchetypeEntityId};
pub mod view;
pub use view::*;
pub mod entities;
#[allow(unused_imports)]
pub use entities::*;
pub mod borrow;
#[allow(unused_imports)]
pub use borrow::*;
pub struct QuerySimple<'a> {
//entities: Iter<Entity
archetypes: Vec<&'a Archetype>,
type_ids: Vec<TypeId>,
}
impl<'a> QuerySimple<'a> {
pub fn new(archetypes: Vec<&'a Archetype>) -> Self {
Self {
archetypes,
type_ids: Vec::new(),
}
}
pub fn with_component<T: Any>(&mut self) {
let type_id = TypeId::of::<T>();
self.type_ids.push(type_id);
}
pub fn run<C1: Component>(&self) -> impl Iterator<Item = &C1>
{
//let mut columns = Vec::new();
/* for type_id in self.type_ids.iter() {
for arch in self.archetypes.iter() {
if let Some(col) = arch.columns
.iter().find(|c| c.component_type_id() == type_id.clone()) {
columns.push(col);
}
}
}
let mut entities: Vec<&C1> = columns.iter().map(|bx| bx.as_any().downcast_ref::<C1>()
.expect("Failure to downcast component column"))
.collect(); */
let entities = self.archetypes
.iter()
.filter_map(|a| a.get_component_column::<C1>())
.flatten();
/* let columns = self.type_ids
.iter()
.map(|type_id| {
let a = self.archetypes
.iter()
.filter_map(|arch| {
arch.columns
.iter()
.find(|c| c.component_type_id() == type_id.clone())
});
}); */
/* self.type_ids
.iter()
.map(|type_id| {
self.archetypes
.iter()
.map(|arch| {
arch.get_component_column_typeid(type_id.clone())
})
}); */
return entities;
}
}
pub mod tuple;
#[allow(unused_imports)]
pub use tuple::*;
/// A [`Fetch`]er implementation gets data out of an archetype.
pub trait Fetch<'a> {
@ -93,7 +27,7 @@ pub trait Fetch<'a> {
}
/// Creates an empty Fetch. DO NOT try to `get_item` on this
fn create_empty() -> Self;
fn dangling() -> Self;
unsafe fn get_item(&mut self, entity: ArchetypeEntityId) -> Self::Item;
}

179
lyra-ecs/src/query/tuple.rs Normal file
View File

@ -0,0 +1,179 @@
use super::{Query, Fetch, AsQuery, DefaultQuery};
// Technically all of these implementations for a 2-sized tuple
// can be implemented by the macro near the end of the file, but
// these are left here for development.
impl<'a, F1, F2> Fetch<'a> for (F1, F2)
where
F1: Fetch<'a>,
F2: Fetch<'a>,
{
type Item = (F1::Item, F2::Item);
fn dangling() -> Self {
(F1::dangling(), F2::dangling())
}
fn can_visit_item(&mut self, entity: crate::world::ArchetypeEntityId) -> bool {
let (f1, f2) = self;
f1.can_visit_item(entity) && f2.can_visit_item(entity)
}
unsafe fn get_item(&mut self, entity: crate::world::ArchetypeEntityId) -> Self::Item {
let (f1, f2) = self;
( f1.get_item(entity), f2.get_item(entity) )
}
}
impl<Q1, Q2> Query for (Q1, Q2)
where
Q1: Query,
Q2: Query,
{
type Item<'a> = (Q1::Item<'a>, Q2::Item<'a>);
type Fetch<'a> = (Q1::Fetch<'a>, Q2::Fetch<'a>);
fn can_visit_archetype(&self, archetype: &crate::archetype::Archetype) -> bool {
let (q1, q2) = self;
q1.can_visit_archetype(archetype) && q2.can_visit_archetype(archetype)
}
unsafe fn fetch<'a>(&self, arch_id: crate::archetype::ArchetypeId, archetype: &'a crate::archetype::Archetype) -> Self::Fetch<'a> {
let (q1, q2) = self;
( q1.fetch(arch_id, archetype), q2.fetch(arch_id, archetype) )
}
}
impl<Q1, Q2> AsQuery for (Q1, Q2)
where
Q1: AsQuery,
Q2: AsQuery,
{
type Query = (Q1::Query, Q2::Query);
}
impl<Q1, Q2> DefaultQuery for (Q1, Q2)
where
Q1: DefaultQuery,
Q2: DefaultQuery,
{
fn default_query() -> (Q1::Query, Q2::Query) {
( Q1::default_query(), Q2::default_query() )
}
}
macro_rules! impl_bundle_tuple {
( $($name: ident),+ ) => (
#[allow(non_snake_case)]
impl<'a, $($name: Fetch<'a>),+> Fetch<'a> for ($($name,)+) {
type Item = ($($name::Item,)+);
fn dangling() -> Self {
( $($name::dangling(),)+ )
}
fn can_visit_item(&mut self, entity: crate::world::ArchetypeEntityId) -> bool {
let ( $($name,)+ ) = self;
// this is the only way I could figure out how to do an 'and'
let bools = vec![$($name.can_visit_item(entity),)+];
bools.iter().all(|b| *b)
}
unsafe fn get_item(&mut self, entity: crate::world::ArchetypeEntityId) -> Self::Item {
let ( $($name,)+ ) = self;
( $($name.get_item(entity),)+ )
}
}
#[allow(non_snake_case)]
impl<$($name: Query),+> Query for ($($name,)+) {
type Item<'a> = ($($name::Item<'a>,)+);
type Fetch<'a> = ($($name::Fetch<'a>,)+);
fn can_visit_archetype(&self, archetype: &crate::archetype::Archetype) -> bool {
let ( $($name,)+ ) = self;
// this is the only way I could figure out how to do an 'and'
let bools = vec![$($name.can_visit_archetype(archetype),)+];
bools.iter().all(|b| *b)
}
unsafe fn fetch<'a>(&self, arch_id: crate::archetype::ArchetypeId, archetype: &'a crate::archetype::Archetype) -> Self::Fetch<'a> {
let ( $($name,)+ ) = self;
( $($name.fetch(arch_id, archetype),)+ )
}
}
impl<$($name: AsQuery),+> AsQuery for ($($name,)+) {
type Query = ($($name::Query,)+);
}
impl<$($name: DefaultQuery),+> DefaultQuery for ($($name,)+) {
fn default_query() -> ($($name::Query,)+) {
( $($name::default_query(),)+ )
}
}
);
}
// Hopefully up to 16 queries in a SINGLE view is enough
impl_bundle_tuple! { Q1, Q2, Q3 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 }
impl_bundle_tuple! { Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15, Q16 }
#[cfg(test)]
mod tests {
use crate::{world::World, tests::{Vec2, Vec3}};
#[test]
fn tuple_queries() {
let mut world = World::new();
let comps = &[
(
Vec2 {
x: 10.0,
y: 15.0,
},
Vec3 {
x: 83.0,
y: 38.0,
z: 98.0,
}
),
(
Vec2 {
x: 152.0,
y: 3585.0,
},
Vec3 {
x: 43.0,
y: 29.0,
z: 30.0,
}
),
];
world.spawn(comps[0]);
world.spawn(comps[1]);
for (pos2, pos3) in world.view::<(&Vec2, &Vec3)>() {
println!("Entity at {:?} and {:?}", pos2, pos3);
assert!(comps.contains(&( pos2.clone(), pos3.clone() )));
}
}
}

View File

@ -32,7 +32,7 @@ where
fn into_iter(self) -> Self::IntoIter {
ViewIter {
query: self.query,
fetcher: Q::Fetch::create_empty(),
fetcher: Q::Fetch::dangling(),
archetypes: self.archetypes,
next_archetype: 0,
component_indices: 0..0,

View File

@ -13,4 +13,21 @@ impl Vec2 {
y,
}
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
pub struct Vec3 {
pub x: f32,
pub y: f32,
pub z: f32,
}
impl Vec3 {
pub fn new(x: f32, y: f32, z: f32) -> Self {
Self {
x,
y,
z
}
}
}

View File

@ -1,7 +1,6 @@
use std::{collections::{HashMap, VecDeque}, any::{Any, TypeId}};
use std::slice::Iter;
use std::collections::{HashMap, VecDeque};
use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, component::Component, query::{QuerySimple, ViewIter, IntoQuery, View, AsQuery, DefaultQuery}};
use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, component::Component, query::{ViewIter, View, DefaultQuery}};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct EntityId(pub u64);
@ -60,7 +59,7 @@ impl World {
where
B: Bundle
{
let bundle_types = bundle.types();
let bundle_types = bundle.type_ids();
let new_entity = self.get_new_entity();
// try to find an archetype
@ -102,30 +101,11 @@ impl World {
new_entity
}
pub fn get_component<T: Component>(&self, entity: Entity) -> Option<&T> {
let record = self.entity_index.get(&entity.id)?;
let archetype = self.archetypes.get(&record.id)?;
archetype.get_entity_component(record.index)
}
pub fn view<'a, T: 'static + Component + DefaultQuery>(&'a self) -> ViewIter<'a, T::Query> {
let archetypes = self.archetypes.values().collect();
let v = View::new(T::default_query(), archetypes);
v.into_iter()
}
pub fn query_better(&self) -> QuerySimple {
let archetypes = self.archetypes.values().collect();
QuerySimple::new(archetypes)
}
/* pub fn query_m<B: Bundle>(&self) -> impl Iterator<Item = &T> {
self.archetypes
.iter()
.filter_map(|(_, a)| a.get_component_column::<T>())
.flatten()
} */
}
#[cfg(test)]
@ -144,7 +124,7 @@ mod tests {
}
#[test]
fn query_entities() {
fn world_view_entities() {
let mut world = World::new();
world.spawn((Vec2 {
x: 10.0,