use crate::{AssetId, AssetLocation, AssetPathCache, DataSet, EditorModel};
use std::cmp::Ordering;
use std::collections::BTreeMap;
#[derive(Debug, PartialEq, Eq)]
pub struct LocationTreeNodeKey {
name: String,
location: AssetLocation,
}
impl LocationTreeNodeKey {
pub fn name(&self) -> &str {
&self.name
}
pub fn location(&self) -> &AssetLocation {
&self.location
}
}
impl PartialOrd<Self> for LocationTreeNodeKey {
fn partial_cmp(
&self,
other: &Self,
) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for LocationTreeNodeKey {
fn cmp(
&self,
other: &Self,
) -> Ordering {
match self.name.cmp(&other.name) {
Ordering::Less => Ordering::Less,
Ordering::Equal => self.location.cmp(&other.location),
Ordering::Greater => Ordering::Greater,
}
}
}
#[derive(Debug)]
pub struct LocationTreeNode {
pub location: AssetLocation,
pub location_root: AssetLocation,
pub children: BTreeMap<LocationTreeNodeKey, LocationTreeNode>,
pub has_changes: bool,
}
#[derive(Debug)]
pub struct LocationTree {
pub root_nodes: BTreeMap<LocationTreeNodeKey, LocationTreeNode>,
}
impl Default for LocationTree {
fn default() -> Self {
LocationTree {
root_nodes: Default::default(),
}
}
}
impl LocationTree {
pub fn create_node(
&mut self,
data_set: &DataSet,
tree_node_id: AssetId,
) {
let mut path_asset_stack = vec![AssetLocation::new(tree_node_id)];
path_asset_stack.append(
&mut data_set
.asset_location_chain(tree_node_id)
.unwrap_or_default(),
);
let root_location = path_asset_stack.last().cloned().unwrap(); let root_location_path_node_id = root_location.path_node_id();
let root_tree_node_key = LocationTreeNodeKey {
location: root_location.clone(),
name: data_set
.asset_name(root_location_path_node_id)
.unwrap()
.as_string()
.cloned()
.unwrap_or_default(),
};
path_asset_stack.pop();
if let Some(mut tree_node) = self.root_nodes.get_mut(&root_tree_node_key) {
while let Some(node_object) = path_asset_stack.pop() {
let node_name = data_set
.asset_name(node_object.path_node_id())
.unwrap()
.as_string()
.cloned()
.unwrap();
let node_key = LocationTreeNodeKey {
name: node_name,
location: node_object.clone(),
};
tree_node = tree_node.children.entry(node_key).or_insert_with(|| {
let has_changes = false; LocationTreeNode {
location: node_object,
location_root: root_location.clone(),
children: Default::default(),
has_changes,
}
});
}
} else {
}
}
pub fn build(
editor_model: &EditorModel,
asset_path_cache: &AssetPathCache,
) -> Self {
let data_sources = editor_model.data_sources();
let root_data_set = editor_model.root_edit_context().data_set();
let mut root_nodes: BTreeMap<LocationTreeNodeKey, LocationTreeNode> = Default::default();
for (source_id, _) in data_sources {
let location = AssetLocation::new(AssetId::from_uuid(*source_id.uuid()));
let name = root_data_set.asset_name(location.path_node_id()).unwrap();
root_nodes.insert(
LocationTreeNodeKey {
location: location.clone(),
name: name.as_string().cloned().unwrap_or_default(),
},
LocationTreeNode {
location,
location_root: AssetLocation::null(),
children: Default::default(),
has_changes: false,
},
);
}
let mut tree = LocationTree { root_nodes };
for (tree_node_id, _path) in asset_path_cache.path_to_id_lookup() {
tree.create_node(root_data_set, *tree_node_id);
}
tree
}
}