1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use std::marker::PhantomData;

use hecs::{Entity, View};
use hecs_schedule::{error::Result, GenericWorld};

/// Component of a entity with descendents in hierarchy tree `T`.
/// Children represent a circular linked list. Since `Parent` and child is generic over a marker
/// type, several hierarchies can coexist.
pub struct Parent<T> {
    pub(crate) num_children: usize,
    pub(crate) last_child: Entity,
    marker: PhantomData<T>,
}

impl<T: 'static + Send + Sync> Parent<T> {
    pub(crate) fn new(num_children: usize, last_child: Entity) -> Self {
        Self {
            num_children,
            last_child,
            marker: PhantomData,
        }
    }

    /// Return the parent's num children.
    pub fn num_children(&self) -> usize {
        self.num_children
    }

    /// Query the parent's first child.
    pub fn first_child<W: GenericWorld>(&self, world: &W) -> Result<Entity> {
        Ok(world.try_get::<Child<T>>(self.last_child)?.next)
    }

    /// Query the parent's first child.
    pub fn view_first_child(&self, view: &View<&Child<T>>) -> Result<Entity> {
        Ok(view
            .get(self.last_child)
            .ok_or_else(|| hecs_schedule::Error::NoSuchEntity(self.last_child))?
            .next)
    }
    /// Return the parent's last child.
    pub fn last_child(&self) -> Entity {
        self.last_child
    }
}

impl<T> std::fmt::Debug for Parent<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Parent")
            .field("num_children", &self.num_children)
            .field("last_child", &self.last_child)
            .finish()
    }
}

/// Component of a child entity in hierarchy tree `T`.
/// Children represent a circular linked list. Since `Parent` and child is generic over a marker
/// type, several hierarchies can coexist.
pub struct Child<T> {
    pub(crate) parent: Entity,
    pub(crate) next: Entity,
    pub(crate) prev: Entity,
    marker: PhantomData<T>,
}

impl<T> Child<T> {
    pub(crate) fn new(parent: Entity, next: Entity, prev: Entity) -> Self {
        Self {
            parent,
            next,
            prev,
            marker: PhantomData,
        }
    }
}

impl<T> std::fmt::Debug for Child<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Child")
            .field("parent", &self.parent)
            .field("next", &self.next)
            .field("prev", &self.prev)
            .finish()
    }
}