summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-12-12 01:01:11 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-12-12 01:04:33 +0200
commit59f7f03d64cc78423537a108a69cd838e9cc5119 (patch)
tree8c6311713e6c3e1a3291cab9aa4d3fb2103dcc79
parent7732b851e62aa7d9582932c8a508c7f84951ebcd (diff)
ui: refactor watch thread spawning procedure
- Remove unnecessary parameters from watch(), reload() - Add NewThread event that adds new threads in work_controller.static_threads hashmap - removed obsolete field State.threads - silence watch thread error notifications
-rw-r--r--src/bin.rs4
-rw-r--r--ui/src/conf/accounts.rs55
-rw-r--r--ui/src/state.rs42
-rw-r--r--ui/src/types.rs2
4 files changed, 39 insertions, 64 deletions
diff --git a/src/bin.rs b/src/bin.rs
index cabe5536..8f0f1899 100644
--- a/src/bin.rs
+++ b/src/bin.rs
@@ -373,8 +373,8 @@ fn run_app() -> Result<()> {
state.check_accounts();
state.redraw();
},
- ThreadEvent::ThreadJoin(id) => {
- state.join(id);
+ ThreadEvent::NewThread(id, name) => {
+ state.new_thread(id, name);
},
}
},
diff --git a/ui/src/conf/accounts.rs b/ui/src/conf/accounts.rs
index b053fe83..109c8870 100644
--- a/ui/src/conf/accounts.rs
+++ b/ui/src/conf/accounts.rs
@@ -38,7 +38,7 @@ use melib::StackVec;
use text_processing::GlobMatch;
use crate::types::UIEvent::{self, EnvelopeRemove, EnvelopeRename, EnvelopeUpdate, Notification};
-use crate::{workers::WorkController, StatusEvent, ThreadEvent};
+use crate::{StatusEvent, ThreadEvent};
use crossbeam::Sender;
use std::collections::VecDeque;
use std::fs;
@@ -162,6 +162,7 @@ pub struct Account {
pub(crate) runtime_settings: AccountConf,
pub(crate) backend: Arc<RwLock<Box<dyn MailBackend>>>,
+ sender: Sender<ThreadEvent>,
event_queue: VecDeque<(FolderHash, RefreshEvent)>,
notify_fn: Arc<NotifyFn>,
}
@@ -245,6 +246,7 @@ impl Account {
mut settings: AccountConf,
map: &Backends,
work_context: WorkContext,
+ sender: Sender<ThreadEvent>,
notify_fn: NotifyFn,
) -> Result<Self> {
let s = settings.clone();
@@ -300,6 +302,7 @@ impl Account {
settings,
backend: Arc::new(RwLock::new(backend)),
notify_fn,
+ sender,
event_queue: VecDeque::with_capacity(8),
})
@@ -514,16 +517,7 @@ impl Account {
}
Some(w)
}
- pub fn reload(
- &mut self,
- event: RefreshEvent,
- folder_hash: FolderHash,
- context: (
- &mut WorkController,
- &Sender<ThreadEvent>,
- &mut VecDeque<UIEvent>,
- ),
- ) -> Option<UIEvent> {
+ pub fn reload(&mut self, event: RefreshEvent, folder_hash: FolderHash) -> Option<UIEvent> {
if !self.folders[&folder_hash].is_available() {
self.event_queue.push_back((folder_hash, event));
return None;
@@ -683,6 +677,7 @@ impl Account {
}
RefreshEventKind::Failure(e) => {
debug!("RefreshEvent Failure: {}", e.to_string());
+ /*
context
.1
.send(ThreadEvent::UIEvent(UIEvent::Notification(
@@ -691,43 +686,39 @@ impl Account {
Some(crate::types::NotificationType::ERROR),
)))
.expect("Could not send event on main channel");
- self.watch(context);
+ */
+ self.watch();
}
}
}
None
}
- pub fn watch(
- &self,
- context: (
- &mut WorkController,
- &Sender<ThreadEvent>,
- &mut VecDeque<UIEvent>,
- ),
- ) {
- let (work_controller, sender, replies) = context;
- let sender = sender.clone();
+ pub fn watch(&self) {
+ let sender_ = self.sender.clone();
let r = RefreshEventConsumer::new(Box::new(move |r| {
- sender.send(ThreadEvent::from(r)).unwrap();
+ sender_.send(ThreadEvent::from(r)).unwrap();
}));
match self
.backend
.read()
.unwrap()
- .watch(r, work_controller.get_context())
+ .watch(r, self.work_context.clone())
{
Ok(id) => {
- work_controller
- .static_threads
- .lock()
- .unwrap()
- .insert(id, format!("watching {}", self.name()).into());
+ self.sender
+ .send(ThreadEvent::NewThread(
+ id,
+ format!("watching {}", self.name()).into(),
+ ))
+ .unwrap();
}
Err(e) => {
- replies.push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(
- e.to_string(),
- )));
+ self.sender
+ .send(ThreadEvent::UIEvent(UIEvent::StatusEvent(
+ StatusEvent::DisplayMessage(e.to_string()),
+ )))
+ .unwrap();
}
}
}
diff --git a/ui/src/state.rs b/ui/src/state.rs
index dd788181..c1bed88f 100644
--- a/ui/src/state.rs
+++ b/ui/src/state.rs
@@ -137,9 +137,6 @@ impl Context {
pub fn is_online(&mut self, account_pos: usize) -> bool {
let Context {
- ref mut work_controller,
- ref sender,
- ref mut replies,
ref mut accounts,
ref mut mailbox_hashes,
..
@@ -158,7 +155,7 @@ impl Context {
* inform the main binary that refresh events arrived
* - replies to report any failures to the user
*/
- accounts[account_pos].watch((work_controller, sender, replies));
+ accounts[account_pos].watch();
}
true
} else {
@@ -184,7 +181,6 @@ pub struct State {
components: Vec<Box<dyn Component>>,
pub context: Context,
timer: thread::JoinHandle<()>,
- threads: FnvHashMap<thread::ThreadId, (Sender<bool>, thread::JoinHandle<()>)>,
}
impl Drop for State {
@@ -232,6 +228,7 @@ impl State {
a_s.clone(),
&backends,
work_controller.get_context(),
+ sender.clone(),
NotifyFn::new(Box::new(move |f: FolderHash| {
sender
.send(ThreadEvent::UIEvent(UIEvent::StartupCheck(f)))
@@ -286,7 +283,6 @@ impl State {
tx: input_thread.0,
},
},
- threads: FnvHashMap::with_capacity_and_hasher(1, Default::default()),
};
if s.context.settings.terminal.ascii_drawing {
s.grid.set_ascii_drawing(true);
@@ -319,41 +315,29 @@ impl State {
return;
}
let Context {
- ref mut work_controller,
- ref sender,
- ref mut replies,
- ref mut accounts,
- ..
+ ref mut accounts, ..
} = &mut self.context;
- if let Some(notification) =
- accounts[idxa].reload(event, hash, (work_controller, sender, replies))
- {
+ if let Some(notification) = accounts[idxa].reload(event, hash) {
if let UIEvent::Notification(_, _, _) = notification {
self.rcv_event(UIEvent::MailboxUpdate((idxa, hash)));
}
self.rcv_event(notification);
}
} else {
- if let melib::backends::RefreshEventKind::Failure(e) = event.kind() {
- self.context
- .sender
- .send(ThreadEvent::UIEvent(UIEvent::Notification(
- Some("watcher thread exited with error".to_string()),
- e.to_string(),
- Some(crate::types::NotificationType::ERROR),
- )))
- .expect("Could not send event on main channel");
+ if let melib::backends::RefreshEventKind::Failure(err) = event.kind() {
+ debug!(err);
}
}
}
- /// If an owned thread returns a `ThreadEvent::ThreadJoin` event to `State` then it must remove
- /// the thread from its list and `join` it.
- pub fn join(&mut self, id: thread::ThreadId) {
- let (tx, handle) = self.threads.remove(&id).unwrap();
- tx.send(true).unwrap();
- handle.join().unwrap();
+ pub fn new_thread(&mut self, id: thread::ThreadId, name: String) {
+ self.context
+ .work_controller
+ .static_threads
+ .lock()
+ .unwrap()
+ .insert(id, name.into());
}
/// Switch back to the terminal's main screen (The command line the user sees before opening
diff --git a/ui/src/types.rs b/ui/src/types.rs
index 743e9fea..b3ed0d0b 100644
--- a/ui/src/types.rs
+++ b/ui/src/types.rs
@@ -46,7 +46,7 @@ pub enum StatusEvent {
/// to the main process.
#[derive(Debug)]
pub enum ThreadEvent {
- ThreadJoin(thread::ThreadId),
+ NewThread(thread::ThreadId, String),
/// User input.
Input(Key),
/// User input and input as raw bytes.