use anyhow::Result;
use ratatui::widgets::TableState;
use signal_hook::{consts::SIGINT, consts::SIGTERM, iterator::Signals};
use std::sync::mpsc;
use std::thread;
use sysinfo::{System, SystemExt};
use crate::action_menu::{generate_known_menu_actions, MenuAction};
use crate::appdata::{Ordering, WindowFocus};
use crate::logs::print_logs;
use crate::sysinfo::{ProcessStat, SystemProcStats, SystemStat};
use crate::tui::Tui;
#[derive(Debug, Default)]
pub struct App {
pub should_quit: bool,
pub window_focus: WindowFocus,
pub process_cursor: usize,
pub proc_stats: SystemProcStats,
pub previous_proc_stats: SystemProcStats,
pub sys_stat: SystemStat,
pub previous_stat: SystemStat,
pub init_stat: SystemStat,
pub filter_text: String,
pub filtered_processes: Vec<ProcessStat>,
pub menu_action_cursor: usize,
pub known_menu_actions: Vec<MenuAction>,
pub proc_list_table_state: TableState,
pub horizontal_scroll: i32,
pub sysinfo_scroll: i32,
pub sysinfo_sys: System,
pub ordering: Ordering,
pub error_message: Option<String>,
pub info_message: Option<String>,
pub info_lines_num: Option<usize>,
pub info_message_scroll: usize,
pub group_by_exe: bool,
}
impl App {
pub fn new() -> Self {
Self {
known_menu_actions: generate_known_menu_actions(),
sysinfo_sys: System::new_all(),
..Default::default()
}
}
pub fn run(&mut self) -> Result<()> {
let signal_rx = self.handle_signals();
self.refresh_system_stats();
self.refresh_processes();
self.init_stat = self.sys_stat.clone();
let mut tui = Tui::new();
tui.enter()?;
while !self.should_quit {
tui.draw(self)?;
tui.handle_events(self)?;
signal_rx.try_recv().ok().map(|_| {
self.quit();
});
}
tui.exit()?;
print_logs();
Ok(())
}
pub fn handle_signals(&mut self) -> mpsc::Receiver<i32> {
let (tx, rx) = mpsc::channel();
let mut signals = Signals::new(&[SIGINT, SIGTERM]).unwrap();
thread::spawn(move || {
for sig in signals.forever() {
println!("Received signal {:?}", sig);
tx.send(sig).unwrap();
}
});
return rx;
}
pub fn tick(&mut self) {
self.previous_stat = self.sys_stat.clone();
self.refresh_system_stats();
}
pub fn quit(&mut self) {
self.should_quit = true;
}
}