diff options
author | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2020-08-29 22:06:19 -0400 |
---|---|---|
committer | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2020-08-29 22:08:23 -0400 |
commit | 5be4a5f472655a76e1430bad09a19f6ad111e474 (patch) | |
tree | 1fcffa6c8d37cc6d538b29b6fbd773e8de58512d /src/context | |
parent | 4f3842b56f1729dcd8e81c77f98253ed9dfb23b3 (diff) |
big rework and dependency update
- abstract JoshutoContext implementation behind functions
- rework io workers in an attempt to fix a bug
- update dependencies
- remove JoshutoContextWorker
Diffstat (limited to 'src/context')
-rw-r--r-- | src/context/context.rs | 125 | ||||
-rw-r--r-- | src/context/local_state.rs | 29 | ||||
-rw-r--r-- | src/context/mod.rs | 7 | ||||
-rw-r--r-- | src/context/tab_context.rs | 70 |
4 files changed, 231 insertions, 0 deletions
diff --git a/src/context/context.rs b/src/context/context.rs new file mode 100644 index 0000000..c39bd8e --- /dev/null +++ b/src/context/context.rs @@ -0,0 +1,125 @@ +use std::collections::VecDeque; +use std::sync::mpsc; +use std::thread; + +use crate::config; +use crate::context::{LocalStateContext, TabContext}; +use crate::io::{IOWorkerObserver, IOWorkerThread}; +use crate::util::event::{Event, Events}; + +pub struct JoshutoContext { + pub exit: bool, + pub config_t: config::JoshutoConfig, + local_state: Option<LocalStateContext>, + tab_context: TabContext, + pub events: Events, + pub message_queue: VecDeque<String>, + worker_queue: VecDeque<IOWorkerThread>, + worker: Option<IOWorkerObserver>, +} + +impl JoshutoContext { + pub fn new(config_t: config::JoshutoConfig) -> Self { + Self { + exit: false, + local_state: None, + tab_context: TabContext::default(), + message_queue: VecDeque::with_capacity(4), + events: Events::new(), + worker_queue: VecDeque::new(), + worker: None, + config_t, + } + } + + pub fn tab_context_ref(&self) -> &TabContext { + &self.tab_context + } + pub fn tab_context_mut(&mut self) -> &mut TabContext { + &mut self.tab_context + } + + pub fn push_msg(&mut self, msg: String) { + self.message_queue.push_back(msg); + } + + // event related + pub fn poll_event(&self) -> Result<Event, mpsc::RecvError> { + self.events.next() + } + pub fn get_event_tx(&self) -> mpsc::Sender<Event> { + self.events.event_tx.clone() + } + pub fn flush_event(&self) { + self.events.flush(); + } + + // local state related + pub fn set_local_state(&mut self, state: LocalStateContext) { + self.local_state = Some(state); + } + pub fn get_local_state(&self) -> Option<&LocalStateContext> { + self.local_state.as_ref() + } + pub fn take_local_state(&mut self) -> Option<LocalStateContext> { + self.local_state.take() + } + + // worker related + pub fn add_worker(&mut self, thread: IOWorkerThread) { + self.worker_queue.push_back(thread); + } + pub fn worker_is_busy(&self) -> bool { + self.worker.is_some() + } + pub fn worker_len(&self) -> usize { + self.worker_queue.len() + } + pub fn worker_is_empty(&self) -> bool { + self.worker_queue.is_empty() + } + pub fn set_worker_msg(&mut self, msg: String) { + if let Some(s) = self.worker.as_mut() { + s.set_msg(msg); + } + } + pub fn worker_msg(&self) -> Option<&String> { + self.worker.as_ref().and_then(|s| s.get_msg()) + } + + pub fn start_next_job(&mut self) { + let tx = self.get_event_tx(); + + if let Some(worker) = self.worker_queue.pop_front() { + let src = worker.paths[0].clone(); + let dest = worker.dest.clone(); + let file_op = worker.options.kind; + let handle = thread::spawn(move || { + let (wtx, wrx) = mpsc::channel(); + // start worker + let worker_handle = thread::spawn(move || worker.start(wtx)); + // relay worker info to event loop + while let Ok(progress) = wrx.recv() { + tx.send(Event::IOWorkerProgress((file_op, progress))); + } + let result = worker_handle.join(); + match result { + Ok(res) => { + let _ = tx.send(Event::IOWorkerResult((file_op, res))); + } + Err(e) => { + let err = std::io::Error::new(std::io::ErrorKind::Other, + "Sending Error"); + let _ = tx.send(Event::IOWorkerResult((file_op, Err(err)))); + } + } + }); + let observer = IOWorkerObserver::new(handle, src, dest); + self.worker = Some(observer); + } + } + + pub fn remove_job(&mut self) -> Option<IOWorkerObserver> { + self.worker.take() + } +} diff --git a/src/context/local_state.rs b/src/context/local_state.rs new file mode 100644 index 0000000..6bb8d00 --- /dev/null +++ b/src/context/local_state.rs @@ -0,0 +1,29 @@ +use crate::io::FileOp; + +use std::iter::Iterator; +use std::path; + +pub struct LocalStateContext { + pub paths: Vec<path::PathBuf>, + pub file_op: FileOp, +} + +impl LocalStateContext { + pub fn new() -> Self { + Self { + paths: Vec::new(), + file_op: FileOp::Copy, + } + } + + pub fn set_file_op(&mut self, operation: FileOp) { + self.file_op = operation; + } + + pub fn set_paths<'a, I>(&mut self, vals: I) + where + I: Iterator<Item = &'a path::Path>, + { + self.paths = vals.map(|p| p.to_path_buf()).collect(); + } +} diff --git a/src/context/mod.rs b/src/context/mod.rs new file mode 100644 index 0000000..f5d4ce0 --- /dev/null +++ b/src/context/mod.rs @@ -0,0 +1,7 @@ +mod context; +mod local_state; +mod tab_context; + +pub use self::context::*; +pub use self::local_state::LocalStateContext; +pub use self::tab_context::*; diff --git a/src/context/tab_context.rs b/src/context/tab_context.rs new file mode 100644 index 0000000..272e356 --- /dev/null +++ b/src/context/tab_context.rs @@ -0,0 +1,70 @@ +use crate::tab::JoshutoTab; + +use std::slice::{Iter, IterMut}; + +pub struct TabContext { + index: usize, + tabs: Vec<JoshutoTab>, +} + +impl std::default::Default for TabContext { + fn default() -> Self { + Self { + index: 0, + tabs: Vec::new(), + } + } +} + +impl TabContext { + pub fn new() -> Self { + Self::default() + } + + pub fn get_index(&self) -> usize { + self.index + } + + pub fn set_index(&mut self, index: usize) { + self.index = index; + } + + pub fn len(&self) -> usize { + self.tabs.len() + } + + pub fn tab_ref(&self, i: usize) -> Option<&JoshutoTab> { + if i >= self.tabs.len() { + return None; + } + Some(&self.tabs[i]) + } + pub fn tab_mut(&mut self, i: usize) -> Option<&mut JoshutoTab> { + if i >= self.tabs.len() { + return None; + } + Some(&mut self.tabs[i]) + } + + pub fn curr_tab_ref(&self) -> &JoshutoTab { + &self.tabs[self.index] + } + pub fn curr_tab_mut(&mut self) -> &mut JoshutoTab { + &mut self.tabs[self.index] + } + pub fn push_tab(&mut self, tab: JoshutoTab) { + self.tabs.push(tab); + self.index = self.tabs.len() - 1; + } + pub fn pop_tab(&mut self, index: usize) -> JoshutoTab { + self.tabs.remove(index) + } + + pub fn iter(&self) -> Iter<JoshutoTab> { + self.tabs.iter() + } + + pub fn iter_mut(&mut self) -> IterMut<JoshutoTab> { + self.tabs.iter_mut() + } +} |