lgui_core/renderer/
cache.rs1use std::{cell::RefCell, sync::Arc};
2
3#[derive(Clone, Debug, Default, PartialEq, Eq)]
4pub struct StaticLayerMemoryCacheStats {
5 pub entry_count: usize,
6 pub bytes: usize,
7 pub budget_bytes: usize,
8 pub hits: u64,
9 pub misses: u64,
10 pub stores: u64,
11 pub evictions: u64,
12}
13
14#[derive(Clone, Debug, Default, PartialEq, Eq)]
15pub struct StaticLayerMemoryCachePrefixStats {
16 pub entry_count: usize,
17 pub bytes: usize,
18}
19
20#[derive(Clone)]
21pub struct RenderCacheHandle {
22 stats: Arc<dyn Fn() -> StaticLayerMemoryCacheStats + Send + Sync>,
23 prefix_stats: Arc<dyn Fn(&str) -> StaticLayerMemoryCachePrefixStats + Send + Sync>,
24 prefix_entry_ids: Arc<dyn Fn(&str) -> Vec<String> + Send + Sync>,
25}
26
27impl RenderCacheHandle {
28 pub fn new(
29 stats: impl Fn() -> StaticLayerMemoryCacheStats + Send + Sync + 'static,
30 prefix_stats: impl Fn(&str) -> StaticLayerMemoryCachePrefixStats + Send + Sync + 'static,
31 prefix_entry_ids: impl Fn(&str) -> Vec<String> + Send + Sync + 'static,
32 ) -> Self {
33 Self {
34 stats: Arc::new(stats),
35 prefix_stats: Arc::new(prefix_stats),
36 prefix_entry_ids: Arc::new(prefix_entry_ids),
37 }
38 }
39}
40
41thread_local! {
42 static RENDER_CACHE: RefCell<Option<RenderCacheHandle>> = const { RefCell::new(None) };
43}
44
45pub(crate) struct RenderCacheGuard {
46 previous: Option<RenderCacheHandle>,
47}
48
49impl Drop for RenderCacheGuard {
50 fn drop(&mut self) {
51 RENDER_CACHE.with(|current| {
52 *current.borrow_mut() = self.previous.take();
53 });
54 }
55}
56
57pub(crate) fn install_render_cache(handle: RenderCacheHandle) -> RenderCacheGuard {
58 let previous = RENDER_CACHE.with(|current| current.borrow_mut().replace(handle));
59 RenderCacheGuard { previous }
60}
61
62pub fn static_layer_cache_stats() -> StaticLayerMemoryCacheStats {
63 RENDER_CACHE.with(|current| {
64 current
65 .borrow()
66 .as_ref()
67 .map_or_else(StaticLayerMemoryCacheStats::default, |cache| {
68 (cache.stats)()
69 })
70 })
71}
72
73pub fn static_layer_cache_stats_for_prefix(prefix: &str) -> StaticLayerMemoryCachePrefixStats {
74 RENDER_CACHE.with(|current| {
75 current
76 .borrow()
77 .as_ref()
78 .map_or_else(StaticLayerMemoryCachePrefixStats::default, |cache| {
79 (cache.prefix_stats)(prefix)
80 })
81 })
82}
83
84pub fn static_layer_cache_entry_ids_for_prefix(prefix: &str) -> Vec<String> {
85 RENDER_CACHE.with(|current| {
86 current
87 .borrow()
88 .as_ref()
89 .map_or_else(Vec::new, |cache| (cache.prefix_entry_ids)(prefix))
90 })
91}
92
93#[cfg(test)]
94#[path = "cache_test.rs"]
95mod tests;