Skip to main content

goud_engine/ecs/components/hierarchy/
parent.rs

1//! [`Parent`] component for pointing to a parent entity.
2
3use crate::ecs::entity::Entity;
4use crate::ecs::Component;
5use std::fmt;
6
7// =============================================================================
8// Parent Component
9// =============================================================================
10
11/// Component indicating the parent entity of this entity.
12///
13/// When an entity has a `Parent` component, its transform (if any) is
14/// considered to be in the parent's local coordinate space. The hierarchy
15/// propagation system will compute the global transform by combining
16/// the parent's global transform with this entity's local transform.
17///
18/// # Memory Layout
19///
20/// ```text
21/// Parent (8 bytes total):
22/// ┌────────────────┬────────────────┐
23/// │  index (u32)   │ generation(u32)│  <- Entity
24/// └────────────────┴────────────────┘
25/// ```
26///
27/// # Example
28///
29/// ```
30/// use goud_engine::ecs::Entity;
31/// use goud_engine::ecs::components::Parent;
32///
33/// let parent_entity = Entity::new(0, 1);
34/// let parent_component = Parent::new(parent_entity);
35///
36/// assert_eq!(parent_component.get(), parent_entity);
37/// ```
38#[repr(C)]
39#[derive(Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
40pub struct Parent {
41    /// The parent entity.
42    entity: Entity,
43}
44
45impl Parent {
46    /// Creates a new Parent component pointing to the given entity.
47    ///
48    /// # Arguments
49    ///
50    /// * `parent` - The entity that should be this entity's parent
51    ///
52    /// # Example
53    ///
54    /// ```
55    /// use goud_engine::ecs::Entity;
56    /// use goud_engine::ecs::components::Parent;
57    ///
58    /// let parent_entity = Entity::new(42, 1);
59    /// let parent = Parent::new(parent_entity);
60    /// ```
61    #[inline]
62    pub const fn new(parent: Entity) -> Self {
63        Self { entity: parent }
64    }
65
66    /// Returns the parent entity.
67    ///
68    /// # Example
69    ///
70    /// ```
71    /// use goud_engine::ecs::Entity;
72    /// use goud_engine::ecs::components::Parent;
73    ///
74    /// let parent_entity = Entity::new(10, 2);
75    /// let parent = Parent::new(parent_entity);
76    ///
77    /// assert_eq!(parent.get(), parent_entity);
78    /// ```
79    #[inline]
80    pub const fn get(&self) -> Entity {
81        self.entity
82    }
83
84    /// Sets the parent entity.
85    ///
86    /// This allows changing the parent without removing and re-adding the component.
87    ///
88    /// # Arguments
89    ///
90    /// * `parent` - The new parent entity
91    ///
92    /// # Example
93    ///
94    /// ```
95    /// use goud_engine::ecs::Entity;
96    /// use goud_engine::ecs::components::Parent;
97    ///
98    /// let mut parent = Parent::new(Entity::new(0, 1));
99    /// parent.set(Entity::new(5, 1));
100    ///
101    /// assert_eq!(parent.get(), Entity::new(5, 1));
102    /// ```
103    #[inline]
104    pub fn set(&mut self, parent: Entity) {
105        self.entity = parent;
106    }
107}
108
109impl fmt::Debug for Parent {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        write!(f, "Parent({:?})", self.entity)
112    }
113}
114
115impl fmt::Display for Parent {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        write!(f, "Parent({})", self.entity)
118    }
119}
120
121impl Default for Parent {
122    /// Returns a Parent with PLACEHOLDER entity.
123    ///
124    /// This is primarily for initialization purposes. A valid parent should
125    /// be set before the entity is used in a hierarchy.
126    #[inline]
127    fn default() -> Self {
128        Self {
129            entity: Entity::PLACEHOLDER,
130        }
131    }
132}
133
134impl From<Entity> for Parent {
135    #[inline]
136    fn from(entity: Entity) -> Self {
137        Self::new(entity)
138    }
139}
140
141impl From<Parent> for Entity {
142    #[inline]
143    fn from(parent: Parent) -> Self {
144        parent.entity
145    }
146}
147
148// Implement Component trait
149impl Component for Parent {}