Handle thread joins from State

embed
Manos Pitsidianakis 2018-08-06 14:58:54 +03:00
parent 3f35b69ff1
commit 00200aedb6
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
5 changed files with 64 additions and 43 deletions

View File

@ -5,19 +5,19 @@ authors = []
workspace = ".."
[dependencies]
notify = "4.0.1"
notify-rust = "^3"
crossbeam = "^0.3.0"
fnv = "1.0.3"
config = "0.6"
xdg = "2.1.0"
bitflags = "1.0"
chan = "0.1.21"
chrono = "0.4"
serde_derive = "^1.0.8"
serde = "^1.0.8"
nom = "3.2.0"
memmap = "0.5.2"
config = "0.6"
crossbeam = "^0.3.0"
data-encoding = "2.1.1"
encoding = "0.2.33"
bitflags = "1.0"
fnv = "1.0.3"
memmap = "0.5.2"
nom = "3.2.0"
notify = "4.0.1"
notify-rust = "^3"
serde = "^1.0.8"
serde_derive = "^1.0.8"
termion = "1.5.1"
chan = "0.1.21"
xdg = "2.1.0"

View File

@ -215,6 +215,9 @@ fn main() {
state.rcv_event(UIEvent { id: 0, event_type: e});
state.render();
},
ThreadEvent::ThreadJoin(id) => {
state.join(id);
},
}
},
signal.recv() -> signal => {

View File

@ -5,14 +5,14 @@ authors = []
workspace = ".."
[dependencies]
melib = { path = "../melib", version = "*" }
termion = "1.5.1"
chan = "0.1.21"
chan-signal = "0.3.1"
fnv = "1.0.3"
linkify = "0.3.1"
melib = { path = "../melib", version = "*" }
mime_apps = { path = "../../mime_apps", version = "*" }
nom = "3.2.0"
notify = "4.0.1"
notify-rust = "^3"
nom = "3.2.0"
chan-signal = "0.3.1"
mime_apps = { path = "../../mime_apps", version = "*" }
termion = "1.5.1"
uuid = { version = "0.6", features = ["serde", "v4"] }
linkify = "0.3.1"

View File

@ -44,7 +44,7 @@ impl AccountMenu {
cursor: None,
}
}
fn print_account(&self, grid: &mut CellBuffer, area: Area, a: &AccountMenuEntry) -> usize {
fn print_account(&self, grid: &mut CellBuffer, area: Area, a: &AccountMenuEntry, context: &mut Context) -> usize {
if !is_valid_area!(area) {
eprintln!("BUG: invalid area in print_account");
}
@ -86,25 +86,38 @@ impl AccountMenu {
entries: &Vec<(usize, Folder)>,
s: &mut String,
inc: &mut usize,
) -> () {
index: usize, //account index
context: &mut Context,
) -> () {
let len = s.len();
s.insert_str(len, &format!("{} {}\n ", *inc, &entries[root].1.name()));
match context.accounts[index].status(root) {
Ok(()) => {},
Err(_) => {
return;
// TODO: Show progress visually
}
}
let count = context.accounts[index][root].as_ref().unwrap().collection.iter().filter(|e| !e.is_seen()).count();
s.insert_str(len, &format!("{} {} {}\n ", *inc, &entries[root].1.name(), count));
*inc += 1;
let children_no = entries[root].1.children().len();
for (idx, child) in entries[root].1.children().iter().enumerate() {
let len = s.len();
s.insert_str(len, &format!("{}├─", depth));
push(depth, if idx == children_no - 1 { '│' } else { ' ' });
print(*child, parents, depth, entries, s, inc);
print(*child, parents, depth, entries, s, inc, index, context);
pop(depth);
}
}
for r in roots {
print(r, &parents, &mut depth, &a.entries, &mut s, &mut inc);
print(r, &parents, &mut depth, &a.entries, &mut s, &mut inc, a.index, context);
}
let lines: Vec<&str> = s.lines().collect();
let lines_len = lines.len();
if lines_len < 2 {
return 0;
}
let mut idx = 0;
for y in get_y(upper_left)..get_y(bottom_right) {
if idx == lines_len {
@ -115,24 +128,14 @@ impl AccountMenu {
} else {
format!("{}", lines[idx])
};
let color_fg = if highlight {
let (color_fg, color_bg) = if highlight {
if idx > 1 && self.cursor.unwrap().1 == idx - 2 {
Color::Byte(233)
(Color::Byte(233), Color::Byte(15))
} else {
Color::Byte(15)
(Color::Byte(15), Color::Byte(233))
}
} else {
Color::Default
};
let color_bg = if highlight {
if idx > 1 && self.cursor.unwrap().1 == idx - 2 {
Color::Byte(15)
} else {
Color::Byte(233)
}
} else {
Color::Default
(Color::Default, Color::Default)
};
let (x, _) = write_string_to_grid(
@ -175,7 +178,7 @@ impl Component for AccountMenu {
self.dirty = false;
let mut y = get_y(upper_left);
for a in &self.accounts {
y += self.print_account(grid, (set_y(upper_left, y), bottom_right), &a);
y += self.print_account(grid, (set_y(upper_left, y), bottom_right), &a, context);
}
context.dirty_areas.push_back(area);

View File

@ -57,6 +57,8 @@ use std::fmt;
use std::io::Write;
use std::thread;
use std::time;
extern crate fnv;
use self::fnv::FnvHashMap;
extern crate termion;
use termion::event::Key as TermionKey;
use termion::input::TermRead;
@ -73,6 +75,7 @@ use chan::Sender;
/// to the main process.
#[derive(Debug)]
pub enum ThreadEvent {
ThreadJoin(thread::ThreadId),
/// User input.
Input(Key),
/// A watched folder has been refreshed.
@ -191,7 +194,9 @@ pub struct State<W: Write> {
entities: Vec<Entity>,
pub context: Context,
startup_thread: Option<(chan::Sender<bool>, thread::JoinHandle<()>)>,
startup_thread: Option<chan::Sender<bool>>,
threads: FnvHashMap<thread::ThreadId, thread::JoinHandle<()>>,
}
impl<W: Write> Drop for State<W> {
@ -231,6 +236,8 @@ impl State<std::io::Stdout> {
let (startup_tx, startup_rx) = chan::async();
let startup_thread = {
let sender = sender.clone();
let startup_rx = startup_rx.clone();
thread::Builder::new()
.name("startup-thread".to_string())
.spawn(move || {
@ -239,6 +246,7 @@ impl State<std::io::Stdout> {
chan_select! {
default => {},
startup_rx.recv() -> _ => {
sender.send(ThreadEvent::ThreadJoin(thread::current().id()));
return;
}
}
@ -267,8 +275,10 @@ impl State<std::io::Stdout> {
input_thread: input_thread,
},
startup_thread: Some((startup_tx, startup_thread)),
startup_thread: Some(startup_tx),
threads: FnvHashMap::with_capacity_and_hasher(1, Default::default()),
};
s.threads.insert(startup_thread.thread().id(), startup_thread);
write!(
s.stdout(),
"{}{}{}",
@ -284,6 +294,12 @@ impl State<std::io::Stdout> {
})));
}
s
}
pub fn join(&mut self, id: thread::ThreadId) {
let handle = self.threads.remove(&id).unwrap();
handle.join().unwrap();
}
pub fn finish_startup(&mut self) {
// TODO: Encode startup process with the type system if possible
@ -291,9 +307,8 @@ impl State<std::io::Stdout> {
return;
}
{
let (tx, handle) = self.startup_thread.take().unwrap();
let tx = self.startup_thread.take().unwrap();
tx.send(true);
handle.join().unwrap();
}
}
pub fn to_main_screen(&mut self) {