Skip to main content

par_term/pane/
render_cache.rs

1use crate::config::Cell;
2use crate::selection::Selection;
3use std::sync::Arc;
4
5/// State related to render caching and dirty tracking
6pub struct RenderCache {
7    pub(crate) cells: Option<Arc<Vec<Cell>>>, // Cached cells from last render (dirty tracking; Arc avoids double-clone on cache hit)
8    pub(crate) generation: u64, // Last terminal generation number (for dirty tracking)
9    pub(crate) scroll_offset: usize, // Last scroll offset (for cache invalidation)
10    pub(crate) cursor_pos: Option<(usize, usize)>, // Last cursor position (for cache invalidation)
11    pub(crate) selection: Option<Selection>, // Last selection state (for cache invalidation)
12    pub(crate) grid_dims: (usize, usize), // Last known terminal grid dimensions (cols, rows)
13    pub(crate) terminal_title: String, // Last known terminal title (for change detection)
14    pub(crate) scrollback_len: usize, // Last known scrollback length
15    pub(crate) pane_cells: Option<Arc<Vec<Cell>>>, // Cached cells for pane rendering (reuse across frames)
16    pub(crate) pane_cells_generation: u64, // Generation of cached pane_cells (0 = stale/unset)
17    pub(crate) pane_cells_scroll_offset: usize, // Scroll offset used when pane_cells was generated
18    pub(crate) pane_cells_selection: Option<Selection>, // Selection used when pane_cells was generated
19    pub(crate) pane_cells_grid_dims: (usize, usize), // Grid dimensions used when pane_cells was generated
20    pub(crate) pane_scrollback_len: usize,           // Cached scrollback_len for pane rendering
21}
22
23impl RenderCache {
24    pub(crate) fn new() -> Self {
25        Self {
26            cells: None,
27            generation: 0,
28            scroll_offset: 0,
29            cursor_pos: None,
30            selection: None,
31            grid_dims: (0, 0),
32            terminal_title: String::new(),
33            scrollback_len: 0,
34            pane_cells: None,
35            pane_cells_generation: 0,
36            pane_cells_scroll_offset: 0,
37            pane_cells_selection: None,
38            pane_cells_grid_dims: (0, 0),
39            pane_scrollback_len: 0,
40        }
41    }
42
43    /// Force the next `gather_pane_render_data` call to regather cells for this
44    /// pane instead of reusing the cross-frame cache.
45    ///
46    /// Needed for frontend-driven mutations that change rendered cell content
47    /// without going through the PTY reader thread (which is the only place
48    /// `update_generation` is bumped) — e.g. theme changes or `clear_scrollback()`.
49    pub(crate) fn invalidate_pane_cells(&mut self) {
50        self.pane_cells = None;
51        self.pane_cells_generation = 0;
52    }
53}
54
55impl Default for RenderCache {
56    fn default() -> Self {
57        Self::new()
58    }
59}