pub struct DifferentialRenderer { /* private fields */ }Expand description
Optimized renderer that only outputs changed cells.
DifferentialRenderer compares the current frame to the previous frame
and renders only the cells that have changed. For typical animations with
small moving objects on static backgrounds, this reduces terminal I/O
by 60-80% or more.
§Performance
- Full render at 80×24: 1920 cells, ~1920 escape codes
- Differential with 5% changes: ~96 cells, ~96 escape codes
- Typical I/O reduction: 60-95%
§Example
use dotmax::animation::DifferentialRenderer;
use dotmax::{BrailleGrid, TerminalRenderer};
let mut diff_renderer = DifferentialRenderer::new();
let mut terminal = TerminalRenderer::new()?;
// First frame renders fully (no previous frame)
let frame1 = BrailleGrid::new(80, 24)?;
diff_renderer.render_diff(&frame1, &mut terminal)?;
// Subsequent frames render only changes
let mut frame2 = BrailleGrid::new(80, 24)?;
frame2.set_dot(10, 10)?; // One changed cell
diff_renderer.render_diff(&frame2, &mut terminal)?; // Only outputs one cell!Implementations§
Source§impl DifferentialRenderer
impl DifferentialRenderer
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Creates a new differential renderer.
The first call to render_diff() will render the full frame
since there’s no previous frame to compare against.
§Examples
use dotmax::animation::DifferentialRenderer;
let renderer = DifferentialRenderer::new();
// First render_diff() call will render the entire frameSourcepub fn render_diff(
&mut self,
current: &BrailleGrid,
renderer: &mut TerminalRenderer,
) -> Result<(), DotmaxError>
pub fn render_diff( &mut self, current: &BrailleGrid, renderer: &mut TerminalRenderer, ) -> Result<(), DotmaxError>
Renders only the cells that changed since the last frame.
Compares current to the stored previous frame and outputs
only the changed cells using ANSI cursor positioning.
§Behavior
- First call: Renders entire grid (no previous frame)
- Dimension mismatch: Renders entire grid (auto-invalidates)
- Normal operation: Renders only changed cells
§Arguments
current- The current frame to renderrenderer- The terminal renderer for full-frame fallback
§Returns
Ok(())- Render completed successfullyErr(DotmaxError)- Terminal I/O error
§Errors
Returns DotmaxError::Terminal if terminal I/O operations fail
(cursor positioning or character output).
§Examples
use dotmax::animation::DifferentialRenderer;
use dotmax::{BrailleGrid, TerminalRenderer};
let mut diff = DifferentialRenderer::new();
let mut terminal = TerminalRenderer::new()?;
let frame = BrailleGrid::new(80, 24)?;
diff.render_diff(&frame, &mut terminal)?;Sourcepub fn invalidate(&mut self)
pub fn invalidate(&mut self)
Forces a full render on the next render_diff() call.
Use this after terminal resize, mode changes, or when the entire screen needs to be refreshed.
§Examples
use dotmax::animation::DifferentialRenderer;
let mut renderer = DifferentialRenderer::new();
// ... after some renders ...
renderer.invalidate(); // Next render_diff() will render full frameSourcepub fn count_changed_cells(
&self,
current: &BrailleGrid,
previous: &BrailleGrid,
) -> usize
pub fn count_changed_cells( &self, current: &BrailleGrid, previous: &BrailleGrid, ) -> usize
Returns the number of cells that would change between two frames.
This is useful for benchmarking and debugging to understand how much I/O reduction differential rendering provides.
§Arguments
current- The current frameprevious- The previous frame to compare against
§Returns
The number of cells that differ between the two frames.
§Examples
use dotmax::animation::DifferentialRenderer;
use dotmax::BrailleGrid;
let renderer = DifferentialRenderer::new();
let mut frame1 = BrailleGrid::new(80, 24).unwrap();
let mut frame2 = BrailleGrid::new(80, 24).unwrap();
frame2.set_dot(10, 10).unwrap();
let changed = renderer.count_changed_cells(&frame2, &frame1);
assert_eq!(changed, 1); // Only one cell changedSourcepub const fn has_previous_frame(&self) -> bool
pub const fn has_previous_frame(&self) -> bool
Returns whether the renderer has a cached previous frame.
§Returns
true- A previous frame is cached (differential rendering enabled)false- No previous frame (next render will be full)
§Examples
use dotmax::animation::DifferentialRenderer;
let renderer = DifferentialRenderer::new();
assert!(!renderer.has_previous_frame());Trait Implementations§
Source§impl Clone for DifferentialRenderer
impl Clone for DifferentialRenderer
Source§impl Debug for DifferentialRenderer
impl Debug for DifferentialRenderer
Auto Trait Implementations§
impl Freeze for DifferentialRenderer
impl RefUnwindSafe for DifferentialRenderer
impl Send for DifferentialRenderer
impl Sync for DifferentialRenderer
impl Unpin for DifferentialRenderer
impl UnwindSafe for DifferentialRenderer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more