Skip to main content

emux_render/
damage.rs

1//! Damage tracking for incremental screen updates.
2
3/// Tracks which rows need redrawing to avoid full-screen repaints.
4pub struct DamageTracker {
5    dirty_rows: Vec<bool>,
6    full_redraw: bool,
7}
8
9impl DamageTracker {
10    /// Create a new tracker with the given number of rows, initially marked for full redraw.
11    pub fn new(rows: usize) -> Self {
12        Self {
13            dirty_rows: vec![false; rows],
14            full_redraw: true,
15        }
16    }
17
18    /// Mark a single row as dirty.
19    pub fn mark_row(&mut self, row: usize) {
20        if row < self.dirty_rows.len() {
21            self.dirty_rows[row] = true;
22        }
23    }
24
25    /// Mark all rows for redraw.
26    pub fn mark_all(&mut self) {
27        self.full_redraw = true;
28    }
29
30    /// Clear all damage state.
31    pub fn clear(&mut self) {
32        for d in &mut self.dirty_rows {
33            *d = false;
34        }
35        self.full_redraw = false;
36    }
37
38    /// Check whether a specific row needs redrawing.
39    pub fn is_dirty(&self, row: usize) -> bool {
40        self.full_redraw || self.dirty_rows.get(row).copied().unwrap_or(false)
41    }
42
43    /// Check whether any redraw is needed at all.
44    pub fn needs_redraw(&self) -> bool {
45        self.full_redraw || self.dirty_rows.iter().any(|&d| d)
46    }
47
48    /// Return a list of row indices that need redrawing.
49    pub fn dirty_rows(&self) -> Vec<usize> {
50        (0..self.dirty_rows.len())
51            .filter(|&r| self.is_dirty(r))
52            .collect()
53    }
54
55    /// Resize the tracker to a new row count, marking a full redraw.
56    pub fn resize(&mut self, rows: usize) {
57        self.dirty_rows.resize(rows, false);
58        self.full_redraw = true;
59    }
60}