vizia_core/
cache.rs

1//! The cache is a store for intermediate data produced while computing state, notably layout
2//! results. The main type here is CachedData, usually accessed via `cx.cache`.
3
4use crate::prelude::*;
5use skia_safe::{Matrix, Path};
6use vizia_storage::SparseSet;
7
8/// Stores data which can be cached between system runs.
9///
10/// When an event occurs or style data is changed systems run to determine the new state of the UI.
11/// The output of these systems can be cached so that not all of the systems need to run again.
12#[derive(Default)]
13pub struct CachedData {
14    pub(crate) bounds: SparseSet<BoundingBox>,
15    pub(crate) draw_bounds: SparseSet<BoundingBox>,
16    pub(crate) relative_bounds: SparseSet<BoundingBox>,
17    pub(crate) geo_changed: SparseSet<GeoChanged>,
18    pub(crate) transform: SparseSet<Matrix>,
19    pub(crate) clip_path: SparseSet<BoundingBox>,
20    pub(crate) path: SparseSet<Path>,
21}
22
23impl CachedData {
24    pub(crate) fn add(&mut self, entity: Entity) {
25        self.bounds.insert(entity, Default::default());
26        self.relative_bounds.insert(entity, Default::default());
27        self.geo_changed.insert(entity, GeoChanged::empty());
28        self.transform.insert(entity, Matrix::new_identity());
29    }
30
31    pub(crate) fn remove(&mut self, entity: Entity) {
32        self.bounds.remove(entity);
33        self.relative_bounds.remove(entity);
34        self.draw_bounds.remove(entity);
35        self.geo_changed.remove(entity);
36        self.transform.remove(entity);
37        self.clip_path.remove(entity);
38        self.path.remove(entity);
39    }
40
41    /// Returns the bounding box of the entity, determined by the layout system.
42    pub fn get_bounds(&self, entity: Entity) -> BoundingBox {
43        self.bounds.get(entity).cloned().unwrap()
44    }
45
46    /// Returns the x position of the entity.
47    pub fn get_posx(&self, entity: Entity) -> f32 {
48        self.bounds.get(entity).map_or(0.0, |b| b.x)
49    }
50
51    /// Returns the y position of the entity.
52    pub fn get_posy(&self, entity: Entity) -> f32 {
53        self.bounds.get(entity).map_or(0.0, |b| b.y)
54    }
55
56    /// Returns the width of the entity.
57    pub fn get_width(&self, entity: Entity) -> f32 {
58        self.bounds.get(entity).map_or(0.0, |b| b.w)
59    }
60
61    /// Returns the height of the entity.
62    pub fn get_height(&self, entity: Entity) -> f32 {
63        self.bounds.get(entity).map_or(0.0, |b| b.h)
64    }
65
66    pub fn set_bounds(&mut self, entity: Entity, bounds: BoundingBox) {
67        if let Some(b) = self.bounds.get_mut(entity) {
68            *b = bounds;
69        }
70    }
71
72    /// Sets the x position of the entity.
73    pub fn set_posx(&mut self, entity: Entity, val: f32) {
74        if let Some(bounds) = self.bounds.get_mut(entity) {
75            bounds.x = val;
76        }
77    }
78
79    /// Sets the y position of the entity.
80    pub fn set_posy(&mut self, entity: Entity, val: f32) {
81        if let Some(bounds) = self.bounds.get_mut(entity) {
82            bounds.y = val;
83        }
84    }
85
86    /// Sets the width of the entity.
87    pub fn set_width(&mut self, entity: Entity, val: f32) {
88        if let Some(bounds) = self.bounds.get_mut(entity) {
89            bounds.w = val;
90        }
91    }
92
93    /// Sets the height of the entity.
94    pub fn set_height(&mut self, entity: Entity, val: f32) {
95        if let Some(bounds) = self.bounds.get_mut(entity) {
96            bounds.h = val;
97        }
98    }
99}