diff options
author | Jesse Luehrs <doy@tozt.net> | 2019-11-10 06:17:09 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2019-11-10 08:08:14 -0500 |
commit | 168a91a9ddc331cd3b8e5c32f7701f2b0973b147 (patch) | |
tree | 6b2df47bf18a731a9814bb875ce231e28cad1bf0 /src | |
parent | b04c0e6e97765aeb888479c5e0bc27d54de60659 (diff) | |
download | vt100-rust-168a91a9ddc331cd3b8e5c32f7701f2b0973b147.tar.gz vt100-rust-168a91a9ddc331cd3b8e5c32f7701f2b0973b147.zip |
optimize attribute setting a bit
Diffstat (limited to 'src')
-rw-r--r-- | src/attrs.rs | 6 | ||||
-rw-r--r-- | src/cell.rs | 13 | ||||
-rw-r--r-- | src/grid.rs | 21 | ||||
-rw-r--r-- | src/row.rs | 28 | ||||
-rw-r--r-- | src/screen.rs | 10 | ||||
-rw-r--r-- | src/term.rs | 35 |
6 files changed, 86 insertions, 27 deletions
diff --git a/src/attrs.rs b/src/attrs.rs index dc46646..4b78771 100644 --- a/src/attrs.rs +++ b/src/attrs.rs @@ -94,13 +94,13 @@ impl Attrs { contents: &mut Vec<u8>, other: &Self, ) { - let attrs = crate::term::Attrs::default(); - if self != other && self == &Self::default() { - write!(contents, "{}", attrs).unwrap(); + write!(contents, "{}", crate::term::ClearAttrs::new()).unwrap(); return; } + let attrs = crate::term::Attrs::default(); + let attrs = if self.fgcolor == other.fgcolor { attrs } else { diff --git a/src/cell.rs b/src/cell.rs index 61a3cd3..b9d7168 100644 --- a/src/cell.rs +++ b/src/cell.rs @@ -11,15 +11,22 @@ pub struct Cell { attrs: crate::attrs::Attrs, } +#[allow(clippy::collapsible_if)] impl PartialEq<Cell> for Cell { fn eq(&self, other: &Self) -> bool { - if self.attrs != other.attrs { - return false; - } if self.len != other.len { return false; } let len = self.len as usize; + if len > 0 { + if self.attrs != other.attrs { + return false; + } + } else { + if self.attrs.bgcolor != other.attrs.bgcolor { + return false; + } + } self.contents[..len] == other.contents[..len] } } diff --git a/src/grid.rs b/src/grid.rs index 1cc4daf..a546c43 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -179,11 +179,14 @@ impl Grid { } } - pub fn write_contents_formatted(&self, contents: &mut Vec<u8>) { + pub fn write_contents_formatted( + &self, + contents: &mut Vec<u8>, + ) -> crate::attrs::Attrs { write!( contents, "{}{}", - crate::term::Attrs::new(), + crate::term::ClearAttrs::new(), crate::term::ClearScreen::new() ) .unwrap(); @@ -211,13 +214,17 @@ impl Grid { write!(contents, "{}", crate::term::MoveTo::new(self.pos)) .unwrap(); } - } - pub fn write_contents_diff(&self, contents: &mut Vec<u8>, prev: &Self) { - write!(contents, "{}", crate::term::Attrs::default()).unwrap(); + prev_attrs + } + pub fn write_contents_diff( + &self, + contents: &mut Vec<u8>, + prev: &Self, + mut prev_attrs: crate::attrs::Attrs, + ) -> crate::attrs::Attrs { let mut prev_pos = prev.pos; - let mut prev_attrs = crate::attrs::Attrs::default(); let mut wrapping = false; for (i, (row, prev_row)) in self.visible_rows().zip(prev.visible_rows()).enumerate() @@ -242,6 +249,8 @@ impl Grid { write!(contents, "{}", crate::term::MoveTo::new(self.pos)) .unwrap(); } + + prev_attrs } pub fn erase_all(&mut self, bgcolor: crate::attrs::Color) { @@ -165,12 +165,13 @@ impl Row { } let attrs = cell.attrs(); - if &prev_attrs != attrs { - attrs.write_escape_code_diff(contents, &prev_attrs); - prev_attrs = *attrs; - } if has_contents { + if &prev_attrs != attrs { + attrs.write_escape_code_diff(contents, &prev_attrs); + prev_attrs = *attrs; + } + // using write! here is significantly slower, for some // reason // write!(contents, "{}", cell.contents()).unwrap(); @@ -179,6 +180,11 @@ impl Row { prev_pos.col += width; new_pos.col += width; } else { + if prev_attrs.bgcolor != attrs.bgcolor { + attrs.write_escape_code_diff(contents, &prev_attrs); + prev_attrs = *attrs; + } + write!( contents, "{}", @@ -262,12 +268,13 @@ impl Row { } let attrs = cell.attrs(); - if &prev_attrs != attrs { - attrs.write_escape_code_diff(contents, &prev_attrs); - prev_attrs = *attrs; - } if cell.has_contents() { + if &prev_attrs != attrs { + attrs.write_escape_code_diff(contents, &prev_attrs); + prev_attrs = *attrs; + } + // using write! here is significantly slower, for some // reason // write!(contents, "{}", cell.contents()).unwrap(); @@ -276,6 +283,11 @@ impl Row { prev_pos.col += width; new_pos.col += width; } else { + if prev_attrs.bgcolor != attrs.bgcolor { + attrs.write_escape_code_diff(contents, &prev_attrs); + prev_attrs = *attrs; + } + write!( contents, "{}", diff --git a/src/screen.rs b/src/screen.rs index b774c10..c2fef6b 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -189,7 +189,8 @@ impl Screen { crate::term::HideCursor::new(self.hide_cursor()) ) .unwrap(); - self.grid().write_contents_formatted(contents); + let prev_attrs = self.grid().write_contents_formatted(contents); + self.attrs.write_escape_code_diff(contents, &prev_attrs); } /// Returns the formatted contents of the terminal by row, restricted to @@ -247,7 +248,12 @@ impl Screen { ) .unwrap(); } - self.grid().write_contents_diff(contents, prev.grid()); + let prev_attrs = self.grid().write_contents_diff( + contents, + prev.grid(), + prev.attrs, + ); + self.attrs.write_escape_code_diff(contents, &prev_attrs); } /// Returns a sequence of terminal byte streams sufficient to turn the diff --git a/src/term.rs b/src/term.rs index ef6c546..074f177 100644 --- a/src/term.rs +++ b/src/term.rs @@ -56,6 +56,21 @@ impl std::fmt::Display for MoveTo { } #[derive(Default, Debug)] +pub struct ClearAttrs; + +impl ClearAttrs { + pub fn new() -> Self { + Self::default() + } +} + +impl std::fmt::Display for ClearAttrs { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("\x1b[m") + } +} + +#[derive(Default, Debug)] pub struct Attrs { fgcolor: Option<crate::attrs::Color>, bgcolor: Option<crate::attrs::Color>, @@ -66,10 +81,6 @@ pub struct Attrs { } impl Attrs { - pub fn new() -> Self { - Self::default() - } - pub fn fgcolor(mut self, fgcolor: crate::attrs::Color) -> Self { self.fgcolor = Some(fgcolor); self @@ -102,8 +113,22 @@ impl Attrs { } impl std::fmt::Display for Attrs { - #[allow(unused_assignments, clippy::cognitive_complexity)] + #[allow( + unused_assignments, + clippy::cognitive_complexity, + clippy::too_many_lines + )] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.fgcolor.is_none() + && self.bgcolor.is_none() + && self.bold.is_none() + && self.italic.is_none() + && self.underline.is_none() + && self.inverse.is_none() + { + return Ok(()); + } + f.write_str("\x1b[")?; let mut first = true; |