diff options
Diffstat (limited to 'ecs/src')
| -rw-r--r-- | ecs/src/component.rs | 4 | ||||
| -rw-r--r-- | ecs/src/component/storage.rs | 2 | ||||
| -rw-r--r-- | ecs/src/component/storage/archetype.rs | 13 | ||||
| -rw-r--r-- | ecs/src/event/component.rs | 98 | ||||
| -rw-r--r-- | ecs/src/lib.rs | 122 | 
5 files changed, 98 insertions, 141 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs index 207c329..cc4b460 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -5,7 +5,6 @@ use std::ops::{Deref, DerefMut};  use seq_macro::seq; -use crate::event::component::Kind as ComponentEventKind;  use crate::lock::{      Error as LockError,      MappedReadGuard, @@ -39,9 +38,6 @@ pub trait Component: SystemInput + Any      /// Returns the name of this component.      fn name(&self) -> &'static str; - -    /// Returns the component UID of a component event for this component. -    fn get_event_uid(&self, event_kind: ComponentEventKind) -> Uid;  }  impl dyn Component diff --git a/ecs/src/component/storage.rs b/ecs/src/component/storage.rs index 9cf4433..14f3ea4 100644 --- a/ecs/src/component/storage.rs +++ b/ecs/src/component/storage.rs @@ -268,7 +268,7 @@ impl Storage          entity.insert_component(              component_id, -            ArchetypeEntityComponent::new(component, component_name), +            ArchetypeEntityComponent::new(component, component_id, component_name),              add_edge_archetype,          ); diff --git a/ecs/src/component/storage/archetype.rs b/ecs/src/component/storage/archetype.rs index 10a665e..f8c204b 100644 --- a/ecs/src/component/storage/archetype.rs +++ b/ecs/src/component/storage/archetype.rs @@ -314,18 +314,29 @@ impl Entity  #[derive(Debug)]  pub struct EntityComponent  { +    id: Uid,      component: Lock<Box<dyn Any>>,  }  impl EntityComponent  { -    pub fn new(component: Box<dyn Any>, component_name: &'static str) -> Self +    pub fn new( +        component: Box<dyn Any>, +        component_id: Uid, +        component_name: &'static str, +    ) -> Self      {          Self { +            id: component_id,              component: Lock::new(component, component_name),          }      } +    pub fn id(&self) -> Uid +    { +        self.id +    } +      pub fn component(&self) -> &Lock<Box<dyn Any>>      {          &self.component diff --git a/ecs/src/event/component.rs b/ecs/src/event/component.rs index b4edffc..ef09480 100644 --- a/ecs/src/event/component.rs +++ b/ecs/src/event/component.rs @@ -1,84 +1,18 @@  //! Component events. -use std::fmt::{Debug, Formatter}; -use std::marker::PhantomData; - -use ecs_macros::Component; - -use crate::component::Component; - -/// Event emitted when: -/// a) A entity with component `ComponentT` is spawned. -/// b) A component `ComponentT` is added to a entity. -#[derive(Clone, Component)] -pub struct Added<ComponentT> -where -    ComponentT: Component, -{ -    _pd: PhantomData<ComponentT>, -} - -impl<ComponentT> Debug for Added<ComponentT> -where -    ComponentT: Component, -{ -    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result -    { -        formatter -            .debug_struct("Added") -            .field("_pd", &self._pd) -            .finish() -    } -} - -impl<ComponentT> Default for Added<ComponentT> -where -    ComponentT: Component, -{ -    fn default() -> Self -    { -        Self { _pd: PhantomData } -    } -} - -/// Event emitted when: -/// a) A `ComponentT` component is removed from a entity. -/// b) A entity with component `ComponentT` is despawned. -#[derive(Clone, Component)] -pub struct Removed<ComponentT> -where -    ComponentT: Component, -{ -    _pd: PhantomData<ComponentT>, -} - -impl<ComponentT> Debug for Removed<ComponentT> -where -    ComponentT: Component, -{ -    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result -    { -        formatter -            .debug_struct("Removed") -            .field("_pd", &self._pd) -            .finish() -    } -} - -impl<ComponentT> Default for Removed<ComponentT> -where -    ComponentT: Component, -{ -    fn default() -> Self -    { -        Self { _pd: PhantomData } -    } -} - -/// Specifies a kind of component event UID. -#[derive(Debug, Clone, Copy)] -#[non_exhaustive] -pub enum Kind -{ -    Removed, -} +use std::convert::Infallible; +use std::fmt::Debug; + +use crate::Component; + +/// Pair relation for events emitted when: +/// a) A entity with the target component is spawned. +/// b) The target component is added to a entity. +#[derive(Debug, Component)] +pub struct Added(Infallible); + +/// Pair relation for events emitted when: +/// a) The target component is removed from a entity. +/// b) A entity with the target component is despawned. +#[derive(Debug, Component)] +pub struct Removed(Infallible); diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 3b89dac..dd43e0b 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -18,6 +18,10 @@ use crate::component::{      Sequence as ComponentSequence,  };  use crate::entity::CREATE_STATIC_ENTITIES; +use crate::event::component::{ +    Added as ComponentAddedEvent, +    Removed as ComponentRemovedEvent, +};  use crate::extension::{Collector as ExtensionCollector, Extension};  use crate::lock::{Lock, WriteGuard};  use crate::pair::{ChildOf, DependsOn, Pair}; @@ -111,6 +115,8 @@ impl World      {          debug_assert_eq!(entity_uid.kind(), UidKind::Entity); +        let added_component_ids; +          {              let mut component_storage_lock = self.lock_component_storage_rw(); @@ -119,18 +125,16 @@ impl World                  return;              }; -            Self::add_entity_components( +            added_component_ids = Self::add_entity_components(                  entity_uid,                  components.into_parts_array(),                  &mut component_storage_lock,              );          } -        // TODO: Emit component added events here - -        // for added_event_id in Comps::added_event_ids() { -        //     self.emit_event_by_id(added_event_id); -        // } +        for comp_id in added_component_ids { +            self.emit_event_by_id::<ComponentAddedEvent>(comp_id); +        }      }      /// Adds a globally shared singleton value. @@ -156,14 +160,13 @@ impl World          ));      } -    pub fn register_observer_system<'this, SystemImpl, Event>( +    pub fn register_observer_system<'this, SystemImpl>(          &'this mut self,          system: impl System<'this, SystemImpl>, -        event: Event, -    ) where -        Event: Component, +        event: Pair<Uid, Uid>, +    )      { -        self.create_entity::<(SystemComponent, Event)>(( +        self.create_entity((              SystemComponent { system: system.into_type_erased() },              event,          )); @@ -377,6 +380,8 @@ impl World          for action in active_action_queue.drain(..) {              match action {                  Action::Spawn(components) => { +                    let added_component_ids; +                      {                          let mut component_storage_lock = self.lock_component_storage_rw(); @@ -389,7 +394,7 @@ impl World                              continue;                          }; -                        Self::add_entity_components( +                        added_component_ids = Self::add_entity_components(                              new_entity_uid,                              components,                              &mut component_storage_lock, @@ -400,20 +405,20 @@ impl World                          self.swap_event_queue(&mut has_swapped_active_queue);                      } -                    // TODO: Emit component added events here - -                    // for comp_added_event_id in component_added_event_ids.ids { -                    //     self.emit_event_by_id(comp_added_event_id); -                    // } +                    for comp_id in added_component_ids { +                        self.emit_event_by_id::<ComponentAddedEvent>(comp_id); +                    }                  }                  Action::Despawn(entity_uid) => {                      self.despawn_entity(entity_uid, &mut has_swapped_active_queue);                  }                  Action::AddComponents(entity_uid, components) => { +                    let added_component_ids; +                      {                          let mut component_storage_lock = self.lock_component_storage_rw(); -                        Self::add_entity_components( +                        added_component_ids = Self::add_entity_components(                              entity_uid,                              components,                              &mut component_storage_lock, @@ -424,20 +429,17 @@ impl World                          self.swap_event_queue(&mut has_swapped_active_queue);                      } -                    // TODO: Emit component added events here - -                    // 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); -                    // } +                    for comp_id in added_component_ids { +                        self.emit_event_by_id::<ComponentAddedEvent>(comp_id); +                    }                  }                  Action::RemoveComponents(entity_uid, component_ids) => { +                    let removed_component_ids; +                      {                          let mut component_storage_lock = self.lock_component_storage_rw(); -                        Self::remove_entity_components( +                        removed_component_ids = Self::remove_entity_components(                              entity_uid,                              component_ids,                              &mut component_storage_lock, @@ -448,14 +450,9 @@ impl World                          self.swap_event_queue(&mut has_swapped_active_queue);                      } -                    // TODO: Emit component removed events here - -                    // 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); -                    // } +                    for comp_id in removed_component_ids { +                        self.emit_event_by_id::<ComponentRemovedEvent>(comp_id); +                    }                  }                  Action::Stop => {                      self.stop.store(true, Ordering::Relaxed); @@ -469,7 +466,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}"); @@ -483,54 +480,73 @@ impl World              self.swap_event_queue(has_swapped_active_queue);          } -        // 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); -        // } +        for removed_ent_comp in removed_entity.components() { +            self.emit_event_by_id::<ComponentRemovedEvent>(removed_ent_comp.id()); +        }      }      fn add_entity_components(          entity_uid: Uid,          components: impl IntoIterator<Item = ComponentParts>,          component_storage: &mut ComponentStorage, -    ) +    ) -> Vec<Uid>      { -        for component_parts in components { +        let component_iter = components.into_iter(); + +        let mut added_component_ids = +            Vec::<Uid>::with_capacity(component_iter.size_hint().0); + +        for component_parts in component_iter { +            let comp_id = component_parts.id(); +              if let Err(err) = component_storage.add_entity_component(                  entity_uid, -                ( -                    component_parts.id(), -                    component_parts.name(), -                    component_parts.into_data(), -                ), +                (comp_id, component_parts.name(), component_parts.into_data()),              ) {                  tracing::error!("Failed to add component to entity: {err}"); +                continue;              } + +            added_component_ids.push(comp_id);          } + +        added_component_ids      }      fn remove_entity_components(          entity_uid: Uid,          component_ids: impl IntoIterator<Item = Uid>,          component_storage: &mut ComponentStorage, -    ) +    ) -> Vec<Uid>      { -        for component_id in component_ids { +        let component_id_iter = component_ids.into_iter(); + +        let mut removed_component_ids = +            Vec::<Uid>::with_capacity(component_id_iter.size_hint().0); + +        for component_id in component_id_iter {              if let Err(err) =                  component_storage.remove_entity_component(entity_uid, component_id)              {                  tracing::error!("Failed to remove component to entity: {err}"); +                continue;              } + +            removed_component_ids.push(component_id);          } + +        removed_component_ids      } -    #[allow(dead_code)] -    fn emit_event_by_id(&self, event_id: Uid) +    fn emit_event_by_id<Event: Component>(&self, target: Uid)      { +        if target.kind() == UidKind::Pair { +            return; +        } +          let query = self.flexible_query(              QueryTerms::<2>::builder() -                .with_required([SystemComponent::id(), event_id]) +                .with_required([SystemComponent::id(), Pair::new::<Event>(target).id()])                  .build(),          );  | 
