hydrate_model/editor/
location_tree.rs1use crate::{AssetId, AssetLocation, AssetPathCache, DataSet, EditorModel};
2use std::cmp::Ordering;
3use std::collections::BTreeMap;
4
5#[derive(Debug, PartialEq, Eq)]
6pub struct LocationTreeNodeKey {
7 name: String,
8 location: AssetLocation,
9}
10
11impl LocationTreeNodeKey {
12 pub fn name(&self) -> &str {
13 &self.name
14 }
15
16 pub fn location(&self) -> &AssetLocation {
17 &self.location
18 }
19}
20
21impl PartialOrd<Self> for LocationTreeNodeKey {
22 fn partial_cmp(
23 &self,
24 other: &Self,
25 ) -> Option<Ordering> {
26 Some(self.cmp(other))
27 }
28}
29
30impl Ord for LocationTreeNodeKey {
31 fn cmp(
32 &self,
33 other: &Self,
34 ) -> Ordering {
35 match self.name.cmp(&other.name) {
36 Ordering::Less => Ordering::Less,
37 Ordering::Equal => self.location.cmp(&other.location),
38 Ordering::Greater => Ordering::Greater,
39 }
40 }
41}
42
43#[derive(Debug)]
44pub struct LocationTreeNode {
45 pub location: AssetLocation,
47 pub location_root: AssetLocation,
48 pub children: BTreeMap<LocationTreeNodeKey, LocationTreeNode>,
49 pub has_changes: bool,
50}
51
52#[derive(Debug)]
53pub struct LocationTree {
54 pub root_nodes: BTreeMap<LocationTreeNodeKey, LocationTreeNode>,
55}
56
57impl Default for LocationTree {
58 fn default() -> Self {
59 LocationTree {
60 root_nodes: Default::default(),
61 }
62 }
63}
64
65impl LocationTree {
66 pub fn create_node(
67 &mut self,
68 data_set: &DataSet,
69 tree_node_id: AssetId,
70 ) {
71 let mut path_asset_stack = vec![AssetLocation::new(tree_node_id)];
72 path_asset_stack.append(
73 &mut data_set
74 .asset_location_chain(tree_node_id)
75 .unwrap_or_default(),
76 );
77
78 let root_location = path_asset_stack.last().cloned().unwrap(); let root_location_path_node_id = root_location.path_node_id();
84
85 let root_tree_node_key = LocationTreeNodeKey {
86 location: root_location.clone(),
87 name: data_set
88 .asset_name(root_location_path_node_id)
89 .unwrap()
90 .as_string()
91 .cloned()
92 .unwrap_or_default(),
93 };
94
95 path_asset_stack.pop();
96
97 if let Some(mut tree_node) = self.root_nodes.get_mut(&root_tree_node_key) {
98 while let Some(node_object) = path_asset_stack.pop() {
99 let node_name = data_set
104 .asset_name(node_object.path_node_id())
105 .unwrap()
106 .as_string()
107 .cloned()
108 .unwrap(); let node_key = LocationTreeNodeKey {
111 name: node_name,
112 location: node_object.clone(),
113 };
114
115 tree_node = tree_node.children.entry(node_key).or_insert_with(|| {
116 let has_changes = false; LocationTreeNode {
121 location: node_object,
124 location_root: root_location.clone(),
125 children: Default::default(),
126 has_changes,
127 }
128 });
129 }
130 } else {
131 }
133 }
134
135 pub fn build(
136 editor_model: &EditorModel,
137 asset_path_cache: &AssetPathCache,
138 ) -> Self {
139 let data_sources = editor_model.data_sources();
140 let root_data_set = editor_model.root_edit_context().data_set();
141
142 let mut root_nodes: BTreeMap<LocationTreeNodeKey, LocationTreeNode> = Default::default();
144 for (source_id, _) in data_sources {
145 let location = AssetLocation::new(AssetId::from_uuid(*source_id.uuid()));
146 let name = root_data_set.asset_name(location.path_node_id()).unwrap();
147 root_nodes.insert(
148 LocationTreeNodeKey {
149 location: location.clone(),
150 name: name.as_string().cloned().unwrap_or_default(),
151 },
152 LocationTreeNode {
153 location,
154 location_root: AssetLocation::null(),
155 children: Default::default(),
156 has_changes: false,
157 },
158 );
159 }
160
161 let mut tree = LocationTree { root_nodes };
162
163 for (tree_node_id, _path) in asset_path_cache.path_to_id_lookup() {
165 tree.create_node(root_data_set, *tree_node_id);
167 }
168
169 tree
170 }
171}