diff options
-rw-r--r-- | src/devices/file.rs | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/devices/file.rs b/src/devices/file.rs index bf185d7..0bea2f4 100644 --- a/src/devices/file.rs +++ b/src/devices/file.rs @@ -13,6 +13,7 @@ pub use entry::*; use operations::*; use std::path::{Component, Path, PathBuf}; +use std::mem::take; pub struct FileDevice { @@ -24,6 +25,7 @@ pub struct FileDevice { pub name_buffer: CircularPathBuffer, pub entry: Option<(Entry, BedrockFilePath)>, + pub cached_dir: Option<(Entry, BedrockFilePath)>, pub success: bool, pub pointer: u32, @@ -55,6 +57,7 @@ impl FileDevice { name_buffer: CircularPathBuffer::new(), entry: None, + cached_dir: None, success: false, pointer: 0, @@ -81,9 +84,11 @@ impl FileDevice { self.move_buffer.clear(); self.name_buffer.clear(); self.flush_entry(); - self.entry = None; self.pointer = 0; self.length = 0; + if let Some((Entry::Directory(dir), path)) = take(&mut self.entry) { + self.cached_dir = Some((Entry::Directory(dir), path)); + } } /// Process a byte received from the OPEN port. @@ -113,6 +118,15 @@ impl FileDevice { }; } Some(EntryType::Directory) => { + // Attempt to use the cached directory. + if let Some((dir, cached_path)) = take(&mut self.cached_dir) { + if cached_path == path { + self.close_entry(); + self.name_buffer.populate(cached_path.as_buffer()); + self.entry = Some((dir, cached_path)); + return Ok(()); + } + } // Keep the current entry open if we can't open the new path. if let Some(listing) = DirectoryListing::from_path(&path) { self.close_entry(); @@ -242,7 +256,7 @@ impl FileDevice { } pub fn commit_pointer(&mut self) { - let pointer = std::mem::take(&mut self.pointer); + let pointer = take(&mut self.pointer); match &mut self.entry { Some((Entry::File(buffered_file), _)) => buffered_file.set_pointer(pointer), Some((Entry::Directory(listing), _)) => listing.set_selected(pointer), @@ -259,7 +273,7 @@ impl FileDevice { } pub fn commit_length(&mut self) { - let length = std::mem::take(&mut self.length); + let length = take(&mut self.length); match &mut self.entry { Some((Entry::File(buffered_file), _)) => buffered_file.set_length(length), _ => (), |