diff options
Diffstat (limited to 'ecs/src/lib.rs')
| -rw-r--r-- | ecs/src/lib.rs | 692 | 
1 files changed, 332 insertions, 360 deletions
| diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 3adc415..f6fba64 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -1,36 +1,48 @@  #![deny(clippy::all, clippy::pedantic)] -use std::any::{type_name, TypeId}; -use std::cell::RefCell; +use std::any::{type_name, Any, TypeId};  use std::fmt::Debug;  use std::mem::ManuallyDrop; +use std::rc::Rc;  use std::sync::atomic::{AtomicBool, Ordering};  use std::sync::Arc;  use hashbrown::HashMap;  use crate::actions::Action; +use crate::component::storage::archetype::EntityComponent as ArchetypeEntityComponent;  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::component::{ +    Component, +    IntoParts as IntoComponentParts, +    Parts as ComponentParts, +    Sequence as ComponentSequence, +}; +use crate::entity::{Declaration as EntityDeclaration, Handle as EntityHandle}; +use crate::event::component::Added; +use crate::event::{Emitted as EmittedEvent, NewEvents, Submitter as EventSubmitter};  use crate::extension::{Collector as ExtensionCollector, Extension}; -use crate::lock::{Lock, WriteGuard}; -use crate::phase::{Phase, START as START_PHASE}; +use crate::lock::Lock; +use crate::pair::{ChildOf, DependsOn, Pair}; +use crate::phase::{ +    Phase, +    POST_UPDATE as POST_UPDATE_PHASE, +    PRE_UPDATE as PRE_UPDATE_PHASE, +    START as START_PHASE, +    UPDATE as UPDATE_PHASE, +};  use crate::query::flexible::Query as FlexibleQuery; -use crate::query::term::Without;  use crate::query::{ -    ComponentIter,      TermWithFieldTuple as QueryTermWithFieldTuple,      TermWithoutFieldTuple as QueryTermWithoutFieldTuple,      Terms as QueryTerms,      TermsBuilderInterface, +    MAX_TERM_CNT as QUERY_MAX_TERM_CNT,  }; -use crate::relationship::{ChildOf, DependsOn, Relationship}; -use crate::sole::Sole; +use crate::sole::{Single, Sole};  use crate::stats::Stats; -use crate::system::{System, SystemComponent}; -use crate::type_name::TypeName; +use crate::system::observer::{Observer, WrapperComponent as ObserverWrapperComponent}; +use crate::system::{Callbacks, Metadata as SystemMetadata, System, SystemComponent};  use crate::uid::{Kind as UidKind, Uid};  pub mod actions; @@ -38,20 +50,17 @@ pub mod component;  pub mod entity;  pub mod event;  pub mod extension; -pub mod lock; +pub mod pair;  pub mod phase;  pub mod query; -pub mod relationship;  pub mod sole;  pub mod stats;  pub mod system;  pub mod tuple; -pub mod type_name;  pub mod uid;  pub mod util; -#[doc(hidden)] -pub mod private; +mod lock;  pub use ecs_macros::{Component, Sole}; @@ -76,56 +85,49 @@ impl World              is_first_tick: AtomicBool::new(false),          }; -        world.add_sole(Stats::default()).ok(); +        crate::phase::spawn_entities(&mut world); -        for create_static_entity in CREATE_STATIC_ENTITIES { -            create_static_entity(&world); -        } +        world.add_sole(Stats::default()).ok();          world      } -    /// Creates a new entity with the given components. -    /// -    /// # Panics -    /// Will panic if mutable internal lock cannot be acquired. +    /// Creates a entity with the given components. A new unique [`Uid`] will be generated +    /// for this entity.      pub fn create_entity<Comps>(&mut self, components: Comps) -> Uid      where          Comps: ComponentSequence,      {          let entity_uid = Uid::new_unique(UidKind::Entity); -        self.create_entity_with_uid(components, entity_uid); +        self.create_entity_with_uid(entity_uid, components);          entity_uid      } +    /// Creates a entity with the given components. The entity will have the specified +    /// [`Uid`].      #[tracing::instrument(skip_all)] -    #[doc(hidden)] -    pub fn create_entity_with_uid<Comps>(&self, components: Comps, entity_uid: Uid) +    pub fn create_entity_with_uid<Comps>(&mut self, entity_uid: Uid, components: Comps)      where          Comps: ComponentSequence,      { -        debug_assert_eq!(entity_uid.kind(), UidKind::Entity); - -        { -            let mut component_storage_lock = self.lock_component_storage_rw(); - -            if let Err(err) = component_storage_lock.create_entity(entity_uid) { -                tracing::warn!("Failed to create entity: {err}"); -                return; -            }; +        self.create_ent(entity_uid, components.into_parts_array()); +    } -            Self::add_entity_components( -                entity_uid, -                components.into_array(), -                &mut component_storage_lock, -            ); -        } +    pub fn add_component(&mut self, entity_id: Uid, component_parts: ComponentParts) +    { +        Self::add_entity_components( +            entity_id, +            [component_parts], +            &mut self.data.component_storage, +            &EventSubmitter::new(&self.data.new_events), +        ); +    } -        for added_event_id in Comps::added_event_ids() { -            self.emit_event_by_id(added_event_id); -        } +    pub fn create_declared_entity(&mut self, entity_decl: &EntityDeclaration) +    { +        entity_decl.create(self);      }      /// Adds a globally shared singleton value. @@ -139,35 +141,48 @@ impl World          self.data.sole_storage.insert(sole)      } -    pub fn register_system<'this, SystemImpl>( +    pub fn register_observer<'this, SystemImpl, ObserverT>(          &'this mut self, -        phase_euid: Uid, -        system: impl System<'this, SystemImpl>, -    ) +        observer: ObserverT, +    ) where +        ObserverT: Observer<'this, SystemImpl>,      { -        self.create_entity(( -            SystemComponent { system: system.into_type_erased() }, -            Relationship::<DependsOn, Phase>::new(phase_euid), -        )); +        let (wrapper_comp, mut system_callbacks) = observer.finish_observer(); + +        let ent_id = Uid::new_unique(UidKind::Entity); + +        self.create_ent( +            ent_id, +            [wrapper_comp.into_parts()].into_iter().chain( +                ObserverT::observed_events() +                    .into_iter() +                    .map(IntoComponentParts::into_parts), +            ), +        ); + +        system_callbacks.on_created(self, SystemMetadata { ent_id });      } -    pub fn register_observer_system<'this, SystemImpl, Event>( +    pub fn register_system<'this, SystemImpl>(          &'this mut self, +        phase_euid: Uid,          system: impl System<'this, SystemImpl>, -        event: Event, -    ) where -        Event: Component, +    )      { -        self.create_entity::<(SystemComponent, Event)>(( -            SystemComponent { system: system.into_type_erased() }, -            event, +        let (type_erased_system, mut system_callbacks) = system.finish(); + +        let system_ent_id = self.create_entity(( +            SystemComponent { system: type_erased_system }, +            Pair::builder() +                .relation::<DependsOn>() +                .target_id(phase_euid) +                .build(),          )); + +        system_callbacks.on_created(self, SystemMetadata { ent_id: system_ent_id });      }      /// Adds a extensions. -    /// -    /// # Panics -    /// Will panic if mutable internal lock cannot be acquired.      pub fn add_extension(&mut self, extension: impl Extension)      {          let extension_collector = ExtensionCollector::new(self); @@ -175,7 +190,9 @@ impl World          extension.collect(extension_collector);      } -    pub fn query<FieldTerms, FieldlessTerms>(&self) -> Query<FieldTerms, FieldlessTerms> +    pub fn query<FieldTerms, FieldlessTerms>( +        &self, +    ) -> Query<'_, FieldTerms, FieldlessTerms>      where          FieldTerms: QueryTermWithFieldTuple,          FieldlessTerms: QueryTermWithoutFieldTuple, @@ -183,19 +200,42 @@ impl World          Query::new(self)      } -    pub fn flexible_query<'terms>( +    pub fn flexible_query<const MAX_TERM_CNT: usize>(          &self, -        terms: QueryTerms<'terms>, -    ) -> FlexibleQuery<'_, 'terms> +        terms: QueryTerms<MAX_TERM_CNT>, +    ) -> FlexibleQuery<'_, MAX_TERM_CNT>      {          FlexibleQuery::new(self, terms)      } +    pub fn get_entity(&self, entity_id: Uid) -> Option<EntityHandle<'_>> +    { +        let archetype = self +            .data +            .component_storage +            .get_entity_archetype(entity_id)?; + +        let Some(entity) = archetype.get_entity_by_id(entity_id) else { +            unreachable!("Should exist since archetype was found by entity id"); +        }; + +        Some(EntityHandle::new(archetype, entity, self)) +    } + +    pub fn get_sole<SoleT: Sole>(&self) -> Option<Single<'_, SoleT>> +    { +        Some(Single::new(self.data.sole_storage.get::<SoleT>()?)) +    } + +    pub fn event_submitter(&self) -> EventSubmitter<'_> +    { +        EventSubmitter::new(&self.data.new_events) +    } +      /// Performs a single tick. -    ///      /// # Panics -    /// Will panic if a internal lock cannot be acquired. -    pub fn step(&self) -> StepResult +    /// Will panic if mutable internal lock cannot be acquired. +    pub fn step(&mut self) -> StepResult      {          if self.stop.load(Ordering::Relaxed) {              return StepResult::Stop; @@ -211,8 +251,9 @@ impl World          self.perform_phases(); -        self.lock_component_storage_rw() -            .create_imaginary_archetypes(); +        self.emit_new_events(); + +        self.data.component_storage.create_imaginary_archetypes();          self.perform_queued_actions(); @@ -220,17 +261,9 @@ impl World              return StepResult::Stop;          } -        let mut stats_lock = self -            .data -            .sole_storage -            .get::<Stats>() -            .expect("No stats sole found") -            .write_nonblock() -            .expect("Failed to aquire read-write stats sole lock"); - -        let stats = stats_lock -            .downcast_mut::<Stats>() -            .expect("Casting stats sole to Stats type failed"); +        let Some(mut stats) = self.get_sole::<Stats>() else { +            unreachable!(); // Reason: is added in World::new +        };          stats.current_tick += 1; @@ -238,10 +271,7 @@ impl World      }      /// Starts a loop which calls [`Self::step`] until the world is stopped. -    /// -    /// # Panics -    /// Will panic if a internal lock cannot be acquired. -    pub fn start_loop(&self) +    pub fn start_loop(&mut self)      {          while let StepResult::Continue = self.step() {}      } @@ -259,13 +289,7 @@ impl World              VizoxideArchetypeGraphParams,          }; -        let component_storage_lock = self -            .data -            .component_storage -            .read_nonblock() -            .expect("Failed to acquire read-only component storage lock"); - -        component_storage_lock.create_vizoxide_archetype_graph( +        self.data.component_storage.create_vizoxide_archetype_graph(              name,              VizoxideArchetypeGraphParams {                  create_node_name: |archetype, _| { @@ -274,7 +298,7 @@ impl World                          archetype                              .component_ids_sorted()                              .into_iter() -                            .map(|comp_id| comp_id.id().to_string()) +                            .map(|comp_id| comp_id.to_string())                              .collect::<Vec<_>>()                              .join(", ")                      )) @@ -299,161 +323,168 @@ impl World          )      } -    fn query_and_run_systems(&self, phase_euid: Uid) +    #[tracing::instrument(skip_all)] +    fn create_ent( +        &mut self, +        entity_uid: Uid, +        components: impl IntoIterator<Item = ComponentParts>, +    )      { -        let system_comps_query = -            self.query::<(&SystemComponent, &Relationship<DependsOn, Phase>), ()>(); +        debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + +        if let Err(err) = self.data.component_storage.create_entity(entity_uid) { +            tracing::warn!("Failed to create entity: {err}"); +            return; +        } + +        Self::add_entity_components( +            entity_uid, +            components, +            &mut self.data.component_storage, +            &EventSubmitter::new(&self.data.new_events), +        ); +    } -        let system_iter = system_comps_query.iter().filter(|(_, phase_rel)| { -            phase_rel -                .target_uids() -                .any(|target_uid| target_uid == phase_euid) -        }); +    fn query_and_run_systems(&self, phase_euid: Uid) +    { +        let system_query = Query::<(&SystemComponent,)>::from_flexible_query( +            self.flexible_query( +                QueryTerms::<QUERY_MAX_TERM_CNT>::builder() +                    .with_required([ +                        SystemComponent::id(), +                        Pair::builder() +                            .relation::<DependsOn>() +                            .target_id(phase_euid) +                            .build() +                            .id(), +                    ]) +                    .build(), +            ), +        ); -        for (system_component, _) in system_iter { +        for (system_ent_id, (system_component,)) in system_query.iter_with_euids() {              // SAFETY: The world lives long enough              unsafe { -                system_component.system.run(self); +                system_component +                    .system +                    .run(self, SystemMetadata { ent_id: system_ent_id });              }          }      }      fn perform_child_phases(&self, parent_phase_euid: Uid)      { -        let phase_query = self.query::<(&Phase, &Relationship<ChildOf, Phase>), ()>(); - -        for (child_phase_euid, (_, phase_rel)) in phase_query.iter_with_euids() { -            if !phase_rel -                .target_uids() -                .any(|phase_euid| phase_euid == parent_phase_euid) -            { -                continue; -            } +        let phase_query = self.flexible_query( +            QueryTerms::<2>::builder() +                .with_required([ +                    Phase::id(), +                    Pair::builder() +                        .relation::<ChildOf>() +                        .target_id(parent_phase_euid) +                        .build() +                        .id(), +                ]) +                .build(), +        ); -            self.query_and_run_systems(child_phase_euid); -            self.perform_child_phases(child_phase_euid); +        for child_phase_entity in &phase_query { +            self.query_and_run_systems(child_phase_entity.uid()); +            self.perform_child_phases(child_phase_entity.uid());          }      } +    fn perform_single_phase(&self, phase_entity_id: Uid) +    { +        self.query_and_run_systems(phase_entity_id); +        self.perform_child_phases(phase_entity_id); +    } +      fn perform_phases(&self)      { -        let phase_query = -            self.query::<(&Phase,), (Without<Relationship<ChildOf, Phase>>,)>(); +        self.perform_single_phase(*PRE_UPDATE_PHASE); +        self.perform_single_phase(*UPDATE_PHASE); +        self.perform_single_phase(*POST_UPDATE_PHASE); +    } -        for (phase_euid, (_,)) in phase_query.iter_with_euids() { -            if phase_euid == *START_PHASE { -                continue; -            } +    fn emit_new_events(&self) +    { +        loop { +            let new_events = { +                let mut new_events_lock = self +                    .data +                    .new_events +                    .write_nonblock() +                    .expect("Failed to acquire read-write lock to new events"); + +                if new_events_lock.is_empty() { +                    break; +                } + +                new_events_lock.take() +            }; -            self.query_and_run_systems(phase_euid); -            self.perform_child_phases(phase_euid); +            for (event_id, event_matches) in new_events { +                self.emit_event_observers( +                    event_id, +                    &EmittedEvent { +                        event: event_id, +                        match_ids: &event_matches.match_ids, +                    }, +                ); +            }          }      }      #[tracing::instrument(skip_all)] -    fn perform_queued_actions(&self) +    fn perform_queued_actions(&mut self)      { -        let mut active_action_queue = match *self.data.action_queue.active_queue.borrow() -        { -            ActiveActionQueue::A => &self.data.action_queue.queue_a, -            ActiveActionQueue::B => &self.data.action_queue.queue_b, -        } -        .write_nonblock() -        .unwrap_or_else(|err| { -            panic!( -                "Failed to take read-write action queue lock {:?}: {err}", -                self.data.action_queue.active_queue -            ); -        }); - -        let mut has_swapped_active_queue = false; +        let mut action_queue_lock = self +            .data +            .action_queue +            .queue +            .write_nonblock() +            .unwrap_or_else(|err| { +                panic!("Failed to take read-write action queue lock: {err}",); +            }); -        for action in active_action_queue.drain(..) { +        for action in action_queue_lock.drain(..) {              match action { -                Action::Spawn(components, component_added_event_ids) => { +                Action::Spawn(new_entity_uid, components) => { +                    if let Err(err) = +                        self.data.component_storage.create_entity(new_entity_uid)                      { -                        let mut component_storage_lock = self.lock_component_storage_rw(); - -                        let new_entity_uid = Uid::new_unique(UidKind::Entity); - -                        if let Err(err) = -                            component_storage_lock.create_entity(new_entity_uid) -                        { -                            tracing::warn!("Failed to create entity: {err}"); -                            continue; -                        }; - -                        Self::add_entity_components( -                            new_entity_uid, -                            components, -                            &mut component_storage_lock, -                        ); -                    } - -                    if !has_swapped_active_queue { -                        self.swap_event_queue(&mut has_swapped_active_queue); +                        tracing::warn!("Failed to create entity: {err}"); +                        continue;                      } -                    for comp_added_event_id in component_added_event_ids.ids { -                        self.emit_event_by_id(comp_added_event_id); -                    } +                    Self::add_entity_components( +                        new_entity_uid, +                        components, +                        &mut self.data.component_storage, +                        &EventSubmitter::new(&self.data.new_events), +                    );                  }                  Action::Despawn(entity_uid) => { -                    self.despawn_entity(entity_uid, &mut has_swapped_active_queue); -                } -                Action::AddComponents( -                    entity_uid, -                    components, -                    component_added_event_ids, -                ) => { +                    if let Err(err) = +                        self.data.component_storage.remove_entity(entity_uid)                      { -                        let mut component_storage_lock = self.lock_component_storage_rw(); - -                        Self::add_entity_components( -                            entity_uid, -                            components, -                            &mut component_storage_lock, -                        ); -                    } - -                    if !has_swapped_active_queue { -                        self.swap_event_queue(&mut has_swapped_active_queue); -                    } - -                    // TODO: Fix that events are emitted for components that haven't been -                    // added because a error occurred (for example, the entity already has -                    // the component) -                    for comp_added_event_id in component_added_event_ids.ids { -                        self.emit_event_by_id(comp_added_event_id); +                        tracing::error!("Failed to despawn entity: {err}");                      }                  } -                Action::RemoveComponents( -                    entity_uid, -                    components_metadata, -                    component_removed_event_ids, -                ) => { -                    { -                        let mut component_storage_lock = self.lock_component_storage_rw(); - -                        Self::remove_entity_components( -                            entity_uid, -                            components_metadata -                                .iter() -                                .map(|comp_metadata| comp_metadata.id), -                            &mut component_storage_lock, -                        ); -                    } - -                    if !has_swapped_active_queue { -                        self.swap_event_queue(&mut has_swapped_active_queue); -                    } - -                    // TODO: Fix that events are emitted for components that haven't been -                    // removed because a error occurred (for example, the entity does not -                    // have the component) -                    for comp_removed_event_id in component_removed_event_ids.ids { -                        self.emit_event_by_id(comp_removed_event_id); -                    } +                Action::AddComponents(entity_uid, components) => { +                    Self::add_entity_components( +                        entity_uid, +                        components, +                        &mut self.data.component_storage, +                        &EventSubmitter::new(&self.data.new_events), +                    ); +                } +                Action::RemoveComponents(entity_uid, component_ids) => { +                    Self::remove_entity_components( +                        entity_uid, +                        component_ids, +                        &mut self.data.component_storage, +                    );                  }                  Action::Stop => {                      self.stop.store(true, Ordering::Relaxed); @@ -462,58 +493,39 @@ impl World          }      } -    #[tracing::instrument(skip_all)] -    fn despawn_entity(&self, entity_uid: Uid, has_swapped_active_queue: &mut bool) -    { -        let mut component_storage_lock = self.lock_component_storage_rw(); - -        let components = match component_storage_lock.remove_entity(entity_uid) { -            Ok(components) => components, -            Err(err) => { -                tracing::error!("Failed to despawn entity: {err}"); -                return; -            } -        }; - -        let component_removed_event_uids = 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); -        } -    } -      fn add_entity_components(          entity_uid: Uid, -        components: impl IntoIterator<Item = (Uid, Box<dyn Component>)>, +        components: impl IntoIterator<Item = ComponentParts>,          component_storage: &mut ComponentStorage, +        event_submitter: &EventSubmitter<'_>,      )      { -        for (component_id, component) in components { -            if let Err(err) = component_storage -                .add_entity_component(entity_uid, (component_id, component)) -            { -                tracing::error!("Failed to add component to entity: {err}"); +        let component_iter = components.into_iter(); + +        for component_parts in component_iter { +            let comp_id = component_parts.id(); + +            let comp_name = component_parts.name(); + +            if let Err(err) = component_storage.add_entity_component( +                entity_uid, +                (comp_id, comp_name, component_parts.into_data()), +            ) { +                tracing::error!("Failed to add component {comp_name} to entity: {err}"); +                continue; +            } + +            if comp_id.kind() == UidKind::Pair { +                continue;              } + +            event_submitter.submit_event( +                &Pair::builder() +                    .relation::<Added>() +                    .target_id(comp_id) +                    .build(), +                entity_uid, +            );          }      } @@ -523,7 +535,9 @@ impl World          component_storage: &mut ComponentStorage,      )      { -        for component_id in component_ids { +        let component_id_iter = component_ids.into_iter(); + +        for component_id in component_id_iter {              if let Err(err) =                  component_storage.remove_entity_component(entity_uid, component_id)              { @@ -532,48 +546,28 @@ impl World          }      } -    fn emit_event_by_id(&self, event_id: Uid) +    fn emit_event_observers(&self, event_id: Uid, emitted_event: &EmittedEvent<'_>)      { -        //let query = self.flexible_query([ -        //    ComponentMetadata::of::<SystemComponent>(), -        //    ComponentMetadata { id: event_id, is_optional: false }, -        //]); - -        let mut query_required_ids = [SystemComponent::id(), event_id]; - -        let query = self.flexible_query( -            QueryTerms::builder() -                .with_required_ids(&mut query_required_ids) -                .build(), +        assert_eq!(event_id.kind(), UidKind::Pair); + +        let query = Query::<(&ObserverWrapperComponent,)>::from_flexible_query( +            self.flexible_query( +                QueryTerms::<QUERY_MAX_TERM_CNT>::builder() +                    .with_required([ObserverWrapperComponent::id(), event_id]) +                    .build(), +            ),          ); -        for (system,) in ComponentIter::<(&SystemComponent,), _>::new(self, query.iter()) -        { +        for (observer_ent_id, (observer,)) in query.iter_with_euids() {              unsafe { -                system.system.run(self); +                observer.run( +                    self, +                    SystemMetadata { ent_id: observer_ent_id }, +                    emitted_event.clone(), +                );              }          }      } - -    fn swap_event_queue(&self, has_swapped_active_queue: &mut bool) -    { -        let mut active_queue = self.data.action_queue.active_queue.borrow_mut(); - -        *active_queue = match *active_queue { -            ActiveActionQueue::A => ActiveActionQueue::B, -            ActiveActionQueue::B => ActiveActionQueue::A, -        }; - -        *has_swapped_active_queue = true; -    } - -    fn lock_component_storage_rw(&self) -> WriteGuard<'_, ComponentStorage> -    { -        self.data -            .component_storage -            .write_nonblock() -            .expect("Failed to acquire read-write component storage lock") -    }  }  impl Default for World @@ -595,74 +589,66 @@ pub enum StepResult  }  #[derive(Debug, Default)] -pub struct WorldData +struct WorldData  { -    component_storage: Arc<Lock<ComponentStorage>>, +    component_storage: ComponentStorage,      sole_storage: SoleStorage, -    action_queue: Arc<ActionQueue>, +    action_queue: Rc<ActionQueue>, +    new_events: Lock<NewEvents>,  } -#[derive(Debug)] -#[non_exhaustive] -pub struct EntityComponent +#[derive(Debug, Clone)] +pub struct EntityComponentRef<'a>  { -    pub id: Uid, -    pub name: &'static str, -    pub component: Lock<Box<dyn Component>>, +    component_id: Uid, +    component: &'a ArchetypeEntityComponent, +    entity_id: Uid,  } -impl EntityComponent +impl<'a> EntityComponentRef<'a>  { -    pub fn new(id: Uid, component: Box<dyn Component>) -> Self +    fn component(&self) -> &'a Lock<Box<dyn Any>> +    { +        self.component.component() +    } + +    #[must_use] +    pub fn id(&self) -> Uid +    { +        self.component_id +    } + +    #[must_use] +    pub fn entity_id(&self) -> Uid +    { +        self.entity_id +    } + +    fn new(component_id: Uid, comp: &'a ArchetypeEntityComponent, entity_id: Uid) +        -> Self      {          Self { -            id, -            name: component.type_name(), -            component: Lock::new(component), +            component_id, +            component: comp, +            entity_id,          }      }  } -#[derive(Debug, Default, Clone, Copy)] -enum ActiveActionQueue -{ -    #[default] -    A, -    B, -} -  #[derive(Debug, Default)]  struct ActionQueue  { -    queue_a: Lock<Vec<Action>>, -    queue_b: Lock<Vec<Action>>, -    active_queue: RefCell<ActiveActionQueue>, +    queue: Lock<Vec<Action>>,  }  impl ActionQueue  {      fn push(&self, action: Action)      { -        match *self.active_queue.borrow() { -            ActiveActionQueue::A => self -                .queue_a -                .write_nonblock() -                .expect("Failed to aquire read-write action queue A lock") -                .push(action), -            ActiveActionQueue::B => self -                .queue_b -                .write_nonblock() -                .expect("Failed to aquire read-write action queue A lock") -                .push(action), -        } -    } -} - -impl TypeName for ActionQueue -{ -    fn type_name(&self) -> &'static str -    { -        type_name::<Self>() +        self.queue +            .write_nonblock() +            .expect("Failed to aquire read-write lock to action queue") +            .push(action);      }  } @@ -707,7 +693,7 @@ impl SoleStorage          self.storage.insert(              sole_type_id,              ManuallyDrop::new(StoredSole { -                sole: Arc::new(Lock::new(Box::new(sole))), +                sole: Arc::new(Lock::new(Box::new(sole), type_name::<SoleT>())),                  drop_last,              }),          ); @@ -724,18 +710,9 @@ impl Drop for SoleStorage          for sole in self.storage.values_mut() {              if sole.drop_last { -                tracing::trace!( -                    "Sole {} pushed to dropping last queue", -                    sole.sole.read_nonblock().unwrap().type_name() -                ); -                  soles_to_drop_last.push(sole);                  continue;              } -            tracing::trace!( -                "Dropping sole {}", -                sole.sole.read_nonblock().unwrap().type_name() -            );              unsafe {                  ManuallyDrop::drop(sole); @@ -743,11 +720,6 @@ impl Drop for SoleStorage          }          for sole in &mut soles_to_drop_last { -            tracing::trace!( -                "Dropping sole {} last", -                sole.sole.read_nonblock().unwrap().type_name() -            ); -              unsafe {                  ManuallyDrop::drop(sole);              } | 
