summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs312
1 files changed, 182 insertions, 130 deletions
diff --git a/src/main.rs b/src/main.rs
index f63a7ffa..4c483687 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,9 +11,12 @@ use tui::{
mod widgets;
+#[macro_use]
+extern crate log;
+
enum Event<I> {
Input(I),
- Tick,
+ Update(widgets::Data),
}
#[tokio::main]
@@ -22,7 +25,10 @@ async fn main() -> Result<(), io::Error> {
let backend = CrosstermBackend::with_alternate_screen(screen)?;
let mut terminal = Terminal::new(backend)?;
- let update_rate_in_milliseconds : u64 = 500;
+ let tick_rate_in_milliseconds : u64 = 220;
+ let update_rate_in_milliseconds : u64 = 1000;
+
+ let log = init_logger();
terminal.hide_cursor()?;
// Setup input handling
@@ -41,35 +47,51 @@ async fn main() -> Result<(), io::Error> {
}
});
}
+
+ // Event loop
+ let mut data_state = widgets::DataState::default();
{
let tx = tx.clone();
thread::spawn(move || {
let tx = tx.clone();
loop {
- tx.send(Event::Tick).unwrap();
+ futures::executor::block_on(data_state.update_data()); // TODO: Fix
+ tx.send(Event::Update(data_state.data.clone())).unwrap();
thread::sleep(Duration::from_millis(update_rate_in_milliseconds));
}
});
}
- let mut app : widgets::App = widgets::App::new("rustop");
-
+ let mut app = widgets::App::new("rustop");
terminal.clear()?;
+ let mut app_data = widgets::Data::default();
loop {
- if let Ok(recv) = rx.recv() {
+ if let Ok(recv) = rx.recv_timeout(Duration::from_millis(tick_rate_in_milliseconds)) {
match recv {
- Event::Input(event) => match event {
- KeyEvent::Char(c) => app.on_key(c),
- KeyEvent::Left => {}
- KeyEvent::Right => {}
- KeyEvent::Up => {}
- KeyEvent::Down => {}
- KeyEvent::Ctrl('c') => break,
- _ => {}
- },
- Event::Tick => {
- app.update_data().await; // TODO: This await is causing slow responsiveness... perhaps make drawing another thread?
+ Event::Input(event) => {
+ try_debug(&log, "Input event fired!");
+ match event {
+ KeyEvent::Char(c) => app.on_key(c),
+ KeyEvent::Left => app.on_left(),
+ KeyEvent::Right => app.on_right(),
+ KeyEvent::Up => app.on_up(),
+ KeyEvent::Down => app.on_down(),
+ KeyEvent::Ctrl('c') => break,
+ _ => {}
+ }
+
+ if app.to_be_resorted {
+ widgets::processes::sort_processes(&mut app_data.list_of_processes, &app.process_sorting_type, app.process_sorting_reverse);
+ app.to_be_resorted = false;
+ }
+ try_debug(&log, "Input event complete.");
+ }
+ Event::Update(data) => {
+ try_debug(&log, "Update event fired!");
+ app_data = data;
+ widgets::processes::sort_processes(&mut app_data.list_of_processes, &app.process_sorting_type, app.process_sorting_reverse);
+ try_debug(&log, "Update event complete.");
}
}
if app.should_quit {
@@ -77,122 +99,152 @@ async fn main() -> Result<(), io::Error> {
}
}
- // Convert data into tui components
- let temperature_rows = app.list_of_temperature.iter().map(|sensor| {
- Row::StyledData(
- vec![sensor.component_name.to_string(), sensor.temperature.to_string() + "C"].into_iter(), // TODO: Change this based on temperature type
- Style::default().fg(Color::LightGreen),
- )
- });
+ // Draw!
+ draw_data(&mut terminal, &app_data)?;
+ }
- let disk_rows = app.list_of_disks.iter().map(|disk| {
- Row::StyledData(
- vec![
- disk.name.to_string(),
- disk.mount_point.to_string(),
- format!("{:.2}%", disk.used_space as f64 / disk.total_space as f64 * 100_f64),
- (disk.free_space / 1024).to_string() + "GB",
- (disk.total_space / 1024).to_string() + "GB",
- ]
- .into_iter(), // TODO: Change this based on temperature type
- Style::default().fg(Color::LightGreen),
- )
- });
+ Ok(())
+}
- let mem_total_mb = app.memory.mem_total_in_mb as f64;
- let process_rows = app.list_of_processes.iter().map(|process| {
- Row::StyledData(
- vec![
- process.pid.to_string(),
- process.command.to_string(),
- format!("{:.2}%", process.cpu_usage_percent),
- format!("{:.2}%", process.mem_usage_in_mb as f64 / mem_total_mb * 100_f64),
- ]
- .into_iter(),
- Style::default().fg(Color::LightGreen),
- )
- });
+fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, app_data : &widgets::Data) -> Result<(), io::Error> {
+ // Convert data into tui components
+ let temperature_rows = app_data.list_of_temperature.iter().map(|sensor| {
+ Row::StyledData(
+ vec![sensor.component_name.to_string(), sensor.temperature.to_string() + "C"].into_iter(), // TODO: Change this based on temperature type
+ Style::default().fg(Color::LightGreen),
+ )
+ });
+
+ let disk_rows = app_data.list_of_disks.iter().map(|disk| {
+ Row::StyledData(
+ vec![
+ disk.name.to_string(),
+ disk.mount_point.to_string(),
+ format!("{:.2}%", disk.used_space as f64 / disk.total_space as f64 * 100_f64),
+ (disk.free_space / 1024).to_string() + "GB",
+ (disk.total_space / 1024).to_string() + "GB",
+ ]
+ .into_iter(), // TODO: Change this based on temperature type
+ Style::default().fg(Color::LightGreen),
+ )
+ });
+
+ let mem_total_mb = app_data.memory.mem_total_in_mb as f64;
+ let process_rows = app_data.list_of_processes.iter().map(|process| {
+ Row::StyledData(
+ vec![
+ process.pid.to_string(),
+ process.command.to_string(),
+ format!("{:.2}%", process.cpu_usage_percent),
+ format!("{:.2}%", process.mem_usage_in_mb as f64 / mem_total_mb * 100_f64),
+ ]
+ .into_iter(),
+ Style::default().fg(Color::LightGreen),
+ )
+ });
+
+ terminal.draw(|mut f| {
+ let vertical_chunks = Layout::default()
+ .direction(Direction::Vertical)
+ .margin(1)
+ .constraints([Constraint::Percentage(30), Constraint::Percentage(40), Constraint::Percentage(30)].as_ref())
+ .split(f.size());
+ let top_chunks = Layout::default()
+ .direction(Direction::Horizontal)
+ .margin(0)
+ .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
+ .split(vertical_chunks[0]);
+ let middle_chunks = Layout::default()
+ .direction(Direction::Horizontal)
+ .margin(0)
+ .constraints([Constraint::Percentage(40), Constraint::Percentage(60)].as_ref())
+ .split(vertical_chunks[1]);
+ let middle_divided_chunk = Layout::default()
+ .direction(Direction::Vertical)
+ .margin(0)
+ .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
+ .split(middle_chunks[0]);
+ let bottom_chunks = Layout::default()
+ .direction(Direction::Horizontal)
+ .margin(0)
+ .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
+ .split(vertical_chunks[2]);
+
+ // Set up blocks and their components
+
+ // CPU usage graph
+ Chart::default()
+ .block(Block::default().title("CPU Usage").borders(Borders::ALL))
+ .x_axis(Axis::default().style(Style::default().fg(Color::White)).bounds([0.0, 10.0]).labels(&["0.0", "10.0"]))
+ .y_axis(Axis::default().style(Style::default().fg(Color::White)).bounds([0.0, 10.0]).labels(&["0.0", "10.0"]))
+ .datasets(&[
+ Dataset::default()
+ .name("data1")
+ .marker(Marker::Dot)
+ .style(Style::default().fg(Color::Cyan))
+ .data(&[(0.0, 5.0), (1.0, 6.0), (1.5, 6.434)]),
+ Dataset::default()
+ .name("data2")
+ .marker(Marker::Braille)
+ .style(Style::default().fg(Color::Magenta))
+ .data(&[(4.0, 5.0), (5.0, 8.0), (7.66, 13.5)]),
+ ])
+ .render(&mut f, top_chunks[0]);
+
+ //Memory usage graph
+ Block::default().title("Memory Usage").borders(Borders::ALL).render(&mut f, top_chunks[1]);
+
+ // Temperature table
+ Table::new(["Sensor", "Temperature"].iter(), temperature_rows)
+ .block(Block::default().title("Temperatures").borders(Borders::ALL))
+ .header_style(Style::default().fg(Color::LightBlue))
+ .widths(&[25, 25])
+ .render(&mut f, middle_divided_chunk[0]);
+
+ // Disk usage table
+ Table::new(["Disk", "Mount", "Used", "Total", "Free"].iter(), disk_rows)
+ .block(Block::default().title("Disk Usage").borders(Borders::ALL))
+ .header_style(Style::default().fg(Color::LightBlue))
+ .widths(&[25, 25, 10, 10, 10])
+ .render(&mut f, middle_divided_chunk[1]);
+
+ // IO graph
+ Block::default().title("IO Usage").borders(Borders::ALL).render(&mut f, middle_chunks[1]);
+
+ // Network graph
+ Block::default().title("Network").borders(Borders::ALL).render(&mut f, bottom_chunks[0]);
+
+ // Processes table
+ Table::new(["PID", "Command", "CPU%", "Mem%"].iter(), process_rows)
+ .block(Block::default().title("Processes").borders(Borders::ALL))
+ .header_style(Style::default().fg(Color::LightBlue))
+ .widths(&[5, 15, 10, 10])
+ .render(&mut f, bottom_chunks[1]);
+ })?;
- // Draw!
- terminal.draw(|mut f| {
- let vertical_chunks = Layout::default()
- .direction(Direction::Vertical)
- .margin(1)
- .constraints([Constraint::Percentage(30), Constraint::Percentage(40), Constraint::Percentage(30)].as_ref())
- .split(f.size());
- let top_chunks = Layout::default()
- .direction(Direction::Horizontal)
- .margin(0)
- .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
- .split(vertical_chunks[0]);
- let middle_chunks = Layout::default()
- .direction(Direction::Horizontal)
- .margin(0)
- .constraints([Constraint::Percentage(40), Constraint::Percentage(60)].as_ref())
- .split(vertical_chunks[1]);
- let middle_divided_chunk = Layout::default()
- .direction(Direction::Vertical)
- .margin(0)
- .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
- .split(middle_chunks[0]);
- let bottom_chunks = Layout::default()
- .direction(Direction::Horizontal)
- .margin(0)
- .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
- .split(vertical_chunks[2]);
-
- // Set up blocks and their components
-
- // CPU usage graph
- Chart::default()
- .block(Block::default().title("CPU Usage").borders(Borders::ALL))
- .x_axis(Axis::default().style(Style::default().fg(Color::White)).bounds([0.0, 10.0]).labels(&["0.0", "10.0"]))
- .y_axis(Axis::default().style(Style::default().fg(Color::White)).bounds([0.0, 10.0]).labels(&["0.0", "10.0"]))
- .datasets(&[
- Dataset::default()
- .name("data1")
- .marker(Marker::Dot)
- .style(Style::default().fg(Color::Cyan))
- .data(&[(0.0, 5.0), (1.0, 6.0), (1.5, 6.434)]),
- Dataset::default()
- .name("data2")
- .marker(Marker::Braille)
- .style(Style::default().fg(Color::Magenta))
- .data(&[(4.0, 5.0), (5.0, 8.0), (7.66, 13.5)]),
- ])
- .render(&mut f, top_chunks[0]);
-
- //Memory usage graph
- Block::default().title("Memory Usage").borders(Borders::ALL).render(&mut f, top_chunks[1]);
-
- // Temperature table
- Table::new(["Sensor", "Temperature"].iter(), temperature_rows)
- .block(Block::default().title("Temperatures").borders(Borders::ALL))
- .header_style(Style::default().fg(Color::LightBlue))
- .widths(&[25, 25])
- .render(&mut f, middle_divided_chunk[0]);
-
- // Disk usage table
- Table::new(["Disk", "Mount", "Used", "Total", "Free"].iter(), disk_rows)
- .block(Block::default().title("Disk Usage").borders(Borders::ALL))
- .header_style(Style::default().fg(Color::LightBlue))
- .widths(&[25, 25, 10, 10, 10])
- .render(&mut f, middle_divided_chunk[1]);
-
- // IO graph
- Block::default().title("IO Usage").borders(Borders::ALL).render(&mut f, middle_chunks[1]);
-
- // Network graph
- Block::default().title("Network").borders(Borders::ALL).render(&mut f, bottom_chunks[0]);
-
- // Processes table
- Table::new(["PID", "Command", "CPU%", "Mem%"].iter(), process_rows)
- .block(Block::default().title("Processes").borders(Borders::ALL))
- .header_style(Style::default().fg(Color::LightBlue))
- .widths(&[5, 15, 10, 10])
- .render(&mut f, bottom_chunks[1]);
- })?;
- }
+ Ok(())
+}
+
+fn init_logger() -> Result<(), fern::InitError> {
+ fern::Dispatch::new()
+ .format(|out, message, record| {
+ out.finish(format_args!(
+ "{}[{}][{}] {}",
+ chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
+ record.target(),
+ record.level(),
+ message
+ ))
+ })
+ .level(log::LevelFilter::Debug)
+ .chain(fern::log_file("debug.log")?)
+ .apply()?;
Ok(())
}
+
+fn try_debug(result_log : &Result<(), fern::InitError>, message : &str) {
+ if result_log.is_ok() {
+ debug!("{}", message);
+ }
+}