mirror of
https://github.com/bootandy/dust.git
synced 2026-06-08 11:29:05 +03:00
refactor: progress bar
Change threading to use channels instead of atomic boolean Allows for early exit so we don't have to wait for spinner loop timeout
This commit is contained in:
+12
-11
@@ -3,6 +3,7 @@ use std::{
|
|||||||
path::Path,
|
path::Path,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, AtomicU64, AtomicU8, AtomicUsize, Ordering},
|
atomic::{AtomicBool, AtomicU64, AtomicU8, AtomicUsize, Ordering},
|
||||||
|
mpsc::{self, RecvTimeoutError, Sender},
|
||||||
Arc, RwLock,
|
Arc, RwLock,
|
||||||
},
|
},
|
||||||
thread::JoinHandle,
|
thread::JoinHandle,
|
||||||
@@ -78,15 +79,13 @@ fn format_indicator_str(data: &PAtomicInfo, progress_char_i: usize, status: &str
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct PIndicator {
|
pub struct PIndicator {
|
||||||
thread_run: Arc<AtomicBool>,
|
pub thread: Option<(Sender<()>, JoinHandle<()>)>,
|
||||||
pub thread: Option<JoinHandle<()>>,
|
|
||||||
pub data: Arc<PAtomicInfo>,
|
pub data: Arc<PAtomicInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PIndicator {
|
impl PIndicator {
|
||||||
pub fn build_me() -> Self {
|
pub fn build_me() -> Self {
|
||||||
Self {
|
Self {
|
||||||
thread_run: Arc::new(AtomicBool::new(true)),
|
|
||||||
thread: None,
|
thread: None,
|
||||||
data: Arc::new(PAtomicInfo {
|
data: Arc::new(PAtomicInfo {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -96,14 +95,17 @@ impl PIndicator {
|
|||||||
|
|
||||||
pub fn spawn(&mut self, is_iso: bool) {
|
pub fn spawn(&mut self, is_iso: bool) {
|
||||||
let data = self.data.clone();
|
let data = self.data.clone();
|
||||||
let is_building_data_const = self.thread_run.clone();
|
let (stop_handler, receiver) = mpsc::channel::<()>();
|
||||||
|
|
||||||
let time_info_thread = std::thread::spawn(move || {
|
let time_info_thread = std::thread::spawn(move || {
|
||||||
let mut progress_char_i: usize = 0;
|
let mut progress_char_i: usize = 0;
|
||||||
let mut stdout = std::io::stdout();
|
let mut stdout = std::io::stdout();
|
||||||
std::thread::sleep(Duration::from_millis(SPINNER_SLEEP_TIME));
|
|
||||||
|
|
||||||
while is_building_data_const.load(ORDERING) {
|
// While the timeout triggers we go round the loop
|
||||||
|
// If we disconnect or the sender sends its message we exit the while loop
|
||||||
|
while let Err(RecvTimeoutError::Timeout) =
|
||||||
|
receiver.recv_timeout(Duration::from_millis(SPINNER_SLEEP_TIME))
|
||||||
|
{
|
||||||
let msg = match data.state.load(ORDERING) {
|
let msg = match data.state.load(ORDERING) {
|
||||||
Operation::INDEXING => {
|
Operation::INDEXING => {
|
||||||
let base = format_indicator_str(&data, progress_char_i, "Indexing");
|
let base = format_indicator_str(&data, progress_char_i, "Indexing");
|
||||||
@@ -126,7 +128,6 @@ impl PIndicator {
|
|||||||
progress_char_i += 1;
|
progress_char_i += 1;
|
||||||
progress_char_i %= PROGRESS_CHARS_LEN;
|
progress_char_i %= PROGRESS_CHARS_LEN;
|
||||||
|
|
||||||
std::thread::sleep(Duration::from_millis(SPINNER_SLEEP_TIME));
|
|
||||||
// Clear the text written by 'write!'
|
// Clear the text written by 'write!'
|
||||||
print!("\r{:width$}", " ", width = msg.len());
|
print!("\r{:width$}", " ", width = msg.len());
|
||||||
}
|
}
|
||||||
@@ -135,13 +136,13 @@ impl PIndicator {
|
|||||||
print!("\r");
|
print!("\r");
|
||||||
stdout.flush().unwrap();
|
stdout.flush().unwrap();
|
||||||
});
|
});
|
||||||
self.thread = Some(time_info_thread)
|
self.thread = Some((stop_handler, time_info_thread))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(self) {
|
pub fn stop(self) {
|
||||||
self.thread_run.store(false, ORDERING);
|
if let Some((stop_handler, thread)) = self.thread {
|
||||||
if let Some(t) = self.thread {
|
stop_handler.send(()).unwrap();
|
||||||
t.join().unwrap();
|
thread.join().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user