summaryrefslogtreecommitdiffstats
path: root/src/context
diff options
context:
space:
mode:
authorJiayi Zhao <jeff.no.zhao@gmail.com>2020-08-29 22:06:19 -0400
committerJiayi Zhao <jeff.no.zhao@gmail.com>2020-08-29 22:08:23 -0400
commit5be4a5f472655a76e1430bad09a19f6ad111e474 (patch)
tree1fcffa6c8d37cc6d538b29b6fbd773e8de58512d /src/context
parent4f3842b56f1729dcd8e81c77f98253ed9dfb23b3 (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.rs125
-rw-r--r--src/context/local_state.rs29
-rw-r--r--src/context/mod.rs7
-rw-r--r--src/context/tab_context.rs70
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()
+ }
+}