summaryrefslogtreecommitdiff
path: root/ecs/src/component/storage.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-06-06 12:50:05 +0200
committerHampusM <hampus@hampusmat.com>2024-06-06 12:50:20 +0200
commitcb1ff29c8c7fa77bbb4e532eaa7e45df717a58ef (patch)
tree44cbc9c821609dc117b26369c3872386ab533f55 /ecs/src/component/storage.rs
parent43079a8dc9e2b608f47c5919f45c1f1661f11a2e (diff)
refactor(ecs): move ComponentStorage to it's own module
Diffstat (limited to 'ecs/src/component/storage.rs')
-rw-r--r--ecs/src/component/storage.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/ecs/src/component/storage.rs b/ecs/src/component/storage.rs
new file mode 100644
index 0000000..cdff09e
--- /dev/null
+++ b/ecs/src/component/storage.rs
@@ -0,0 +1,81 @@
+use std::any::{type_name, TypeId};
+use std::collections::HashSet;
+
+use crate::component::{Component, IsOptional as ComponentIsOptional};
+use crate::lock::Lock;
+use crate::type_name::TypeName;
+use crate::EntityComponent;
+
+#[derive(Debug, Default)]
+pub struct ComponentStorage
+{
+ entities: Vec<Entity>,
+}
+
+impl ComponentStorage
+{
+ pub fn find_entity_with_components(
+ &self,
+ start_index: usize,
+ component_type_ids: &[(TypeId, ComponentIsOptional)],
+ ) -> Option<(usize, &[EntityComponent])>
+ {
+ // 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()
+ .filter(|(_, is_optional)| *is_optional == ComponentIsOptional::No)
+ .all(|(component_type_id, _)| {
+ entity_components.contains(component_type_id)
+ })
+ {
+ return true;
+ }
+
+ false
+ })
+ .map(|(index, entity)| (index, &*entity.components))
+ }
+
+ pub fn push_entity(
+ &mut self,
+ components: impl IntoIterator<Item = Box<dyn Component>>,
+ )
+ {
+ self.entities.push(Entity {
+ components: components
+ .into_iter()
+ .map(|component| EntityComponent {
+ id: (*component).type_id(),
+ name: component.type_name(),
+ component: Lock::new(component),
+ })
+ .collect(),
+ });
+ }
+}
+
+impl TypeName for ComponentStorage
+{
+ fn type_name(&self) -> &'static str
+ {
+ type_name::<Self>()
+ }
+}
+
+#[derive(Debug, Default)]
+struct Entity
+{
+ components: Vec<EntityComponent>,
+}