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,9 +155,13 @@ fn gen_n_colours(num_to_gen: i32) -> Vec<Color> {
colour_vec
}
#[allow(unused_variables)]
#[derive(Default)]
/// Handles the canvas' state.
pub struct Painter {}
impl Painter {
pub fn draw_data<B: backend::Backend>(
terminal: &mut Terminal<B>, app_state: &mut app::App,
&mut self, terminal: &mut Terminal<B>, app_state: &mut app::App,
) -> error::Result<()> {
terminal.autoresize()?;
terminal.draw(|mut f| {
@ -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,10 +394,10 @@ 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]);
}
}
})?;
@ -406,7 +405,9 @@ pub fn draw_data<B: backend::Backend>(
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
@ -474,7 +475,7 @@ fn draw_cpu_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, d
}
fn draw_cpu_legend<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
let cpu_data: &[ConvertedCpuData] = &(app_state.canvas_data.cpu_data);
@ -590,7 +591,9 @@ fn draw_memory_table<B: backend::Backend>(
.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);
@ -644,7 +647,9 @@ fn draw_memory_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App
.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);
@ -691,7 +696,7 @@ fn draw_network_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::Ap
}
fn draw_network_labels<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
&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();
@ -756,7 +761,7 @@ fn draw_network_labels<B: backend::Backend>(
}
fn draw_temp_table<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
&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);
@ -823,7 +828,7 @@ fn draw_temp_table<B: backend::Backend>(
}
fn draw_disk_table<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
&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;
@ -890,7 +895,7 @@ fn draw_disk_table<B: backend::Backend>(
}
fn draw_search_field<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
&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();
@ -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(),
@ -1008,7 +1014,7 @@ fn draw_search_field<B: backend::Backend>(
}
fn draw_processes_table<B: backend::Backend>(
f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
&self, f: &mut Frame<B>, app_state: &mut app::App, draw_loc: Rect,
) {
let process_data: &[ConvertedProcessData] = &app_state.canvas_data.finalized_process_data;
@ -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!
@ -1130,6 +1137,7 @@ fn draw_processes_table<B: backend::Backend>(
)
.render(f, draw_loc);
}
}
/// A somewhat jury-rigged solution to simulate a variable intrinsic layout for
/// table widths. Note that this will do one main pass to try to properly

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<()> {