ui: add periodic account connectivity check

1. spawn thread to send ThreadPulses to the main event loop that "parks" until unparked from State
2. State unparks thread if there are accounts that are offline
3. thread sends ThreadPulse and parks again
4. State checks accounts again and so on.
jmap
Manos Pitsidianakis 2019-11-23 18:00:00 +02:00
parent 12e4258ae4
commit 874a252394
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 36 additions and 4 deletions

View File

@ -376,6 +376,7 @@ fn run_app() -> Result<()> {
state.render(); state.render();
}, },
ThreadEvent::Pulse => { ThreadEvent::Pulse => {
state.check_accounts();
state.redraw(); state.redraw();
}, },
ThreadEvent::ThreadJoin(id) => { ThreadEvent::ThreadJoin(id) => {

View File

@ -222,7 +222,6 @@ impl Component for Listing {
.dirty_areas .dirty_areas
.push_back(((mid, get_y(upper_left)), (mid, get_y(bottom_right)))); .push_back(((mid, get_y(upper_left)), (mid, get_y(bottom_right))));
} }
self.dirty = false;
if right_component_width == total_cols { if right_component_width == total_cols {
if !context.is_online(self.cursor_pos.0) { if !context.is_online(self.cursor_pos.0) {
@ -278,6 +277,7 @@ impl Component for Listing {
} }
} }
} }
self.dirty = false;
} }
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool { fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
if match self.component { if match self.component {
@ -468,7 +468,7 @@ impl Component for Listing {
self.dirty = true; self.dirty = true;
} }
UIEvent::Resize => { UIEvent::Resize => {
self.dirty = true; self.set_dirty();
} }
UIEvent::Input(Key::Up) => { UIEvent::Input(Key::Up) => {
let amount = if self.cmd_buf.is_empty() { let amount = if self.cmd_buf.is_empty() {

View File

@ -1423,9 +1423,9 @@ impl Component for Tabbed {
create_box(grid, area); create_box(grid, area);
let area = ( let area = (
pos_inc(upper_left!(area), (3, 2)), pos_inc(upper_left!(area), (3, 2)),
set_x( (
bottom_right!(area),
get_x(bottom_right!(area)).saturating_sub(3), get_x(bottom_right!(area)).saturating_sub(3),
get_y(bottom_right!(area)).saturating_sub(1),
), ),
); );
let mut children_maps = self.children[self.cursor_pos].get_shortcuts(context); let mut children_maps = self.children[self.cursor_pos].get_shortcuts(context);

View File

@ -183,6 +183,7 @@ pub struct State {
pub mode: UIMode, pub mode: UIMode,
components: Vec<Box<dyn Component>>, components: Vec<Box<dyn Component>>,
pub context: Context, pub context: Context,
timer: thread::JoinHandle<()>,
threads: FnvHashMap<thread::ThreadId, (Sender<bool>, thread::JoinHandle<()>)>, threads: FnvHashMap<thread::ThreadId, (Sender<bool>, thread::JoinHandle<()>)>,
} }
@ -241,6 +242,22 @@ impl State {
.collect::<Result<Vec<Account>>>()?; .collect::<Result<Vec<Account>>>()?;
accounts.sort_by(|a, b| a.name().cmp(&b.name())); accounts.sort_by(|a, b| a.name().cmp(&b.name()));
let timer = {
let sender = sender.clone();
thread::Builder::new().spawn(move || {
let sender = sender;
loop {
thread::park();
debug!("unparked");
sender.send(ThreadEvent::Pulse).unwrap();
thread::sleep(std::time::Duration::from_millis(100));
}
})
}?;
timer.thread().unpark();
let mut s = State { let mut s = State {
cols, cols,
rows, rows,
@ -249,6 +266,7 @@ impl State {
child: None, child: None,
mode: UIMode::Normal, mode: UIMode::Normal,
components: Vec::with_capacity(1), components: Vec::with_capacity(1),
timer,
context: Context { context: Context {
accounts, accounts,
@ -716,4 +734,17 @@ impl State {
fn stdout(&mut self) -> &mut StateStdout { fn stdout(&mut self) -> &mut StateStdout {
self.stdout.as_mut().unwrap() self.stdout.as_mut().unwrap()
} }
pub fn check_accounts(&mut self) {
let mut ctr = 0;
for i in 0..self.context.accounts.len() {
if self.context.is_online(i) {
ctr += 1;
}
}
if ctr != self.context.accounts.len() {
debug!("unparking");
self.timer.thread().unpark();
}
}
} }