diff --git a/server/src/file_route.rs b/server/src/file_route.rs index c114857d..8ebc2470 100644 --- a/server/src/file_route.rs +++ b/server/src/file_route.rs @@ -1,4 +1,4 @@ -use std::path::{Path, PathBuf}; +use std::path::{Path, PathBuf, Component}; use partition::Partition; @@ -9,9 +9,25 @@ pub struct FileRoute { } impl FileRoute { - pub fn from_path(path: &Path, partition: &Partition) -> FileRoute { - // TODO: Needed for PartitionWatcher to changes onto FileRoute - unimplemented!() + pub fn from_path(path: &Path, partition: &Partition) -> Option { + assert!(path.is_absolute()); + + let relative_path = path.strip_prefix(&partition.path).ok()?; + let mut route = Vec::new(); + + for component in relative_path.components() { + match component { + Component::Normal(piece) => { + route.push(piece.to_string_lossy().into_owned()); + }, + _ => panic!("Unexpected path component: {:?}", component), + } + } + + Some(FileRoute { + partition: partition.name.clone(), + route, + }) } /// Creates a PathBuf out of the `FileRoute` based on the given partition diff --git a/server/src/partition_watcher.rs b/server/src/partition_watcher.rs index f147954b..2f9785e7 100644 --- a/server/src/partition_watcher.rs +++ b/server/src/partition_watcher.rs @@ -1,32 +1,54 @@ -use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::mpsc::{channel, Sender}; use std::time::Duration; use std::thread; use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher, watcher}; use partition::Partition; +use vfs_session::FileChange; +use file_route::FileRoute; pub struct PartitionWatcher { pub watcher: RecommendedWatcher, - pub partition: Partition, } impl PartitionWatcher { - pub fn start_new(partition: Partition, tx: Sender<(String, DebouncedEvent)>) -> PartitionWatcher { + pub fn start_new(partition: Partition, tx: Sender) -> PartitionWatcher { let (watch_tx, watch_rx) = channel(); let mut watcher = watcher(watch_tx, Duration::from_millis(100)).unwrap(); watcher.watch(&partition.path, RecursiveMode::Recursive).unwrap(); - let partition_name = partition.name.clone(); thread::spawn(move || { loop { match watch_rx.recv() { - // TODO: Transform DebouncedEvent to some sort of FileChange object - Ok(event) => match tx.send((partition_name.clone(), event)) { - Ok(_) => {}, - Err(_) => break, + Ok(event) => { + let file_change = match event { + DebouncedEvent::Create(path) => { + let route = FileRoute::from_path(&path, &partition).unwrap(); + FileChange::Created(route) + }, + DebouncedEvent::Write(path) => { + let route = FileRoute::from_path(&path, &partition).unwrap(); + FileChange::Updated(route) + }, + DebouncedEvent::Remove(path) => { + let route = FileRoute::from_path(&path, &partition).unwrap(); + FileChange::Deleted(route) + }, + DebouncedEvent::Rename(from_path, to_path) => { + let from_route = FileRoute::from_path(&from_path, &partition).unwrap(); + let to_route = FileRoute::from_path(&to_path, &partition).unwrap(); + FileChange::Moved(from_route, to_route) + }, + _ => continue, + }; + + match tx.send(file_change) { + Ok(_) => {}, + Err(_) => break, + } }, Err(_) => break, }; @@ -34,7 +56,6 @@ impl PartitionWatcher { }); PartitionWatcher { - partition, watcher, } } diff --git a/server/src/session.rs b/server/src/session.rs index 12244b28..0cc0d0cb 100644 --- a/server/src/session.rs +++ b/server/src/session.rs @@ -3,7 +3,6 @@ use std::sync::{mpsc, Arc, RwLock}; use std::thread; use id::{Id, get_id}; -use file_route::FileRoute; use partition::Partition; use rbx::RbxInstance; use rbx_session::RbxSession; @@ -90,16 +89,20 @@ impl Session { self.watchers.push(watcher); } - thread::spawn(move || { - loop { - match rx.recv() { - Ok((partition_name, change)) => { - println!("Got change {:?} on partition {}", change, partition_name); - }, - Err(_) => break, + { + let vfs_session = self.vfs_session.clone(); + thread::spawn(move || { + loop { + match rx.recv() { + Ok(change) => { + let mut vfs_session = vfs_session.write().unwrap(); + vfs_session.handle_change(change); + }, + Err(_) => break, + } } - } - }); + }); + } } pub fn get_vfs_session(&self) -> Arc> { diff --git a/server/src/vfs_session.rs b/server/src/vfs_session.rs index cf50e115..fdda63ec 100644 --- a/server/src/vfs_session.rs +++ b/server/src/vfs_session.rs @@ -18,11 +18,12 @@ pub enum FileItem { }, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub enum FileChange { - Created, - Deleted, - Modified, + Created(FileRoute), + Deleted(FileRoute), + Updated(FileRoute), + Moved(FileRoute, FileRoute), } pub struct VfsSession { @@ -53,8 +54,8 @@ impl VfsSession { } } - pub fn handle_change(&mut self, route: &FileRoute, change: FileChange) { - // TODO: Update in-memory files + pub fn handle_change(&mut self, change: FileChange) { + println!("Got change {:?}", change); } fn read(&self, route: &FileRoute) -> Result {