Skip to main content

rbx_rsml/compiler/
tree_node.rs

1use std::collections::HashMap;
2use std::mem;
3use std::ops::{Index, IndexMut};
4
5use rbx_types::Attributes;
6
7use crate::datatype::Datatype;
8
9#[derive(Clone, PartialEq, Copy, Eq, Debug, Hash)]
10pub enum TreeNodeType {
11    Root,
12    Node(usize),
13}
14
15#[derive(Debug)]
16pub struct RootTreeNode {
17    pub attributes: Attributes,
18    pub static_attributes: HashMap<String, Datatype>,
19    pub child_rules: Vec<usize>,
20}
21
22impl RootTreeNode {
23    pub fn new() -> Self {
24        Self {
25            attributes: Attributes::new(),
26            static_attributes: HashMap::new(),
27            child_rules: vec![],
28        }
29    }
30}
31
32#[derive(Debug)]
33pub struct TreeNode {
34    pub selector: Option<String>,
35    pub priority: Option<i32>,
36    pub attributes: Attributes,
37    pub static_attributes: HashMap<String, Datatype>,
38    pub properties: Attributes,
39    pub tweens: Attributes,
40    pub child_rules: Vec<usize>,
41    pub parent: TreeNodeType,
42}
43
44impl TreeNode {
45    pub fn new(parent: TreeNodeType, selector: Option<String>) -> Self {
46        Self {
47            attributes: Attributes::new(),
48            static_attributes: HashMap::new(),
49            properties: Attributes::new(),
50            tweens: Attributes::new(),
51            child_rules: vec![],
52            priority: None,
53            selector,
54            parent,
55        }
56    }
57}
58
59pub enum AnyTreeNode<'a> {
60    Node(Option<&'a TreeNode>),
61    Root(Option<&'a RootTreeNode>),
62}
63
64pub enum AnyTreeNodeMut<'a> {
65    Node(Option<&'a mut TreeNode>),
66    Root(Option<&'a mut RootTreeNode>),
67}
68
69#[derive(Debug)]
70pub struct CompiledRsml {
71    root: Option<RootTreeNode>,
72    nodes: Vec<Option<TreeNode>>,
73}
74
75impl CompiledRsml {
76    pub fn new() -> Self {
77        Self {
78            root: Some(RootTreeNode::new()),
79            nodes: vec![],
80        }
81    }
82
83    pub fn get(&self, idx: TreeNodeType) -> AnyTreeNode<'_> {
84        match idx {
85            TreeNodeType::Node(idx) => AnyTreeNode::Node(self.nodes[idx].as_ref()),
86            TreeNodeType::Root => AnyTreeNode::Root(self.root.as_ref()),
87        }
88    }
89
90    pub fn nodes_len(&self) -> usize {
91        self.nodes.len()
92    }
93
94    pub fn get_root(&self) -> Option<&RootTreeNode> {
95        self.root.as_ref()
96    }
97
98    pub fn get_node_mut(&mut self, idx: TreeNodeType) -> AnyTreeNodeMut<'_> {
99        match idx {
100            TreeNodeType::Node(idx) => AnyTreeNodeMut::Node(self.nodes[idx].as_mut()),
101            TreeNodeType::Root => AnyTreeNodeMut::Root(self.root.as_mut()),
102        }
103    }
104
105    pub fn get_root_mut(&mut self) -> Option<&mut RootTreeNode> {
106        self.root.as_mut()
107    }
108
109    pub fn add_node(&mut self, tree_node: TreeNode) {
110        self.nodes.push(Some(tree_node));
111    }
112
113    pub fn take_node(&mut self, idx: usize) -> Option<TreeNode> {
114        mem::replace(&mut self.nodes[idx], None)
115    }
116
117    pub fn take_root(&mut self) -> Option<RootTreeNode> {
118        mem::replace(&mut self.root, None)
119    }
120}
121
122impl Index<usize> for CompiledRsml {
123    type Output = Option<TreeNode>;
124
125    fn index(&self, index: usize) -> &Self::Output {
126        &self.nodes[index]
127    }
128}
129
130impl IndexMut<usize> for CompiledRsml {
131    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
132        &mut self.nodes[index]
133    }
134}