Fix group creation parenting (#455)

* WIP fix of folder crash / indent

* Fixed most crashes

* Known cases of crash / incorrect behavior resolved

* Removed todo & readability tweak

* Removed left over test

* Resolved clippy issue resulting from merging master

* Replace recursive tree traversal with prefix matching

* Reverted changes for #453 and added undo functionality to Paste

* Make uuid generator thread local for tests

* Maintain layer order, test still failing 50% of the time

* Reverting back to known working with the knowledge we can optimize later.

This reverts commit 1aaf5c0d7d.

* Revert "Make uuid generator thread local for tests"

This reverts commit d68e3b9c4e.

* Revert "Reverted changes for #453 and added undo functionality to Paste"

This reverts commit d66992ac94.

* Revert "Replace recursive tree traversal with prefix matching"

This reverts commit 6bcbb9f82f.

* Reverted to working state and added comment back to optimized commit hash

* Re-removed the changes involving #453

Co-authored-by: Dennis <dennis@kobert.dev>
This commit is contained in:
Oliver Davies
2022-01-04 19:18:28 -08:00
committed by Keavon Chambers
co-authored by Dennis
parent a805120638
commit f63d428d32
5 changed files with 77 additions and 30 deletions
+17 -13
View File
@@ -61,7 +61,7 @@ impl Document {
pub fn folder(&self, path: &[LayerId]) -> Result<&Folder, DocumentError> {
let mut root = &self.root;
for id in path {
root = root.as_folder()?.layer(*id).ok_or(DocumentError::LayerNotFound)?;
root = root.as_folder()?.layer(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
}
root.as_folder()
}
@@ -72,7 +72,7 @@ impl Document {
fn folder_mut(&mut self, path: &[LayerId]) -> Result<&mut Folder, DocumentError> {
let mut root = &mut self.root;
for id in path {
root = root.as_folder_mut()?.layer_mut(*id).ok_or(DocumentError::LayerNotFound)?;
root = root.as_folder_mut()?.layer_mut(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
}
root.as_folder_mut()
}
@@ -83,7 +83,7 @@ impl Document {
return Ok(&self.root);
}
let (path, id) = split_path(path)?;
self.folder(path)?.layer(id).ok_or(DocumentError::LayerNotFound)
self.folder(path)?.layer(id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))
}
/// Returns a mutable reference to the layer or folder at the path.
@@ -92,10 +92,10 @@ impl Document {
return Ok(&mut self.root);
}
let (path, id) = split_path(path)?;
self.folder_mut(path)?.layer_mut(id).ok_or(DocumentError::LayerNotFound)
self.folder_mut(path)?.layer_mut(id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))
}
pub fn deepest_common_folder<'a>(&self, layers: impl Iterator<Item = &'a [LayerId]>) -> Result<&'a [LayerId], DocumentError> {
pub fn shallowest_common_folder<'a>(&self, layers: impl Iterator<Item = &'a [LayerId]>) -> Result<&'a [LayerId], DocumentError> {
let common_prefix_of_path = self.common_layer_path_prefix(layers);
Ok(match self.layer(common_prefix_of_path)?.data {
@@ -113,6 +113,10 @@ impl Document {
.unwrap_or_default()
}
pub fn is_folder(&self, path: &[LayerId]) -> bool {
return self.folder(path).is_ok();
}
// Determines which layer is closer to the root, if path_a return true, if path_b return false
// Answers the question: Is A closer to the root than B?
pub fn layer_closer_to_root(&self, path_a: &[u64], path_b: &[u64]) -> bool {
@@ -136,9 +140,9 @@ impl Document {
false
}
// Is the target layer between a <-> b layers, inclusive
// Is the target layer between a <-> b layers, inclusive
pub fn layer_is_between(&self, target: &[u64], path_a: &[u64], path_b: &[u64]) -> bool {
// If the target is a nonsense path, it isn't between
// If the target is the root, it isn't between
if target.is_empty() {
return false;
}
@@ -165,12 +169,12 @@ impl Document {
// TODO: appears to be n^2? should we maintain a lookup table?
for id in path {
let pos = root.layer_ids.iter().position(|x| *x == *id).ok_or(DocumentError::LayerNotFound)?;
let pos = root.layer_ids.iter().position(|x| *x == *id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
indices.push(pos);
root = root.folder(*id).ok_or(DocumentError::LayerNotFound)?;
root = root.folder(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
}
indices.push(root.layer_ids.iter().position(|x| *x == layer_id).ok_or(DocumentError::LayerNotFound)?);
indices.push(root.layer_ids.iter().position(|x| *x == layer_id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?);
Ok(indices)
}
@@ -264,7 +268,7 @@ impl Document {
let mut root = &mut self.root;
root.cache_dirty = true;
for id in path {
root = root.as_folder_mut()?.layer_mut(*id).ok_or(DocumentError::LayerNotFound)?;
root = root.as_folder_mut()?.layer_mut(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
root.cache_dirty = true;
}
Ok(())
@@ -297,7 +301,7 @@ impl Document {
let mut transforms = vec![self.root.transform];
for id in path {
if let Ok(folder) = root.as_folder() {
root = folder.layer(*id).ok_or(DocumentError::LayerNotFound)?;
root = folder.layer(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
}
transforms.push(root.transform);
}
@@ -309,7 +313,7 @@ impl Document {
let mut trans = self.root.transform;
for id in path {
if let Ok(folder) = root.as_folder() {
root = folder.layer(*id).ok_or(DocumentError::LayerNotFound)?;
root = folder.layer(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
}
trans = trans * root.transform;
}
+5 -1
View File
@@ -101,8 +101,12 @@ impl Folder {
Some(&mut self.layers[pos])
}
pub fn folder_contains(&self, id: LayerId) -> bool {
self.layer_ids.contains(&id)
}
pub fn position_of_layer(&self, layer_id: LayerId) -> Result<usize, DocumentError> {
self.layer_ids.iter().position(|x| *x == layer_id).ok_or(DocumentError::LayerNotFound)
self.layer_ids.iter().position(|x| *x == layer_id).ok_or_else(|| DocumentError::LayerNotFound([layer_id].into()))
}
pub fn folder(&self, id: LayerId) -> Option<&Folder> {
+1 -1
View File
@@ -14,7 +14,7 @@ pub type LayerId = u64;
#[derive(Debug, Clone, PartialEq)]
pub enum DocumentError {
LayerNotFound,
LayerNotFound(Vec<LayerId>),
InvalidPath,
IndexOutOfBounds,
NotAFolder,