ecs: impl Clone for World and return entity in dynamic views

This commit is contained in:
SeanOMik 2024-04-27 00:21:26 -04:00
parent 6a11f7cbb7
commit f0d36e7b56
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
5 changed files with 26 additions and 14 deletions

View File

@ -21,6 +21,7 @@ impl Entity {
} }
} }
#[derive(Clone)]
pub struct Entities { pub struct Entities {
pub(crate) arch_index: HashMap<EntityId, Record>, pub(crate) arch_index: HashMap<EntityId, Record>,
dead: VecDeque<Entity>, dead: VecDeque<Entity>,

View File

@ -1,6 +1,6 @@
use std::ops::Range; use std::ops::Range;
use crate::{query::Fetch, Archetype, ArchetypeEntityId, ArchetypeId, World}; use crate::{query::Fetch, Archetype, ArchetypeEntityId, ArchetypeId, Entity, World};
use super::{DynamicType, FetchDynamicTypeUnsafe, QueryDynamicType}; use super::{DynamicType, FetchDynamicTypeUnsafe, QueryDynamicType};
@ -38,6 +38,11 @@ impl DynamicViewState {
} }
} }
pub struct DynamicViewItem {
pub row: Vec<DynamicType>,
pub entity: Entity,
}
/// A view iterator on dynamic types. /// A view iterator on dynamic types.
/// ///
/// You will likely want to use [`DynamicViewIter`] unless you need to store the iterator /// You will likely want to use [`DynamicViewIter`] unless you need to store the iterator
@ -52,7 +57,7 @@ pub struct DynamicViewStateIter {
} }
impl DynamicViewStateIter { impl DynamicViewStateIter {
pub fn next(&mut self, world: &World) -> Option<Vec<DynamicType>> { pub fn next(&mut self, world: &World) -> Option<DynamicViewItem> {
let archetypes = world.archetypes.values().collect::<Vec<_>>(); let archetypes = world.archetypes.values().collect::<Vec<_>>();
loop { loop {
@ -73,7 +78,11 @@ impl DynamicViewStateIter {
continue; continue;
} }
return Some(fetch_res); let arch = archetypes.get(self.next_archetype-1).unwrap();
return Some(DynamicViewItem {
row: fetch_res,
entity: arch.entity_at_index(ArchetypeEntityId(entity_index)).unwrap()
})
} else { } else {
if self.next_archetype >= archetypes.len() { if self.next_archetype >= archetypes.len() {
return None; // ran out of archetypes to go through return None; // ran out of archetypes to go through
@ -129,7 +138,7 @@ impl<'a> DynamicView<'a> {
/// This works great for a embedding with a scripting language (*cough* *cough* WASM) since /// This works great for a embedding with a scripting language (*cough* *cough* WASM) since
/// Rust doesn't actually need to know the types of what its iterating over. /// Rust doesn't actually need to know the types of what its iterating over.
impl<'a> IntoIterator for DynamicView<'a> { impl<'a> IntoIterator for DynamicView<'a> {
type Item = Vec<DynamicType>; type Item = DynamicViewItem;
type IntoIter = DynamicViewIter<'a>; type IntoIter = DynamicViewIter<'a>;
@ -151,7 +160,7 @@ pub struct DynamicViewIter<'a> {
} }
impl<'a> Iterator for DynamicViewIter<'a> { impl<'a> Iterator for DynamicViewIter<'a> {
type Item = Vec<DynamicType>; type Item = DynamicViewItem;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
self.inner.next(&self.world) self.inner.next(&self.world)
@ -185,9 +194,9 @@ mod tests {
let mut view_iter = view.into_iter(); let mut view_iter = view.into_iter();
while let Some(view_row) = view_iter.next(&world) { while let Some(view_row) = view_iter.next(&world) {
assert_eq!(view_row.len(), 1); assert_eq!(view_row.row.len(), 1);
let mut row_iter = view_row.iter(); let mut row_iter = view_row.row.iter();
let dynamic_type = row_iter.next().unwrap(); let dynamic_type = row_iter.next().unwrap();
@ -214,9 +223,9 @@ mod tests {
view.push(query); view.push(query);
for view_row in view.into_iter() { for view_row in view.into_iter() {
assert_eq!(view_row.len(), 1); assert_eq!(view_row.row.len(), 1);
let mut row_iter = view_row.iter(); let mut row_iter = view_row.row.iter();
let dynamic_type = row_iter.next().unwrap(); let dynamic_type = row_iter.next().unwrap();

View File

@ -81,7 +81,7 @@ impl<R: ResourceObject> AsQuery for QueryResource<R> {
} }
/// A struct used for querying resources from the World. /// A struct used for querying resources from the World.
pub struct Res<'a, T>(pub(crate) AtomicRef<'a, T>); pub struct Res<'a, T: ResourceObject>(pub(crate) AtomicRef<'a, T>);
impl<'a, T: ResourceObject> std::ops::Deref for Res<'a, T> { impl<'a, T: ResourceObject> std::ops::Deref for Res<'a, T> {
type Target = T; type Target = T;
@ -169,7 +169,7 @@ impl<R: ResourceObject> AsQuery for QueryResourceMut<R> {
} }
/// A struct used for querying resources from the World. /// A struct used for querying resources from the World.
pub struct ResMut<'a, T>(pub(crate) AtomicRefMut<'a, T>); pub struct ResMut<'a, T: ResourceObject>(pub(crate) AtomicRefMut<'a, T>);
impl<'a, T: ResourceObject> std::ops::Deref for ResMut<'a, T> { impl<'a, T: ResourceObject> std::ops::Deref for ResMut<'a, T> {
type Target = T; type Target = T;

View File

@ -1,4 +1,4 @@
use std::any::{TypeId, Any}; use std::{any::{Any, TypeId}, sync::Arc};
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
@ -19,8 +19,9 @@ impl<T: Send + Sync + Any> ResourceObject for T {
} }
/// A type erased storage for a Resource. /// A type erased storage for a Resource.
#[derive(Clone)]
pub struct ResourceData { pub struct ResourceData {
pub(crate) data: Box<AtomicRefCell<dyn ResourceObject>>, pub(crate) data: Arc<AtomicRefCell<dyn ResourceObject>>,
type_id: TypeId, type_id: TypeId,
} }
@ -28,7 +29,7 @@ impl ResourceData {
pub fn new<T: ResourceObject>(data: T) -> Self { pub fn new<T: ResourceObject>(data: T) -> Self {
Self { Self {
data: Box::new(AtomicRefCell::new(data)), data: Arc::new(AtomicRefCell::new(data)),
type_id: TypeId::of::<T>(), type_id: TypeId::of::<T>(),
} }
} }

View File

@ -16,6 +16,7 @@ pub struct Record {
pub index: ArchetypeEntityId, pub index: ArchetypeEntityId,
} }
#[derive(Clone)]
pub struct World { pub struct World {
pub(crate) archetypes: HashMap<ArchetypeId, Archetype>, pub(crate) archetypes: HashMap<ArchetypeId, Archetype>,
next_archetype_id: ArchetypeId, next_archetype_id: ArchetypeId,