hassium_core/
hierarchy.rs

1use crate::state::StateToken;
2use specs::{Component, Entity, FlaggedStorage, VecStorage, World};
3use specs_hierarchy::Hierarchy;
4use std::{borrow::Cow, collections::HashSet};
5
6pub fn hierarchy_find(mut root: Entity, path: &str, world: &World) -> Option<Entity> {
7    let hierarchy = world.read_resource::<HierarchyRes>();
8    let names = world.read_storage::<Name>();
9    for part in path.split('/') {
10        match part {
11            "" | "." => {}
12            ".." => {
13                if let Some(parent) = hierarchy.parent(root) {
14                    root = parent;
15                } else {
16                    return None;
17                }
18            }
19            part => {
20                let found = hierarchy.children(root).iter().find_map(|child| {
21                    if let Some(name) = names.get(*child) {
22                        if name.0 == part {
23                            Some(child)
24                        } else {
25                            None
26                        }
27                    } else {
28                        None
29                    }
30                });
31                if let Some(child) = found {
32                    root = *child;
33                } else {
34                    return None;
35                }
36            }
37        }
38    }
39    Some(root)
40}
41
42pub type HierarchyRes = Hierarchy<Parent>;
43
44#[derive(Default)]
45pub struct HierarchyChangeRes {
46    pub(crate) entities: HashSet<Entity>,
47    pub(crate) added: Vec<Entity>,
48    pub(crate) removed: Vec<Entity>,
49}
50
51impl HierarchyChangeRes {
52    #[inline]
53    pub fn added(&self) -> &[Entity] {
54        &self.added
55    }
56
57    #[inline]
58    pub fn removed(&self) -> &[Entity] {
59        &self.removed
60    }
61}
62
63#[derive(Debug, Clone, Eq, Ord, PartialEq, PartialOrd)]
64pub struct Parent(pub Entity);
65
66impl Component for Parent {
67    type Storage = FlaggedStorage<Self, VecStorage<Self>>;
68}
69
70impl specs_hierarchy::Parent for Parent {
71    fn parent_entity(&self) -> Entity {
72        self.0
73    }
74}
75
76#[derive(Debug, Clone)]
77pub struct Tag(pub Cow<'static, str>);
78
79impl Component for Tag {
80    type Storage = VecStorage<Self>;
81}
82
83#[derive(Debug, Clone)]
84pub struct Name(pub Cow<'static, str>);
85
86impl Component for Name {
87    type Storage = VecStorage<Self>;
88}
89
90#[derive(Debug, Clone)]
91pub struct NonPersistent(pub StateToken);
92
93impl Component for NonPersistent {
94    type Storage = VecStorage<Self>;
95}