summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2020-02-16 04:00:02 +0100
committerrabite <rabite@posteo.de>2020-02-16 04:39:20 +0100
commitedc2def6110e99f457f56fcce1574d3c7310f1fe (patch)
tree56c5e03ea418043a72fbf2292c57d583cd3a1ece
parentf1fbcf0c3681d2a51f66ef543469513c3b775508 (diff)
extract tick function and tick for widgets too
-rw-r--r--src/files.rs128
-rw-r--r--src/preview.rs7
2 files changed, 50 insertions, 85 deletions
diff --git a/src/files.rs b/src/files.rs
index efe1543..8478beb 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -4,7 +4,7 @@ use std::ops::Index;
use std::fs::Metadata;
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};
-use std::sync::{Arc, Mutex, RwLock};
+use std::sync::{Arc, RwLock};
use std::sync::mpsc::Sender;
use std::hash::{Hash, Hasher};
use std::str::FromStr;
@@ -42,22 +42,13 @@ lazy_static! {
static ref COLORS: LsColors = LsColors::from_env().unwrap_or_default();
static ref TAGS: RwLock<(bool, Vec<PathBuf>)> = RwLock::new((false, vec![]));
static ref ICONS: Icons = Icons::new();
- static ref IOPOOL: Mutex<Option<ThreadPool>> = Mutex::new(None);
+ static ref IOTICK_CLIENTS: AtomicUsize = AtomicUsize::default();
static ref IOTICK: AtomicUsize = AtomicUsize::default();
- static ref TICKING: AtomicBool = AtomicBool::new(false);
-}
-
-pub fn tick() {
- IOTICK.fetch_add(1, Ordering::Relaxed);
-}
-
-pub fn get_tick() -> usize {
- IOTICK.load(Ordering::Relaxed)
}
pub fn tick_str() -> &'static str {
// Using mod 5 for that nice nonlinear look
- match get_tick() % 5 {
+ match IOTICK.load(Ordering::Relaxed) % 5 {
0 => " ",
1 => ". ",
2 => ".. ",
@@ -65,12 +56,44 @@ pub fn tick_str() -> &'static str {
}
}
-pub fn is_ticking() -> bool {
- TICKING.load(Ordering::Acquire)
+pub fn start_ticking(sender: Sender<Events>) {
+ use std::time::Duration;
+
+ IOTICK_CLIENTS.fetch_add(1, Ordering::Relaxed);
+ if IOTICK_CLIENTS.load(Ordering::Acquire) == 1 {
+ std::thread::spawn(move || {
+ IOTICK.store(0, Ordering::Relaxed);
+
+ // Gently slow down refreshes
+ let backoff = Duration::from_millis(10);
+ let mut cooldown = Duration::from_millis(10);
+
+ loop {
+ IOTICK.fetch_add(1, Ordering::Relaxed);
+
+ // Send refresh event before sleeping
+ sender.send(crate::widget::Events::WidgetReady)
+ .unwrap();
+
+ // All jobs done?
+ if IOTICK_CLIENTS.load(Ordering::Acquire) == 0 {
+ IOTICK.store(0, Ordering::Relaxed);
+ return;
+ }
+
+ std::thread::sleep(cooldown);
+
+ // Slow down up to 1 second
+ if cooldown < Duration::from_millis(1000) {
+ cooldown += backoff;
+ }
+ }
+ });
+ }
}
-pub fn set_ticking(val: bool) {
- TICKING.store(val, Ordering::Release);
+pub fn stop_ticking() {
+ IOTICK_CLIENTS.fetch_sub(1, Ordering::Relaxed);
}
#[derive(Fail, Debug, Clone)]
@@ -415,7 +438,6 @@ impl Files {
}
pub fn run_jobs(&mut self, sender: Sender<Events>) {
- use std::time::Duration;
let jobs = std::mem::take(&mut self.jobs);
let stale = self.stale
.clone()
@@ -425,68 +447,14 @@ impl Files {
std::thread::spawn(move || {
let pool = get_pool();
- let stop = AtomicBool::new(false);
- let stop = &stop;
let stale = &stale;
- let ticker = move || {
- // Gently slow down refreshes
- let backoff = Duration::from_millis(10);
- let mut cooldown = Duration::from_millis(10);
-
- loop {
- // Send refresh event before sleeping
- sender.send(crate::widget::Events::WidgetReady)
- .unwrap();
- std::thread::sleep(cooldown);
-
- // Slow down up to 1 second
- if cooldown < Duration::from_secs(1) {
- cooldown += backoff;
- }
-
- // All jobs done?
- if stop.load(Ordering::Relaxed) {
- crate::files::tick();
- std::thread::sleep(cooldown);
- // Refresh one last time
- sender.send(crate::widget::Events::WidgetReady)
- .unwrap();
- crate::files::set_ticking(false);
- return;
- }
-
- crate::files::tick();
- }
- };
-
- // To allow calling without consuming, all while Sender can't be shared
- let mut ticker = Some(ticker);
-
- // Finally this returns the ticker function as an Option
- let mut ticker = move || {
- // Only return ticker if no one's ticking
- match !crate::files::is_ticking() {
- true => {
- crate::files::set_ticking(true);
- ticker.take()
- }
- false => None
- }
- };
+ start_ticking(sender);
pool.scope_fifo(move |s| {
- // Noop with other pool running ticker
- ticker().map(|t| s.spawn_fifo(move |_| t()));
-
- let jobs_num = jobs.len();
-
- for (i, (path, mslot, dirsize)) in jobs.into_iter()
- .stop_stale(stale.clone())
- .enumerate()
+ for (path, mslot, dirsize) in jobs.into_iter()
+ .stop_stale(stale.clone())
{
- ticker().map(|t| s.spawn_fifo(move |_| t()));
-
s.spawn_fifo(move |_| {
if let Some(mslot) = mslot {
if let Ok(meta) = std::fs::symlink_metadata(&path) {
@@ -506,19 +474,11 @@ impl Files {
dirsize.0.store(true, Ordering::Relaxed);
dirsize.1.store(size, Ordering::Relaxed);
};
-
- // This is the last job, stop ticking
- if jobs_num == i + 1 {
- stop.store(true, Ordering::Relaxed);
- }
});
}
+ });
- // Stop ticking if loop breaks on stale
- if stale.is_stale().unwrap_or(true) {
- stop.store(true, Ordering::Relaxed);
- }
- })
+ stop_ticking();
});
}
diff --git a/src/preview.rs b/src/preview.rs
index b31ee7c..7ba2010 100644
--- a/src/preview.rs
+++ b/src/preview.rs
@@ -74,11 +74,14 @@ impl<W: Widget + Send + 'static> AsyncWidget<W> {
let mut widget = Async::new(move |stale|
closure(stale).map_err(|e| e.into()));
widget.on_ready(move |_, stale| {
+ crate::files::stop_ticking();
if !stale.is_stale()? {
sender.lock().map(|s| s.send(crate::widget::Events::WidgetReady)).ok();
}
Ok(())
}).log();
+
+ crate::files::start_ticking(core.get_sender());
widget.run().log();
AsyncWidget {
@@ -101,6 +104,7 @@ impl<W: Widget + Send + 'static> AsyncWidget<W> {
});
widget.on_ready(move |_, stale| {
+ crate::files::stop_ticking();
if !stale.is_stale()? {
sender.lock()
.map(|s| s.send(crate::widget::Events::WidgetReady))
@@ -109,6 +113,7 @@ impl<W: Widget + Send + 'static> AsyncWidget<W> {
Ok(())
}).log();
+ crate::files::start_ticking(self.core.get_sender());
widget.run().log();
self.widget = widget;
@@ -181,7 +186,7 @@ impl<T: Widget + Send + 'static> Widget for AsyncWidget<T> {
let clear = self.core.get_clearlist()?;
let (xpos, ypos) = self.get_coordinates()?.u16position();
let pos = crate::term::goto_xy(xpos, ypos);
- return Ok(clear + &pos + "...")
+ return Ok(clear + &pos + crate::files::tick_str())
}
if self.is_stale()? {