perf: increase rendering efficiency (#1017)

* Efficient rendering

* fix unused import

---------

Co-authored-by: Chris Titus <contact@christitus.com>
This commit is contained in:
Andrii 2025-02-28 22:11:50 +01:00 committed by GitHub
parent 5f6e18b2cc
commit 95e6c357d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 2 deletions

View File

@ -24,9 +24,11 @@ use ratatui::{
}, },
Terminal, Terminal,
}; };
use running_command::TERMINAL_UPDATED;
use state::AppState; use state::AppState;
use std::{ use std::{
io::{stdout, Result, Stdout}, io::{stdout, Result, Stdout},
sync::atomic::Ordering,
time::Duration, time::Duration,
}; };
@ -59,9 +61,14 @@ fn main() -> Result<()> {
fn run(terminal: &mut Terminal<CrosstermBackend<Stdout>>, state: &mut AppState) -> Result<()> { fn run(terminal: &mut Terminal<CrosstermBackend<Stdout>>, state: &mut AppState) -> Result<()> {
loop { loop {
terminal.draw(|frame| state.draw(frame)).unwrap();
// Wait for an event // Wait for an event
if !event::poll(Duration::from_millis(10))? { if !event::poll(Duration::from_millis(10))? {
if TERMINAL_UPDATED
.compare_exchange(true, false, Ordering::AcqRel, Ordering::Acquire)
.is_ok()
{
terminal.draw(|frame| state.draw(frame)).unwrap();
}
continue; continue;
} }
@ -84,5 +91,6 @@ fn run(terminal: &mut Terminal<CrosstermBackend<Stdout>>, state: &mut AppState)
} }
_ => {} _ => {}
} }
terminal.draw(|frame| state.draw(frame)).unwrap();
} }
} }

View File

@ -13,7 +13,10 @@ use ratatui::{
use std::{ use std::{
fs::File, fs::File,
io::{Result, Write}, io::{Result, Write},
sync::{Arc, Mutex}, sync::{
atomic::{AtomicBool, Ordering},
Arc, Mutex,
},
thread::JoinHandle, thread::JoinHandle,
}; };
use time::{macros::format_description, OffsetDateTime}; use time::{macros::format_description, OffsetDateTime};
@ -158,6 +161,7 @@ impl FloatContent for RunningCommand {
} }
} }
} }
pub static TERMINAL_UPDATED: AtomicBool = AtomicBool::new(true);
impl RunningCommand { impl RunningCommand {
pub fn new(commands: &[&Command]) -> Self { pub fn new(commands: &[&Command]) -> Self {
@ -217,6 +221,7 @@ impl RunningCommand {
// A buffer, shared between the thread that reads the command output, and the main tread. // A buffer, shared between the thread that reads the command output, and the main tread.
// The main thread only reads the contents // The main thread only reads the contents
let command_buffer: Arc<Mutex<Vec<u8>>> = Arc::new(Mutex::new(Vec::new())); let command_buffer: Arc<Mutex<Vec<u8>>> = Arc::new(Mutex::new(Vec::new()));
TERMINAL_UPDATED.store(true, Ordering::Release);
let reader_handle = { let reader_handle = {
// Arc is just a reference, so we can create an owned copy without any problem // Arc is just a reference, so we can create an owned copy without any problem
let command_buffer = command_buffer.clone(); let command_buffer = command_buffer.clone();
@ -233,8 +238,10 @@ impl RunningCommand {
// done, to minimise the time it is opened // done, to minimise the time it is opened
let command_buffer = mutex.as_mut().unwrap(); let command_buffer = mutex.as_mut().unwrap();
command_buffer.extend_from_slice(&buf[0..size]); command_buffer.extend_from_slice(&buf[0..size]);
TERMINAL_UPDATED.store(true, Ordering::Release);
// The mutex is closed here automatically // The mutex is closed here automatically
} }
TERMINAL_UPDATED.store(true, Ordering::Release);
}) })
}; };