summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ecs/src/archetype.rs27
-rw-r--r--ecs/src/component/storage.rs39
-rw-r--r--ecs/src/lib.rs2
3 files changed, 38 insertions, 30 deletions
diff --git a/ecs/src/archetype.rs b/ecs/src/archetype.rs
new file mode 100644
index 0000000..a33de66
--- /dev/null
+++ b/ecs/src/archetype.rs
@@ -0,0 +1,27 @@
+use std::hash::{DefaultHasher, Hash, Hasher};
+
+use crate::component::Id as ComponentId;
+
+/// Archetype ID.
+#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Id
+{
+ hash: u64,
+}
+
+impl Id
+{
+ /// Returns the ID of a archetype with the given components.
+ pub fn new(component_ids: impl IntoIterator<Item = ComponentId>) -> Self
+ {
+ let mut hasher = DefaultHasher::new();
+
+ for component_id in component_ids {
+ component_id.hash(&mut hasher);
+ }
+
+ let hash = hasher.finish();
+
+ Self { hash }
+ }
+}
diff --git a/ecs/src/component/storage.rs b/ecs/src/component/storage.rs
index cff50cf..1db9227 100644
--- a/ecs/src/component/storage.rs
+++ b/ecs/src/component/storage.rs
@@ -1,8 +1,8 @@
use std::any::type_name;
use std::collections::{HashMap, HashSet};
-use std::hash::{DefaultHasher, Hash, Hasher};
use std::slice::Iter as SliceIter;
+use crate::archetype::Id as ArchetypeId;
use crate::component::{Component, Id as ComponentId, IsOptional as ComponentIsOptional};
use crate::lock::Lock;
use crate::type_name::TypeName;
@@ -12,7 +12,7 @@ use crate::EntityComponent;
pub struct Storage
{
archetypes: Vec<Archetype>,
- archetype_lookup: HashMap<ArchetypeComponentsHash, Vec<usize>>,
+ archetype_lookup: HashMap<ArchetypeId, Vec<usize>>,
pending_archetype_lookup_entries: Vec<Vec<ComponentId>>,
}
@@ -34,7 +34,7 @@ impl Storage
});
self.archetype_lookup
- .get(&ArchetypeComponentsHash::new(ids))
+ .get(&ArchetypeId::new(ids))
.map_or_else(ArchetypeRefIter::new_empty, |archetypes_indices| {
ArchetypeRefIter {
inner: archetypes_indices.iter(),
@@ -58,7 +58,7 @@ impl Storage
let archetype_indices = self
.archetype_lookup
- .entry(ArchetypeComponentsHash::new(
+ .entry(ArchetypeId::new(
components
.iter()
.filter(|component| !component.is_optional())
@@ -131,7 +131,7 @@ impl Storage
let archetype_indices = self
.archetype_lookup
- .entry(ArchetypeComponentsHash::new(pending_entry.into_iter()))
+ .entry(ArchetypeId::new(pending_entry.into_iter()))
.or_default();
archetype_indices.extend(matching_archetype_indices);
@@ -185,28 +185,6 @@ impl<'component_storage> Iterator for ArchetypeRefIter<'component_storage>
}
}
-#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
-struct ArchetypeComponentsHash
-{
- hash: u64,
-}
-
-impl ArchetypeComponentsHash
-{
- fn new(component_ids: impl IntoIterator<Item = ComponentId>) -> Self
- {
- let mut hasher = DefaultHasher::new();
-
- for component_id in component_ids {
- component_id.hash(&mut hasher);
- }
-
- let hash = hasher.finish();
-
- Self { hash }
- }
-}
-
#[cfg(test)]
mod tests
{
@@ -214,7 +192,8 @@ mod tests
use ecs_macros::Component;
- use super::{Archetype, ArchetypeComponentsHash, Storage};
+ use super::{Archetype, Storage};
+ use crate::archetype::Id as ArchetypeId;
use crate::component::Id as ComponentId;
use crate::lock::Lock;
use crate::{self as ecs, EntityComponent};
@@ -279,7 +258,7 @@ mod tests
let lookup = component_storage
.archetype_lookup
- .get(&ArchetypeComponentsHash::new([
+ .get(&ArchetypeId::new([
ComponentId::of::<HealthPotion>(),
ComponentId::of::<Hookshot>(),
]))
@@ -366,7 +345,7 @@ mod tests
let archetypes = component_storage
.archetype_lookup
- .get(&ArchetypeComponentsHash::new([
+ .get(&ArchetypeId::new([
ComponentId::of::<IronBoots>(),
ComponentId::of::<Hookshot>(),
]))
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index a33d72e..95519c9 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -31,6 +31,8 @@ pub mod system;
pub mod tuple;
pub mod type_name;
+mod archetype;
+
pub use ecs_macros::{Component, Sole};
pub use crate::query::Query;