diff --git a/lyra-ecs/src/entity.rs b/lyra-ecs/src/entity.rs index d7afd20..370af54 100644 --- a/lyra-ecs/src/entity.rs +++ b/lyra-ecs/src/entity.rs @@ -21,6 +21,7 @@ impl Entity { } } +#[derive(Clone)] pub struct Entities { pub(crate) arch_index: HashMap, dead: VecDeque, diff --git a/lyra-ecs/src/query/dynamic/view.rs b/lyra-ecs/src/query/dynamic/view.rs index 7dba417..7d50f18 100644 --- a/lyra-ecs/src/query/dynamic/view.rs +++ b/lyra-ecs/src/query/dynamic/view.rs @@ -1,6 +1,6 @@ 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}; @@ -38,6 +38,11 @@ impl DynamicViewState { } } +pub struct DynamicViewItem { + pub row: Vec, + pub entity: Entity, +} + /// A view iterator on dynamic types. /// /// You will likely want to use [`DynamicViewIter`] unless you need to store the iterator @@ -52,7 +57,7 @@ pub struct DynamicViewStateIter { } impl DynamicViewStateIter { - pub fn next(&mut self, world: &World) -> Option> { + pub fn next(&mut self, world: &World) -> Option { let archetypes = world.archetypes.values().collect::>(); loop { @@ -73,7 +78,11 @@ impl DynamicViewStateIter { 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 { if self.next_archetype >= archetypes.len() { 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 /// Rust doesn't actually need to know the types of what its iterating over. impl<'a> IntoIterator for DynamicView<'a> { - type Item = Vec; + type Item = DynamicViewItem; type IntoIter = DynamicViewIter<'a>; @@ -151,7 +160,7 @@ pub struct DynamicViewIter<'a> { } impl<'a> Iterator for DynamicViewIter<'a> { - type Item = Vec; + type Item = DynamicViewItem; fn next(&mut self) -> Option { self.inner.next(&self.world) @@ -185,9 +194,9 @@ mod tests { let mut view_iter = view.into_iter(); 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(); @@ -214,9 +223,9 @@ mod tests { view.push(query); 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(); diff --git a/lyra-ecs/src/query/resource.rs b/lyra-ecs/src/query/resource.rs index 4920e70..8f60742 100644 --- a/lyra-ecs/src/query/resource.rs +++ b/lyra-ecs/src/query/resource.rs @@ -81,7 +81,7 @@ impl AsQuery for QueryResource { } /// 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> { type Target = T; @@ -169,7 +169,7 @@ impl AsQuery for QueryResourceMut { } /// 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> { type Target = T; diff --git a/lyra-ecs/src/resource.rs b/lyra-ecs/src/resource.rs index 3fc6508..187f2a9 100644 --- a/lyra-ecs/src/resource.rs +++ b/lyra-ecs/src/resource.rs @@ -1,4 +1,4 @@ -use std::any::{TypeId, Any}; +use std::{any::{Any, TypeId}, sync::Arc}; use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; @@ -19,8 +19,9 @@ impl ResourceObject for T { } /// A type erased storage for a Resource. +#[derive(Clone)] pub struct ResourceData { - pub(crate) data: Box>, + pub(crate) data: Arc>, type_id: TypeId, } @@ -28,7 +29,7 @@ impl ResourceData { pub fn new(data: T) -> Self { Self { - data: Box::new(AtomicRefCell::new(data)), + data: Arc::new(AtomicRefCell::new(data)), type_id: TypeId::of::(), } } diff --git a/lyra-ecs/src/world.rs b/lyra-ecs/src/world.rs index 47baab5..4d49f69 100644 --- a/lyra-ecs/src/world.rs +++ b/lyra-ecs/src/world.rs @@ -16,6 +16,7 @@ pub struct Record { pub index: ArchetypeEntityId, } +#[derive(Clone)] pub struct World { pub(crate) archetypes: HashMap, next_archetype_id: ArchetypeId,