summaryrefslogtreecommitdiff
path: root/ecs/src/relationship.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/relationship.rs')
-rw-r--r--ecs/src/relationship.rs434
1 files changed, 0 insertions, 434 deletions
diff --git a/ecs/src/relationship.rs b/ecs/src/relationship.rs
deleted file mode 100644
index e368dd4..0000000
--- a/ecs/src/relationship.rs
+++ /dev/null
@@ -1,434 +0,0 @@
-use std::any::type_name;
-use std::marker::PhantomData;
-
-use ecs_macros::Component;
-
-use crate::component::storage::Storage as ComponentStorage;
-use crate::component::{
- Component,
- Handle as ComponentHandle,
- HandleError as ComponentHandleError,
- HandleFromEntityComponentRef,
- HandleMut as ComponentHandleMut,
-};
-use crate::lock::ReadGuard;
-use crate::uid::{Kind as UidKind, Uid};
-use crate::{EntityComponentRef, World};
-
-/// A relationship to one or more targets.
-#[derive(Debug, Component)]
-#[component(
- handle_type = Relation<'component, Kind, ComponentT>,
- handle_mut_type = RelationMut<'component, Kind, ComponentT>,
-)]
-pub struct Relationship<Kind, ComponentT: Component>
-where
- Kind: 'static,
-{
- entity_uid: SingleOrMultiple<Uid>,
- _pd: PhantomData<(Kind, ComponentT)>,
-}
-
-impl<Kind, ComponentT> Relationship<Kind, ComponentT>
-where
- ComponentT: Component,
-{
- /// Creates a new `Relationship` with a single target.
- #[must_use]
- pub fn new(entity_uid: Uid) -> Self
- {
- debug_assert_eq!(entity_uid.kind(), UidKind::Entity);
-
- Self {
- entity_uid: SingleOrMultiple::Single(entity_uid),
- _pd: PhantomData,
- }
- }
-
- /// Creates a new `Relationship` with multiple targets.
- #[must_use]
- pub fn new_multiple(entity_uids: impl IntoIterator<Item = Uid>) -> Self
- {
- let uids = entity_uids.into_iter().collect::<Vec<_>>();
-
- for euid in &uids {
- debug_assert_eq!(euid.kind(), UidKind::Entity);
- }
-
- Self {
- entity_uid: SingleOrMultiple::Multiple(uids),
- _pd: PhantomData,
- }
- }
-}
-
-pub struct RelationMut<'rel_comp, Kind, ComponentT>
-where
- Kind: 'static,
- ComponentT: Component,
-{
- component_storage_lock: ReadGuard<'rel_comp, ComponentStorage>,
- relationship_comp: ComponentHandleMut<'rel_comp, Relationship<Kind, ComponentT>>,
-}
-
-impl<'rel_comp, Kind, ComponentT> HandleFromEntityComponentRef<'rel_comp>
- for RelationMut<'rel_comp, Kind, ComponentT>
-where
- ComponentT: Component,
-{
- type Error = ComponentHandleError;
-
- fn from_entity_component_ref(
- entity_component_ref: Option<EntityComponentRef<'rel_comp>>,
- world: &'rel_comp World,
- ) -> Result<Self, Self::Error>
- {
- let relationship_comp_handle_from_ent_comp_ref = ComponentHandleMut::<
- Relationship<Kind, ComponentT>,
- >::from_entity_component_ref;
-
- let relationship_comp =
- relationship_comp_handle_from_ent_comp_ref(entity_component_ref, world)?;
-
- let component_storage_lock = world
- .data
- .component_storage
- .read_nonblock()
- .expect("Failed to aquire read-only component storage lock");
-
- Ok(Self {
- relationship_comp,
- component_storage_lock,
- })
- }
-}
-
-impl<'rel_comp, Kind, ComponentT> RelationMut<'rel_comp, Kind, ComponentT>
-where
- ComponentT: Component,
-{
- /// Returns the component of the target at the specified index.
- ///
- /// # Panics
- /// Will panic if the entity does not exist in the archetype it belongs to. This
- /// should hopefully never happend.
- #[must_use]
- pub fn get(&self, index: usize) -> Option<ComponentHandleMut<'_, ComponentT>>
- {
- let target = self.get_target(index)?;
-
- let archetype = self.component_storage_lock.get_entity_archetype(*target)?;
-
- let entity = archetype
- .get_entity_by_id(*target)
- .expect("Target entity is gone from archetype");
-
- let component_index = archetype.get_index_for_component(ComponentT::id())?;
-
- let component = ComponentHandleMut::new(
- entity
- .components()
- .get(component_index)?
- .component()
- .write_nonblock()
- .unwrap_or_else(|_| {
- panic!(
- "Failed to aquire read-write lock of component {}",
- type_name::<ComponentT>()
- )
- }),
- );
-
- Some(component)
- }
-
- /// Returns a reference to the target at the specified index.
- #[must_use]
- pub fn get_target(&self, index: usize) -> Option<&Uid>
- {
- match &self.relationship_comp.entity_uid {
- SingleOrMultiple::Single(entity_uid) if index == 0 => Some(entity_uid),
- SingleOrMultiple::Multiple(entity_uids) => entity_uids.get(index),
- SingleOrMultiple::Single(_) => None,
- }
- }
-
- /// Returns a mutable reference to the target at the specified index.
- #[must_use]
- pub fn get_target_mut(&mut self, index: usize) -> Option<&mut Uid>
- {
- match &mut self.relationship_comp.entity_uid {
- SingleOrMultiple::Single(entity_uid) if index == 0 => Some(entity_uid),
- SingleOrMultiple::Multiple(entity_uids) => entity_uids.get_mut(index),
- SingleOrMultiple::Single(_) => None,
- }
- }
-
- /// Adds a target to the relationship.
- pub fn add_target(&mut self, entity_uid: Uid)
- {
- debug_assert_eq!(entity_uid.kind(), UidKind::Entity);
-
- match &mut self.relationship_comp.entity_uid {
- SingleOrMultiple::Single(prev_entity_uid) => {
- self.relationship_comp.entity_uid =
- SingleOrMultiple::Multiple(vec![*prev_entity_uid, entity_uid]);
- }
- SingleOrMultiple::Multiple(entity_uids) => entity_uids.push(entity_uid),
- }
- }
-
- /// Removes a target to the relationship, returning it.
- pub fn remove_target(&mut self, index: usize) -> Option<Uid>
- {
- match &mut self.relationship_comp.entity_uid {
- SingleOrMultiple::Single(entity_uid) => {
- let prev_entity_uid = *entity_uid;
-
- self.relationship_comp.entity_uid =
- SingleOrMultiple::Multiple(Vec::new());
-
- Some(prev_entity_uid)
- }
- SingleOrMultiple::Multiple(entity_uids) => {
- if index >= entity_uids.len() {
- return None;
- }
-
- Some(entity_uids.remove(index))
- }
- }
- }
-
- #[must_use]
- pub fn target_count(&self) -> usize
- {
- match &self.relationship_comp.entity_uid {
- SingleOrMultiple::Single(_) => 1,
- SingleOrMultiple::Multiple(entity_uids) => entity_uids.len(),
- }
- }
-
- /// Returns a iterator of the components of the targets of this relationship.
- #[must_use]
- pub fn iter(&self) -> TargetComponentIterMut<'_, 'rel_comp, Kind, ComponentT>
- {
- TargetComponentIterMut { relation: self, index: 0 }
- }
-}
-
-impl<'relationship, 'rel_comp, Kind, ComponentT> IntoIterator
- for &'relationship RelationMut<'rel_comp, Kind, ComponentT>
-where
- 'relationship: 'rel_comp,
- ComponentT: Component,
-{
- type IntoIter = TargetComponentIterMut<'relationship, 'rel_comp, Kind, ComponentT>;
- type Item = ComponentHandleMut<'rel_comp, ComponentT>;
-
- fn into_iter(self) -> Self::IntoIter
- {
- self.iter()
- }
-}
-
-/// Iterator of the components of the targets of a relationship.
-pub struct TargetComponentIterMut<'relationship, 'rel_comp, Kind, ComponentT>
-where
- Kind: 'static,
- ComponentT: Component,
-{
- relation: &'relationship RelationMut<'rel_comp, Kind, ComponentT>,
- index: usize,
-}
-
-impl<'relationship, 'rel_comp, Kind, ComponentT> Iterator
- for TargetComponentIterMut<'relationship, 'rel_comp, Kind, ComponentT>
-where
- 'relationship: 'rel_comp,
- Kind: 'static,
- ComponentT: Component,
-{
- type Item = ComponentHandleMut<'rel_comp, ComponentT>;
-
- fn next(&mut self) -> Option<Self::Item>
- {
- let index = self.index;
-
- self.index += 1;
-
- self.relation.get(index)
- }
-}
-
-#[derive(Debug)]
-enum SingleOrMultiple<Value>
-{
- Single(Value),
- Multiple(Vec<Value>),
-}
-
-pub struct Relation<'rel_comp, Kind, ComponentT>
-where
- Kind: 'static,
- ComponentT: Component,
-{
- component_storage_lock: ReadGuard<'rel_comp, ComponentStorage>,
- relationship_comp: ComponentHandle<'rel_comp, Relationship<Kind, ComponentT>>,
-}
-
-impl<'rel_comp, Kind, ComponentT> HandleFromEntityComponentRef<'rel_comp>
- for Relation<'rel_comp, Kind, ComponentT>
-where
- ComponentT: Component,
-{
- type Error = ComponentHandleError;
-
- fn from_entity_component_ref(
- entity_component_ref: Option<EntityComponentRef<'rel_comp>>,
- world: &'rel_comp World,
- ) -> Result<Self, Self::Error>
- {
- let relationship_comp_handle_from_ent_comp_ref =
- ComponentHandle::<Relationship<Kind, ComponentT>>::from_entity_component_ref;
-
- let relationship_comp =
- relationship_comp_handle_from_ent_comp_ref(entity_component_ref, world)?;
-
- let component_storage_lock = world
- .data
- .component_storage
- .read_nonblock()
- .expect("Failed to aquire read-only component storage lock");
-
- Ok(Self {
- relationship_comp,
- component_storage_lock,
- })
- }
-}
-
-impl<'rel_comp, Kind, ComponentT> Relation<'rel_comp, Kind, ComponentT>
-where
- ComponentT: Component,
-{
- /// Returns the component of the target at the specified index.
- ///
- /// # Panics
- /// Will panic if the entity does not exist in the archetype it belongs to. This
- /// should hopefully never happend.
- #[must_use]
- pub fn get(&self, index: usize) -> Option<ComponentHandle<'_, ComponentT>>
- {
- let target = self.get_target(index)?;
-
- let archetype = self.component_storage_lock.get_entity_archetype(*target)?;
-
- let entity = archetype
- .get_entity_by_id(*target)
- .expect("Target entity is gone from archetype");
-
- let component_index = archetype.get_index_for_component(ComponentT::id())?;
-
- let component = ComponentHandle::new(
- entity
- .components()
- .get(component_index)?
- .component()
- .read_nonblock()
- .unwrap_or_else(|_| {
- panic!(
- "Failed to aquire read-write lock of component {}",
- type_name::<ComponentT>()
- )
- }),
- );
-
- Some(component)
- }
-
- /// Returns a reference to the target at the specified index.
- #[must_use]
- pub fn get_target(&self, index: usize) -> Option<&Uid>
- {
- match &self.relationship_comp.entity_uid {
- SingleOrMultiple::Single(entity_uid) if index == 0 => Some(entity_uid),
- SingleOrMultiple::Multiple(entity_uids) => entity_uids.get(index),
- SingleOrMultiple::Single(_) => None,
- }
- }
-
- #[must_use]
- pub fn target_count(&self) -> usize
- {
- match &self.relationship_comp.entity_uid {
- SingleOrMultiple::Single(_) => 1,
- SingleOrMultiple::Multiple(entity_uids) => entity_uids.len(),
- }
- }
-
- pub fn target_uids(&self) -> impl Iterator<Item = Uid> + '_
- {
- (0..self.target_count())
- .map_while(|target_index| self.get_target(target_index).copied())
- }
-
- /// Returns a iterator of the components of the targets of this relationship.
- #[must_use]
- pub fn iter(&self) -> TargetComponentIter<'_, 'rel_comp, Kind, ComponentT>
- {
- TargetComponentIter { relation: self, index: 0 }
- }
-}
-
-impl<'relationship, 'rel_comp, Kind, ComponentT> IntoIterator
- for &'relationship Relation<'rel_comp, Kind, ComponentT>
-where
- 'relationship: 'rel_comp,
- ComponentT: Component,
-{
- type IntoIter = TargetComponentIter<'relationship, 'rel_comp, Kind, ComponentT>;
- type Item = ComponentHandle<'rel_comp, ComponentT>;
-
- fn into_iter(self) -> Self::IntoIter
- {
- self.iter()
- }
-}
-
-/// Iterator of the components of the targets of a relationship.
-pub struct TargetComponentIter<'relationship, 'rel_comp, Kind, ComponentT>
-where
- Kind: 'static,
- ComponentT: Component,
-{
- relation: &'relationship Relation<'rel_comp, Kind, ComponentT>,
- index: usize,
-}
-
-impl<'relationship, 'rel_comp, Kind, ComponentT> Iterator
- for TargetComponentIter<'relationship, 'rel_comp, Kind, ComponentT>
-where
- 'relationship: 'rel_comp,
- Kind: 'static,
- ComponentT: Component,
-{
- type Item = ComponentHandle<'rel_comp, ComponentT>;
-
- fn next(&mut self) -> Option<Self::Item>
- {
- let index = self.index;
-
- self.index += 1;
-
- self.relation.get(index)
- }
-}
-
-/// Relationship kind denoting a dependency to another entity
-#[derive(Debug, Default, Clone, Copy)]
-pub struct DependsOn;
-
-/// Relationship kind denoting being the child of another entity.
-#[derive(Debug, Default, Clone, Copy)]
-pub struct ChildOf;