forked from rojo-rbx/rojo
fix_vfs_double_update (#616)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs,
|
||||||
|
path::PathBuf,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,46 +125,20 @@ impl JobThreadContext {
|
|||||||
|
|
||||||
// For a given VFS event, we might have many changes to different parts
|
// For a given VFS event, we might have many changes to different parts
|
||||||
// of the tree. Calculate and apply all of these changes.
|
// of the tree. Calculate and apply all of these changes.
|
||||||
let applied_patches = {
|
let applied_patches = match event {
|
||||||
let mut tree = self.tree.lock().unwrap();
|
VfsEvent::Write(path) => {
|
||||||
let mut applied_patches = Vec::new();
|
if path.is_dir() {
|
||||||
|
return;
|
||||||
match event {
|
|
||||||
VfsEvent::Create(path) | VfsEvent::Write(path) | VfsEvent::Remove(path) => {
|
|
||||||
// Find the nearest ancestor to this path that has
|
|
||||||
// associated instances in the tree. This helps make sure
|
|
||||||
// that we handle additions correctly, especially if we
|
|
||||||
// receive events for descendants of a large tree being
|
|
||||||
// created all at once.
|
|
||||||
let mut current_path = path.as_path();
|
|
||||||
let affected_ids = loop {
|
|
||||||
let ids = tree.get_ids_at_path(¤t_path);
|
|
||||||
|
|
||||||
log::trace!("Path {} affects IDs {:?}", current_path.display(), ids);
|
|
||||||
|
|
||||||
if !ids.is_empty() {
|
|
||||||
break ids.to_vec();
|
|
||||||
}
|
|
||||||
|
|
||||||
log::trace!("Trying parent path...");
|
|
||||||
match current_path.parent() {
|
|
||||||
Some(parent) => current_path = parent,
|
|
||||||
None => break Vec::new(),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for id in affected_ids {
|
|
||||||
if let Some(patch) = compute_and_apply_changes(&mut tree, &self.vfs, id) {
|
|
||||||
if !patch.is_empty() {
|
|
||||||
applied_patches.push(patch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => log::warn!("Unhandled VFS event: {:?}", event),
|
on_vfs_event(path, &self.tree, &self.vfs)
|
||||||
|
}
|
||||||
|
VfsEvent::Create(path) | VfsEvent::Remove(path) => {
|
||||||
|
on_vfs_event(path, &self.tree, &self.vfs)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
log::warn!("Unhandled VFS event: {:?}", event);
|
||||||
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
applied_patches
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Notify anyone listening to the message queue about the changes we
|
// Notify anyone listening to the message queue about the changes we
|
||||||
@@ -261,6 +236,45 @@ impl JobThreadContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the nearest ancestor to this path that has
|
||||||
|
// associated instances in the tree. This helps make sure
|
||||||
|
// that we handle additions correctly, especially if we
|
||||||
|
// receive events for descendants of a large tree being
|
||||||
|
// created all at once.
|
||||||
|
fn on_vfs_event(
|
||||||
|
path: PathBuf,
|
||||||
|
tree: &Arc<Mutex<RojoTree>>,
|
||||||
|
vfs: &Arc<Vfs>,
|
||||||
|
) -> Vec<AppliedPatchSet> {
|
||||||
|
let mut tree = tree.lock().unwrap();
|
||||||
|
let mut applied_patches = Vec::new();
|
||||||
|
|
||||||
|
let mut current_path = path.as_path();
|
||||||
|
let affected_ids = loop {
|
||||||
|
let ids = tree.get_ids_at_path(¤t_path);
|
||||||
|
|
||||||
|
log::trace!("Path {} affects IDs {:?}", current_path.display(), ids);
|
||||||
|
|
||||||
|
if !ids.is_empty() {
|
||||||
|
break ids.to_vec();
|
||||||
|
}
|
||||||
|
|
||||||
|
log::trace!("Trying parent path...");
|
||||||
|
match current_path.parent() {
|
||||||
|
Some(parent) => current_path = parent,
|
||||||
|
None => break Vec::new(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for id in affected_ids {
|
||||||
|
if let Some(patch) = compute_and_apply_changes(&mut tree, &vfs, id) {
|
||||||
|
if !patch.is_empty() {
|
||||||
|
applied_patches.push(patch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
applied_patches
|
||||||
|
}
|
||||||
fn compute_and_apply_changes(tree: &mut RojoTree, vfs: &Vfs, id: Ref) -> Option<AppliedPatchSet> {
|
fn compute_and_apply_changes(tree: &mut RojoTree, vfs: &Vfs, id: Ref) -> Option<AppliedPatchSet> {
|
||||||
let metadata = tree
|
let metadata = tree
|
||||||
.get_metadata(id)
|
.get_metadata(id)
|
||||||
|
|||||||
Reference in New Issue
Block a user