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_cells_wrap_flags: Vec<bool>,     // Wrap flags captured with pane_cells
21    pub(crate) pane_scrollback_len: usize,           // Cached scrollback_len for pane rendering
22}
23
24impl RenderCache {
25    pub(crate) fn new() -> Self {
26        Self {
27            cells: None,
28            generation: 0,
29            scroll_offset: 0,
30            cursor_pos: None,
31            selection: None,
32            grid_dims: (0, 0),
33            terminal_title: String::new(),
34            scrollback_len: 0,
35            pane_cells: None,
36            pane_cells_generation: 0,
37            pane_cells_scroll_offset: 0,
38            pane_cells_selection: None,
39            pane_cells_grid_dims: (0, 0),
40            pane_cells_wrap_flags: Vec::new(),
41            pane_scrollback_len: 0,
42        }
43    }
44
45    /// Force the next `gather_pane_render_data` call to regather cells for this
46    /// pane instead of reusing the cross-frame cache.
47    ///
48    /// Needed for frontend-driven mutations that change rendered cell content
49    /// without going through the PTY reader thread (which is the only place
50    /// `update_generation` is bumped) — e.g. theme changes or `clear_scrollback()`.
51    pub(crate) fn invalidate_pane_cells(&mut self) {
52        self.pane_cells = None;
53        self.pane_cells_generation = 0;
54    }
55}
56
57impl Default for RenderCache {
58    fn default() -> Self {
59        Self::new()
60    }
61}