Refactoring - moved canvas into its own struct... time to do some more fun optimization.

This commit is contained in:
ClementTsang 2020-02-04 22:44:49 -05:00
parent 41d56d8a9b
commit e0115624a9
2 changed files with 908 additions and 891 deletions

View File

@ -155,10 +155,14 @@ fn gen_n_colours(num_to_gen: i32) -> Vec<Color> {
colour_vec
}
#[allow(unused_variables)]
pub fn draw_data<B: backend::Backend>(
terminal: &mut Terminal<B>, app_state: &mut app::App,
) -> error::Result<()> {
#[derive(Default)]
/// Handles the canvas' state.
pub struct Painter {}
impl Painter {
pub fn draw_data<B: backend::Backend>(
&mut self, terminal: &mut Terminal<B>, app_state: &mut app::App,
) -> error::Result<()> {
terminal.autoresize()?;
terminal.draw(|mut f| {
if app_state.show_help {
@ -279,6 +283,7 @@ pub fn draw_data<B: backend::Backend>(
app_state.show_dd = false;
}
} else {
// TODO: [TUI] Change this back to a more even 33/33/34 when TUI releases
let vertical_chunks = Layout::default()
.direction(Direction::Vertical)
.margin(1)
@ -304,12 +309,6 @@ pub fn draw_data<B: backend::Backend>(
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
.split(middle_chunks[1]);
let middle_divide_chunk_3 = Layout::default()
.direction(Direction::Horizontal)
.margin(0)
.constraints([Constraint::Percentage(40), Constraint::Percentage(60)].as_ref())
.split(middle_divided_chunk_2[0]);
let bottom_chunks = Layout::default()
.direction(Direction::Horizontal)
.margin(0)
@ -355,24 +354,24 @@ pub fn draw_data<B: backend::Backend>(
// Set up blocks and their components
// CPU graph
draw_cpu_graph(&mut f, &app_state, cpu_chunk[graph_index]);
self.draw_cpu_graph(&mut f, &app_state, cpu_chunk[graph_index]);
// CPU legend
draw_cpu_legend(&mut f, app_state, cpu_chunk[legend_index]);
self.draw_cpu_legend(&mut f, app_state, cpu_chunk[legend_index]);
//Memory usage graph
draw_memory_graph(&mut f, &app_state, middle_chunks[0]);
self.draw_memory_graph(&mut f, &app_state, middle_chunks[0]);
// Network graph
draw_network_graph(&mut f, &app_state, network_chunk[0]);
self.draw_network_graph(&mut f, &app_state, network_chunk[0]);
draw_network_labels(&mut f, app_state, network_chunk[1]);
self.draw_network_labels(&mut f, app_state, network_chunk[1]);
// Temperature table
draw_temp_table(&mut f, app_state, middle_divided_chunk_2[0]);
self.draw_temp_table(&mut f, app_state, middle_divided_chunk_2[0]);
// Disk usage table
draw_disk_table(&mut f, app_state, middle_divided_chunk_2[1]);
self.draw_disk_table(&mut f, app_state, middle_divided_chunk_2[1]);
// Processes table
if app_state.is_searching() {
@ -395,18 +394,20 @@ pub fn draw_data<B: backend::Backend>(
)
.split(bottom_chunks[1]);
draw_processes_table(&mut f, app_state, processes_chunk[0]);
draw_search_field(&mut f, app_state, processes_chunk[1]);
self.draw_processes_table(&mut f, app_state, processes_chunk[0]);
self.draw_search_field(&mut f, app_state, processes_chunk[1]);
} else {
draw_processes_table(&mut f, app_state, bottom_chunks[1]);
self.draw_processes_table(&mut f, app_state, bottom_chunks[1]);
}
}
})?;
Ok(())
}
}
fn draw_cpu_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect) {
fn draw_cpu_graph<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect,
) {
let cpu_data: &[ConvertedCpuData] = &app_state.canvas_data.cpu_data;
// CPU usage graph
@ -471,11 +472,11 @@ fn draw_cpu_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, d
.y_axis(y_axis)
.datasets(&dataset_vector)
.render(f, draw_loc);
}
}
fn draw_cpu_legend<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
fn draw_cpu_legend<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
let cpu_data: &[ConvertedCpuData] = &(app_state.canvas_data.cpu_data);
let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
@ -549,13 +550,13 @@ fn draw_cpu_legend<B: backend::Backend>(
.collect::<Vec<_>>()),
)
.render(f, draw_loc);
}
}
#[allow(dead_code)]
fn draw_memory_table<B: backend::Backend>(
#[allow(dead_code)]
fn draw_memory_table<B: backend::Backend>(
f: &mut Frame<B>, app_state: &app::App, memory_entry: Vec<String>, swap_entry: Vec<String>,
draw_loc: Rect,
) {
) {
// Calculate widths
let width = f64::from(draw_loc.width);
let width_ratios = [0.2, 0.4, 0.4];
@ -588,9 +589,11 @@ fn draw_memory_table<B: backend::Backend>(
.collect::<Vec<_>>()),
)
.render(f, draw_loc);
}
}
fn draw_memory_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect) {
fn draw_memory_graph<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect,
) {
let mem_data: &[(f64, f64)] = &(app_state.canvas_data.mem_data);
let swap_data: &[(f64, f64)] = &(app_state.canvas_data.swap_data);
@ -642,9 +645,11 @@ fn draw_memory_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App
.y_axis(y_axis)
.datasets(&mem_canvas_vec)
.render(f, draw_loc);
}
}
fn draw_network_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect) {
fn draw_network_graph<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &app::App, draw_loc: Rect,
) {
let network_data_rx: &[(f64, f64)] = &(app_state.canvas_data.network_data_rx);
let network_data_tx: &[(f64, f64)] = &(app_state.canvas_data.network_data_tx);
@ -688,11 +693,11 @@ fn draw_network_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::Ap
.data(&network_data_tx),
])
.render(f, draw_loc);
}
}
fn draw_network_labels<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
fn draw_network_labels<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
let rx_display: String = app_state.canvas_data.rx_display.clone();
let tx_display: String = app_state.canvas_data.tx_display.clone();
let total_rx_display: String = app_state.canvas_data.total_rx_display.clone();
@ -753,11 +758,11 @@ fn draw_network_labels<B: backend::Backend>(
.collect::<Vec<_>>()),
)
.render(f, draw_loc);
}
}
fn draw_temp_table<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
fn draw_temp_table<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
let temp_sensor_data: &[Vec<String>] = &(app_state.canvas_data.temp_sensor_data);
let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
@ -820,11 +825,11 @@ fn draw_temp_table<B: backend::Backend>(
.collect::<Vec<_>>()),
)
.render(f, draw_loc);
}
}
fn draw_disk_table<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
fn draw_disk_table<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
let disk_data: &[Vec<String>] = &(app_state.canvas_data.disk_data);
let num_rows = max(0, i64::from(draw_loc.height) - 5) as u64;
let start_position = get_start_position(
@ -887,11 +892,11 @@ fn draw_disk_table<B: backend::Backend>(
.collect::<Vec<_>>()),
)
.render(f, draw_loc);
}
}
fn draw_search_field<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
fn draw_search_field<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
let width = max(0, draw_loc.width as i64 - 34) as u64;
let query = app_state.get_current_search_query();
let shrunk_query = if query.len() < width as usize {
@ -902,9 +907,8 @@ fn draw_search_field<B: backend::Backend>(
let cursor_position = app_state.get_cursor_position();
let query_with_cursor: Vec<Text> = if let app::WidgetPosition::ProcessSearch =
app_state.current_widget_selected
{
let query_with_cursor: Vec<Text> =
if let app::WidgetPosition::ProcessSearch = app_state.current_widget_selected {
if cursor_position >= query.len() {
let mut q = vec![Text::styled(
shrunk_query.to_string(),
@ -922,7 +926,9 @@ fn draw_search_field<B: backend::Backend>(
.chars()
.enumerate()
.map(|(itx, c)| {
if let app::WidgetPosition::ProcessSearch = app_state.current_widget_selected {
if let app::WidgetPosition::ProcessSearch =
app_state.current_widget_selected
{
if itx == cursor_position {
return Text::styled(
c.to_string(),
@ -1005,11 +1011,11 @@ fn draw_search_field<B: backend::Backend>(
.alignment(Alignment::Left)
.wrap(false)
.render(f, draw_loc);
}
}
fn draw_processes_table<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
fn draw_processes_table<B: backend::Backend>(
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
let process_data: &[ConvertedProcessData] = &app_state.canvas_data.finalized_process_data;
// Admittedly this is kinda a hack... but we need to:
@ -1036,7 +1042,8 @@ fn draw_processes_table<B: backend::Backend>(
position
};
let sliced_vec: Vec<ConvertedProcessData> = (&process_data[start_position as usize..]).to_vec();
let sliced_vec: Vec<ConvertedProcessData> =
(&process_data[start_position as usize..]).to_vec();
let mut process_counter: i64 = 0;
// Draw!
@ -1129,6 +1136,7 @@ fn draw_processes_table<B: backend::Backend>(
.collect::<Vec<_>>()),
)
.render(f, draw_loc);
}
}
/// A somewhat jury-rigged solution to simulate a variable intrinsic layout for

View File

@ -230,8 +230,9 @@ fn main() -> error::Result<()> {
});
}
let mut painter = canvas::Painter::default();
loop {
// TODO: [OPT] this should not block... let's properly use tick rates and non-blocking, okay?
// TODO: [OPT] this should not block...
if let Ok(recv) = rx.recv_timeout(Duration::from_millis(TICK_RATE_IN_MILLISECONDS)) {
match recv {
Event::KeyInput(event) => {
@ -372,18 +373,26 @@ fn main() -> error::Result<()> {
}
}
// Draw!
if let Err(err) = canvas::draw_data(&mut terminal, &mut app) {
cleanup_terminal(&mut terminal)?;
error!("{}", err);
return Err(err);
}
try_drawing(&mut terminal, &mut app, &mut painter)?;
}
cleanup_terminal(&mut terminal)?;
Ok(())
}
fn try_drawing(
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
app: &mut app::App, painter: &mut canvas::Painter,
) -> error::Result<()> {
if let Err(err) = painter.draw_data(terminal, app) {
cleanup_terminal(terminal)?;
error!("{}", err);
return Err(err);
}
Ok(())
}
fn cleanup_terminal(
terminal: &mut tui::terminal::Terminal<tui::backend::CrosstermBackend<std::io::Stdout>>,
) -> error::Result<()> {