summaryrefslogtreecommitdiffstats
path: root/src/context/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/context/context.rs')
-rw-r--r--src/context/context.rs125
1 files changed, 125 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()
+ }
+}