1
0
mirror of https://github.com/danog/ytop.git synced 2024-12-02 09:27:48 +01:00

Implement proper widget updating

This commit is contained in:
Caleb Bassi 2019-07-27 13:40:43 -07:00
parent 1c23334444
commit 0d4361df27
11 changed files with 96 additions and 52 deletions

23
Cargo.lock generated
View File

@ -797,6 +797,15 @@ name = "nodrop"
version = "0.1.13" version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-bigint"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.41" version = "0.1.41"
@ -806,6 +815,17 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "num-rational"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.8" version = "0.2.8"
@ -1018,6 +1038,7 @@ dependencies = [
"futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
"heim 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "heim 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"platform-dirs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "platform-dirs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1566,7 +1587,9 @@ dependencies = [
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"

View File

@ -16,6 +16,7 @@ futures-preview = { version = "=0.3.0-alpha.17", features = ["async-await", "nig
heim = "0.0.4" heim = "0.0.4"
log = "0.4.7" log = "0.4.7"
num_cpus = "1.10.1" num_cpus = "1.10.1"
num-rational = "0.2.2"
platform-dirs = "0.2.0" platform-dirs = "0.2.0"
tokio = { git = "https://github.com/tokio-rs/tokio" } tokio = { git = "https://github.com/tokio-rs/tokio" }
serde = { version = "1.0.97", features = ["derive"] } serde = { version = "1.0.97", features = ["derive"] }

View File

@ -69,7 +69,7 @@ pub struct Args {
/// Number of times per second to update the CPU and Mem widgets. /// Number of times per second to update the CPU and Mem widgets.
#[structopt(short = "r", long = "rate", default_value = "1")] #[structopt(short = "r", long = "rate", default_value = "1")]
pub rate: f64, pub rate: u64,
/// Show a statusbar with the time. /// Show a statusbar with the time.
#[structopt(short = "s", long = "statusbar")] #[structopt(short = "s", long = "statusbar")]

View File

@ -14,8 +14,8 @@ use std::time::Duration;
use crossbeam_channel::{select, tick, unbounded, Receiver}; use crossbeam_channel::{select, tick, unbounded, Receiver};
use crossterm::{AlternateScreen, InputEvent, KeyEvent, MouseEvent}; use crossterm::{AlternateScreen, InputEvent, KeyEvent, MouseEvent};
use futures::future::join_all; use futures::future::{join_all, FutureExt};
use futures::join; use num_rational::Ratio;
use platform_dirs::{AppDirs, AppUI}; use platform_dirs::{AppDirs, AppUI};
use structopt::StructOpt; use structopt::StructOpt;
use tui::backend::{Backend, CrosstermBackend}; use tui::backend::{Backend, CrosstermBackend};
@ -118,12 +118,16 @@ fn read_colorscheme(
} }
} }
fn setup_widgets(args: &Args, colorscheme: &colorscheme::Colorscheme) -> Widgets { fn setup_widgets(
args: &Args,
update_ratio: Ratio<u64>,
colorscheme: &colorscheme::Colorscheme,
) -> Widgets {
let battery_widget = Some(BatteryWidget::new()); let battery_widget = Some(BatteryWidget::new());
let cpu_widget = CpuWidget::new(Duration::from_secs(1), args.average_cpu, args.per_cpu); let cpu_widget = CpuWidget::new(update_ratio, args.average_cpu, args.per_cpu);
let disk_widget = Some(DiskWidget::new()); let disk_widget = Some(DiskWidget::new());
let help_menu = HelpMenu::new(); let help_menu = HelpMenu::new();
let mem_widget = MemWidget::new(Duration::from_secs(1)); let mem_widget = MemWidget::new(update_ratio);
let net_widget = Some(NetWidget::new()); let net_widget = Some(NetWidget::new());
let proc_widget = ProcWidget::new(); let proc_widget = ProcWidget::new();
let statusbar = Some(Statusbar::new()); let statusbar = Some(Statusbar::new());
@ -142,27 +146,41 @@ fn setup_widgets(args: &Args, colorscheme: &colorscheme::Colorscheme) -> Widgets
} }
} }
async fn update_widgets(widgets: &mut Widgets, ticks: i64) { async fn update_widgets(widgets: &mut Widgets, seconds: Ratio<u64>) {
let cpu = widgets.cpu_widget.update(); let zero = Ratio::from_integer(0);
let mem = widgets.mem_widget.update();
let proc = widgets.proc_widget.update(); let mut futures = vec![
widgets.cpu_widget.update().boxed(),
widgets.mem_widget.update().boxed(),
];
if seconds % widgets.proc_widget.update_interval == zero {
futures.push(widgets.proc_widget.update().boxed());
}
if let (Some(disk_widget), Some(net_widget), Some(temp_widget)) = ( if let (Some(disk_widget), Some(net_widget), Some(temp_widget)) = (
widgets.disk_widget.as_mut(), widgets.disk_widget.as_mut(),
widgets.net_widget.as_mut(), widgets.net_widget.as_mut(),
widgets.temp_widget.as_mut(), widgets.temp_widget.as_mut(),
) { ) {
let disk = disk_widget.update(); if seconds % disk_widget.update_interval == zero {
let net = net_widget.update(); futures.push(disk_widget.update().boxed());
let temp = temp_widget.update(); }
if seconds % net_widget.update_interval == zero {
futures.push(net_widget.update().boxed());
}
if seconds % temp_widget.update_interval == zero {
futures.push(temp_widget.update().boxed());
}
if let Some(battery_widget) = widgets.battery_widget.as_mut() { if let Some(battery_widget) = widgets.battery_widget.as_mut() {
let battery = battery_widget.update(); if seconds % battery_widget.update_interval == zero {
join!(cpu, mem, proc, disk, net, temp, battery); futures.push(battery_widget.update().boxed());
} else {
join!(cpu, mem, proc, disk, net, temp);
} }
} else {
join!(cpu, mem, proc);
} }
}
join_all(futures).await;
} }
fn draw_widgets<B: Backend>(terminal: &mut Terminal<B>, widgets: &mut Widgets) -> io::Result<()> { fn draw_widgets<B: Backend>(terminal: &mut Terminal<B>, widgets: &mut Widgets) -> io::Result<()> {
@ -225,6 +243,7 @@ fn draw_help_menu<B: Backend>(
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let args = Args::from_args(); let args = Args::from_args();
let update_ratio = Ratio::new(1, args.rate);
let mut show_help_menu = false; let mut show_help_menu = false;
let program_name = env!("CARGO_PKG_NAME"); let program_name = env!("CARGO_PKG_NAME");
@ -232,17 +251,19 @@ async fn main() {
let logfile_path = app_dirs.state_dir.join("errors.log"); let logfile_path = app_dirs.state_dir.join("errors.log");
let colorscheme = read_colorscheme(&app_dirs.config_dir, &args.colorscheme).unwrap(); let colorscheme = read_colorscheme(&app_dirs.config_dir, &args.colorscheme).unwrap();
let mut widgets = setup_widgets(&args, &colorscheme); let mut widgets = setup_widgets(&args, update_ratio, &colorscheme);
setup_logfile(&logfile_path); setup_logfile(&logfile_path);
let mut terminal = setup_terminal().unwrap(); let mut terminal = setup_terminal().unwrap();
let mut ticks = 0; let mut update_seconds = Ratio::from_integer(0);
let ticker = tick(Duration::from_secs(1)); let ticker = tick(Duration::from_nanos(
Duration::from_secs(1).as_nanos() as u64 / args.rate,
));
let ui_events_receiver = setup_ui_events(); let ui_events_receiver = setup_ui_events();
let ctrl_c_events = setup_ctrl_c().unwrap(); let ctrl_c_events = setup_ctrl_c().unwrap();
update_widgets(&mut widgets, ticks).await; update_widgets(&mut widgets, update_seconds).await;
draw_widgets(&mut terminal, &mut widgets).unwrap(); draw_widgets(&mut terminal, &mut widgets).unwrap();
loop { loop {
@ -251,8 +272,8 @@ async fn main() {
break; break;
} }
recv(ticker) -> _ => { recv(ticker) -> _ => {
ticks = (ticks + 1) % 60; update_seconds = (update_seconds + update_ratio) % Ratio::from_integer(60);
update_widgets(&mut widgets, ticks).await; update_widgets(&mut widgets, update_seconds).await;
if !show_help_menu { if !show_help_menu {
draw_widgets(&mut terminal, &mut widgets).unwrap(); draw_widgets(&mut terminal, &mut widgets).unwrap();
} }

View File

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::time::Duration;
use num_rational::Ratio;
use tui::buffer::Buffer; use tui::buffer::Buffer;
use tui::layout::Rect; use tui::layout::Rect;
use tui::widgets::Widget; use tui::widgets::Widget;
@ -9,7 +9,7 @@ use crate::widgets::block;
pub struct BatteryWidget { pub struct BatteryWidget {
title: String, title: String,
update_interval: Duration, pub update_interval: Ratio<u64>,
update_count: f64, update_count: f64,
battery_data: HashMap<String, Vec<(f64, f64)>>, battery_data: HashMap<String, Vec<(f64, f64)>>,
@ -19,7 +19,7 @@ impl BatteryWidget {
pub fn new() -> BatteryWidget { pub fn new() -> BatteryWidget {
BatteryWidget { BatteryWidget {
title: " Batteries ".to_string(), title: " Batteries ".to_string(),
update_interval: Duration::from_secs(60), update_interval: Ratio::from_integer(60),
update_count: 0.0, update_count: 0.0,
battery_data: HashMap::new(), battery_data: HashMap::new(),

View File

@ -1,5 +1,4 @@
use std::time::Duration; use num_rational::Ratio;
use tui::buffer::Buffer; use tui::buffer::Buffer;
use tui::layout::Rect; use tui::layout::Rect;
use tui::style::{Color, Style}; use tui::style::{Color, Style};
@ -9,7 +8,7 @@ use crate::widgets::block;
pub struct CpuWidget { pub struct CpuWidget {
title: String, title: String,
update_interval: Duration, pub update_interval: Ratio<u64>,
update_count: f64, update_count: f64,
horizontal_scale: i64, horizontal_scale: i64,
@ -23,7 +22,11 @@ pub struct CpuWidget {
} }
impl CpuWidget { impl CpuWidget {
pub fn new(update_interval: Duration, show_average_cpu: bool, show_per_cpu: bool) -> CpuWidget { pub fn new(
update_interval: Ratio<u64>,
show_average_cpu: bool,
show_per_cpu: bool,
) -> CpuWidget {
let mut cpu_widget = CpuWidget { let mut cpu_widget = CpuWidget {
title: " CPU Usage ".to_string(), title: " CPU Usage ".to_string(),
update_interval, update_interval,

View File

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::path::PathBuf; use std::path::PathBuf;
use std::time::Duration;
use num_rational::Ratio;
use tui::buffer::Buffer; use tui::buffer::Buffer;
use tui::layout::Rect; use tui::layout::Rect;
use tui::widgets::Widget; use tui::widgets::Widget;
@ -21,7 +21,7 @@ struct Partition {
pub struct DiskWidget { pub struct DiskWidget {
title: String, title: String,
update_interval: Duration, pub update_interval: Ratio<u64>,
partitions: HashMap<String, Partition>, partitions: HashMap<String, Partition>,
} }
@ -30,7 +30,7 @@ impl DiskWidget {
pub fn new() -> DiskWidget { pub fn new() -> DiskWidget {
DiskWidget { DiskWidget {
title: " Disk Usage ".to_string(), title: " Disk Usage ".to_string(),
update_interval: Duration::from_secs(1), update_interval: Ratio::from_integer(1),
partitions: HashMap::new(), partitions: HashMap::new(),
} }

View File

@ -1,5 +1,4 @@
use std::time::Duration; use num_rational::Ratio;
use tui::buffer::Buffer; use tui::buffer::Buffer;
use tui::layout::Rect; use tui::layout::Rect;
use tui::widgets::Widget; use tui::widgets::Widget;
@ -8,12 +7,12 @@ use crate::widgets::block;
pub struct MemWidget { pub struct MemWidget {
title: String, title: String,
update_interval: Duration, pub update_interval: Ratio<u64>,
update_count: f64, update_count: f64,
} }
impl MemWidget { impl MemWidget {
pub fn new(update_interval: Duration) -> MemWidget { pub fn new(update_interval: Ratio<u64>) -> MemWidget {
MemWidget { MemWidget {
title: " Memory Usage ".to_string(), title: " Memory Usage ".to_string(),
update_interval, update_interval,

View File

@ -1,5 +1,4 @@
use std::time::Duration; use num_rational::Ratio;
use tui::buffer::Buffer; use tui::buffer::Buffer;
use tui::layout::Rect; use tui::layout::Rect;
use tui::widgets::Widget; use tui::widgets::Widget;
@ -8,14 +7,14 @@ use crate::widgets::block;
pub struct NetWidget { pub struct NetWidget {
title: String, title: String,
update_interval: Duration, pub update_interval: Ratio<u64>,
} }
impl NetWidget { impl NetWidget {
pub fn new() -> NetWidget { pub fn new() -> NetWidget {
NetWidget { NetWidget {
title: " Network Usage ".to_string(), title: " Network Usage ".to_string(),
update_interval: Duration::from_secs(1), update_interval: Ratio::from_integer(1),
} }
} }

View File

@ -1,5 +1,4 @@
use std::time::Duration; use num_rational::Ratio;
use tui::buffer::Buffer; use tui::buffer::Buffer;
use tui::layout::Rect; use tui::layout::Rect;
use tui::widgets::Widget; use tui::widgets::Widget;
@ -8,14 +7,14 @@ use crate::widgets::block;
pub struct ProcWidget { pub struct ProcWidget {
title: String, title: String,
update_interval: Duration, pub update_interval: Ratio<u64>,
} }
impl ProcWidget { impl ProcWidget {
pub fn new() -> ProcWidget { pub fn new() -> ProcWidget {
ProcWidget { ProcWidget {
title: " Processes ".to_string(), title: " Processes ".to_string(),
update_interval: Duration::from_secs(1), update_interval: Ratio::from_integer(1),
} }
} }

View File

@ -1,5 +1,4 @@
use std::time::Duration; use num_rational::Ratio;
use tui::buffer::Buffer; use tui::buffer::Buffer;
use tui::layout::Rect; use tui::layout::Rect;
use tui::widgets::Widget; use tui::widgets::Widget;
@ -8,7 +7,7 @@ use crate::widgets::block;
pub struct TempWidget { pub struct TempWidget {
title: String, title: String,
update_interval: Duration, pub update_interval: Ratio<u64>,
update_count: f64, update_count: f64,
temp_data: Vec<(String, Vec<(f64, f64)>)>, temp_data: Vec<(String, Vec<(f64, f64)>)>,
@ -18,7 +17,7 @@ impl TempWidget {
pub fn new() -> TempWidget { pub fn new() -> TempWidget {
TempWidget { TempWidget {
title: " Temperatures ".to_string(), title: " Temperatures ".to_string(),
update_interval: Duration::from_secs(5), update_interval: Ratio::from_integer(5),
update_count: 0.0, update_count: 0.0,
temp_data: Vec::new(), temp_data: Vec::new(),