diff --git a/src/change_processor.rs b/src/change_processor.rs index ac9cb869..f3902067 100644 --- a/src/change_processor.rs +++ b/src/change_processor.rs @@ -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>, + vfs: &Arc, +) -> Vec { + 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 { let metadata = tree .get_metadata(id)