summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-04-09 20:58:25 +0200
committerHampusM <hampus@hampusmat.com>2024-04-09 20:58:25 +0200
commitcb623e024ea8e9312c543efdc8ba243abeb32c2a (patch)
tree9de8e120add14522ae806be1ada777e6edfcf89d
parentc0fbe4b3790c771836b1723a81a2290d9796f429 (diff)
refactor(ecs): make entity finding a ComponentStorage method
-rw-r--r--ecs/src/lib.rs71
1 files changed, 41 insertions, 30 deletions
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index a2fc36e..9d79b91 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -6,7 +6,6 @@ use std::fmt::Debug;
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::ops::RangeBounds;
-use std::slice::Iter as SliceIter;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Weak};
use std::vec::Drain;
@@ -262,7 +261,8 @@ where
'this: 'world,
{
QueryComponentIter {
- entity_iter: self.component_storage.entities.iter(),
+ component_storage: &self.component_storage,
+ current_entity_index: 0,
component_type_ids: Comps::type_ids(),
comps_pd: PhantomData,
}
@@ -434,7 +434,8 @@ impl QueryComponentIds
pub struct QueryComponentIter<'world, Comps>
{
- entity_iter: SliceIter<'world, Entity>,
+ component_storage: &'world ComponentStorage,
+ current_entity_index: usize,
component_type_ids: Vec<TypeId>,
comps_pd: PhantomData<Comps>,
}
@@ -447,8 +448,13 @@ where
fn next(&mut self) -> Option<Self::Item>
{
- let matching_entity =
- find_entity_with_components(&mut self.entity_iter, &self.component_type_ids)?;
+ let (matching_entity_index, matching_entity) =
+ self.component_storage.find_entity_with_components(
+ self.current_entity_index,
+ &self.component_type_ids,
+ )?;
+
+ self.current_entity_index = matching_entity_index + 1;
Some(Comps::from_components(
matching_entity
@@ -459,37 +465,42 @@ where
}
}
-fn find_entity_with_components<'world>(
- entity_iter: &mut impl Iterator<Item = &'world Entity>,
- component_type_ids: &[TypeId],
-) -> Option<&'world Entity>
-{
- // TODO: This is a really dumb and slow way to do this. Refactor the world
- // to store components in archetypes
- entity_iter.find(|entity| {
- let entity_components = entity
- .components
- .iter()
- .map(|component| component.id)
- .collect::<HashSet<_>>();
-
- if component_type_ids
- .iter()
- .all(|component_type_id| entity_components.contains(component_type_id))
- {
- return true;
- }
-
- false
- })
-}
-
#[derive(Debug, Default)]
pub struct ComponentStorage
{
entities: Vec<Entity>,
}
+impl ComponentStorage
+{
+ fn find_entity_with_components(
+ &self,
+ start_index: usize,
+ component_type_ids: &[TypeId],
+ ) -> Option<(usize, &Entity)>
+ {
+ // TODO: This is a really dumb and slow way to do this. Refactor the world
+ // to store components in archetypes
+ self.entities.iter().enumerate().skip(start_index).find(
+ move |(_index, entity)| {
+ let entity_components = entity
+ .components
+ .iter()
+ .map(|component| component.id)
+ .collect::<HashSet<_>>();
+
+ if component_type_ids.iter().all(|component_type_id| {
+ entity_components.contains(component_type_id)
+ }) {
+ return true;
+ }
+
+ false
+ },
+ )
+ }
+}
+
impl TypeName for ComponentStorage
{
fn type_name(&self) -> &'static str