Skip to content

Commit 028a65d

Browse files
committed
minor refactor
1 parent c802c3a commit 028a65d

File tree

3 files changed

+16
-10
lines changed

3 files changed

+16
-10
lines changed

packages/iocraft/src/canvas.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{
99
};
1010
use unicode_width::UnicodeWidthChar;
1111

12-
#[derive(Clone)]
12+
#[derive(Clone, Debug, PartialEq)]
1313
struct Character {
1414
value: char,
1515
style: CanvasTextStyle,
@@ -28,7 +28,7 @@ pub struct CanvasTextStyle {
2828
pub underline: bool,
2929
}
3030

31-
#[derive(Clone, Default)]
31+
#[derive(Clone, Default, PartialEq)]
3232
struct Cell {
3333
background_color: Option<Color>,
3434
character: Option<Character>,
@@ -43,6 +43,7 @@ impl Cell {
4343
/// Canvas is a low-level abstraction for rendering output. Most users of the library will not need
4444
/// to use it directly. However, it is used by low level component implementations and can be used
4545
/// to store and copy their output.
46+
#[derive(Clone, PartialEq)]
4647
pub struct Canvas {
4748
width: usize,
4849
cells: Vec<Vec<Cell>>,

packages/iocraft/src/render.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -354,18 +354,19 @@ impl<'a> Tree<'a> {
354354
W: Write,
355355
{
356356
let mut terminal = Terminal::new()?;
357-
let mut lines_to_rewind_to_clear = 0;
357+
let mut prev_canvas: Option<Canvas> = None;
358358
loop {
359359
let width = terminal.width().ok().map(|w| w as usize);
360360
execute!(w, terminal::BeginSynchronizedUpdate,)?;
361+
let lines_to_rewind_to_clear = prev_canvas.as_ref().map_or(0, |c| c.height());
361362
let output = self.render(width, Some(&mut terminal), lines_to_rewind_to_clear);
362-
if !output.did_clear_terminal_output && lines_to_rewind_to_clear > 0 {
363-
terminal.rewind_lines(lines_to_rewind_to_clear as _)?;
363+
if output.did_clear_terminal_output || prev_canvas.as_ref() != Some(&output.canvas) {
364+
if !output.did_clear_terminal_output {
365+
terminal.rewind_lines(lines_to_rewind_to_clear as _)?;
366+
}
367+
output.canvas.write_ansi(&mut w)?;
364368
}
365-
// TODO: if we wanted to be efficient and the terminal wasn't cleared, we could
366-
// only write the diff
367-
output.canvas.write_ansi(&mut w)?;
368-
lines_to_rewind_to_clear = output.canvas.height();
369+
prev_canvas = Some(output.canvas);
369370
execute!(w, terminal::EndSynchronizedUpdate)?;
370371
if self.system_context.should_exit() || terminal.received_ctrl_c() {
371372
break;

packages/iocraft/src/terminal.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,11 @@ impl Terminal {
181181
}
182182

183183
pub fn rewind_lines(&mut self, lines: u16) -> io::Result<()> {
184-
self.inner.rewind_lines(lines)
184+
if lines > 0 {
185+
self.inner.rewind_lines(lines)
186+
} else {
187+
Ok(())
188+
}
185189
}
186190

187191
pub fn received_ctrl_c(&self) -> bool {

0 commit comments

Comments
 (0)