mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 20:55:50 +00:00
fix_vfs_double_update (#616)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use std::{
|
||||
fs,
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
@@ -124,46 +125,20 @@ impl JobThreadContext {
|
||||
|
||||
// For a given VFS event, we might have many changes to different parts
|
||||
// of the tree. Calculate and apply all of these changes.
|
||||
let applied_patches = {
|
||||
let mut tree = self.tree.lock().unwrap();
|
||||
let mut applied_patches = Vec::new();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
let applied_patches = match event {
|
||||
VfsEvent::Write(path) => {
|
||||
if path.is_dir() {
|
||||
return;
|
||||
}
|
||||
_ => 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
|
||||
@@ -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> {
|
||||
let metadata = tree
|
||||
.get_metadata(id)
|
||||
|
||||
Reference in New Issue
Block a user