diff options
author | HampusM <hampus@hampusmat.com> | 2025-04-08 16:28:46 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2025-04-08 16:28:46 +0200 |
commit | e4818dd4f0a57a2c9af8859253f570607f64bb12 (patch) | |
tree | 981e6e927b086882ebc2eb9399ee41fe4755d887 | |
parent | 89036adeeec7de82203c819c77950a7728cfe7f9 (diff) |
refactor(ecs): store components as dyn Any
-rw-r--r-- | ecs/src/component.rs | 4 | ||||
-rw-r--r-- | ecs/src/component/storage.rs | 13 | ||||
-rw-r--r-- | ecs/src/component/storage/archetype.rs | 16 | ||||
-rw-r--r-- | ecs/src/lib.rs | 37 | ||||
-rw-r--r-- | ecs/src/system/stateful.rs | 2 |
5 files changed, 23 insertions, 49 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs index c01fd75..f4c29ae 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -220,7 +220,7 @@ pub struct Handle<'a, ComponentT: Component> impl<'a, ComponentT: Component> Handle<'a, ComponentT> { - pub(crate) fn new(inner: ReadGuard<'a, Box<dyn Component>>) -> Self + pub(crate) fn new(inner: ReadGuard<'a, Box<dyn Any>>) -> Self { Self { inner: inner.map(|component| { @@ -300,7 +300,7 @@ pub struct HandleMut<'a, ComponentT: Component> impl<'a, ComponentT: Component> HandleMut<'a, ComponentT> { - pub(crate) fn new(inner: WriteGuard<'a, Box<dyn Component>>) -> Self + pub(crate) fn new(inner: WriteGuard<'a, Box<dyn Any>>) -> Self { Self { inner: inner.map(|component| { diff --git a/ecs/src/component/storage.rs b/ecs/src/component/storage.rs index 14aa191..53f51f2 100644 --- a/ecs/src/component/storage.rs +++ b/ecs/src/component/storage.rs @@ -1,3 +1,4 @@ +use std::any::Any; use std::array::IntoIter as ArrayIter; use std::cell::RefCell; use std::vec::IntoIter as VecIntoIter; @@ -16,7 +17,6 @@ use crate::component::storage::graph::{ ArchetypeEdges, Graph, }; -use crate::component::Component; use crate::uid::{Kind as UidKind, Uid}; use crate::util::{BorrowedOrOwned, Either, StreamingIterator, VecExt}; @@ -159,18 +159,9 @@ impl Storage pub fn add_entity_component( &mut self, entity_uid: Uid, - (component_id, component_name, component): ( - Uid, - &'static str, - Box<dyn Component>, - ), + (component_id, component_name, component): (Uid, &'static str, Box<dyn Any>), ) -> Result<(), Error> { - debug_assert!( - !component.self_is_optional(), - "Adding a optional component to a entity is not supported" - ); - let Some(archetype_id) = self.entity_archetype_lookup.get(&entity_uid) else { return Err(Error::EntityDoesNotExist(entity_uid)); }; diff --git a/ecs/src/component/storage/archetype.rs b/ecs/src/component/storage/archetype.rs index 8d48e13..58facc9 100644 --- a/ecs/src/component/storage/archetype.rs +++ b/ecs/src/component/storage/archetype.rs @@ -1,9 +1,10 @@ +use std::any::Any; use std::hash::{DefaultHasher, Hash, Hasher}; use std::slice::Iter as SliceIter; use hashbrown::HashMap; -use crate::component::{Component, Metadata as ComponentMetadata}; +use crate::component::Metadata as ComponentMetadata; use crate::lock::Lock; use crate::uid::{Kind as UidKind, Uid}; use crate::util::HashMapExt; @@ -209,26 +210,19 @@ impl Entity #[derive(Debug)] pub struct EntityComponent { - name: &'static str, - component: Lock<Box<dyn Component>>, + component: Lock<Box<dyn Any>>, } impl EntityComponent { - pub fn new(component: Box<dyn Component>, component_name: &'static str) -> Self + pub fn new(component: Box<dyn Any>, component_name: &'static str) -> Self { Self { - name: component_name, component: Lock::new(component, component_name), } } - pub fn name(&self) -> &str - { - self.name - } - - pub fn component(&self) -> &Lock<Box<dyn Component>> + pub fn component(&self) -> &Lock<Box<dyn Any>> { &self.component } diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 3f0042c..ee33bd1 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -1,6 +1,6 @@ #![deny(clippy::all, clippy::pedantic)] -use std::any::{type_name, TypeId}; +use std::any::{type_name, Any, TypeId}; use std::cell::RefCell; use std::fmt::Debug; use std::mem::ManuallyDrop; @@ -14,7 +14,6 @@ use crate::component::storage::archetype::EntityComponent as ArchetypeEntityComp use crate::component::storage::Storage as ComponentStorage; use crate::component::{Component, Sequence as ComponentSequence}; use crate::entity::CREATE_STATIC_ENTITIES; -use crate::event::component::Kind as ComponentEventKind; use crate::extension::{Collector as ExtensionCollector, Extension}; use crate::lock::{Lock, WriteGuard}; use crate::phase::{Phase, START as START_PHASE}; @@ -466,7 +465,7 @@ impl World { let mut component_storage_lock = self.lock_component_storage_rw(); - let removed_entity = match component_storage_lock.remove_entity(entity_uid) { + let _removed_entity = match component_storage_lock.remove_entity(entity_uid) { Ok(components) => components, Err(err) => { tracing::error!("Failed to despawn entity: {err}"); @@ -474,32 +473,17 @@ impl World } }; - let component_removed_event_uids = removed_entity - .components() - .iter() - .map(|component| { - component - .component() - .read_nonblock() - .unwrap_or_else(|_| { - panic!( - "Failed to acquire read-only {} component lock", - component.name() - ) - }) - .get_event_uid(ComponentEventKind::Removed) - }) - .collect::<Vec<_>>(); - drop(component_storage_lock); if !*has_swapped_active_queue { self.swap_event_queue(has_swapped_active_queue); } - for comp_removed_event_id in component_removed_event_uids { - self.emit_event_by_id(comp_removed_event_id); - } + // TODO: Emit component removed events here + + // for comp_removed_event_id in component_removed_event_uids { + // self.emit_event_by_id(comp_removed_event_id); + // } } fn add_entity_components( @@ -509,6 +493,11 @@ impl World ) { for (component_id, component) in components { + debug_assert!( + !component.self_is_optional(), + "Adding a optional component to a entity is not supported" + ); + if let Err(err) = component_storage.add_entity_component( entity_uid, (component_id, component.name(), component), @@ -618,7 +607,7 @@ pub struct EntityComponentRef<'a> impl<'a> EntityComponentRef<'a> { - fn component(&self) -> &'a Lock<Box<dyn Component>> + fn component(&self) -> &'a Lock<Box<dyn Any>> { self.comp.component() } diff --git a/ecs/src/system/stateful.rs b/ecs/src/system/stateful.rs index 5415cc7..54f6979 100644 --- a/ecs/src/system/stateful.rs +++ b/ecs/src/system/stateful.rs @@ -25,7 +25,7 @@ use crate::World; pub struct Stateful<Func> { func: Func, - local_components: HashMap<Uid, Lock<Box<dyn Component>>>, + local_components: HashMap<Uid, Lock<Box<dyn Any>>>, } macro_rules! impl_system { |