egui/cache/cache_storage.rs
1use super::CacheTrait;
2
3/// A typemap of many caches, all implemented with [`CacheTrait`].
4///
5/// You can access egui's caches via [`crate::Memory::caches`],
6/// found with [`crate::Context::memory_mut`].
7///
8/// ```
9/// use egui::cache::{CacheStorage, ComputerMut, FrameCache};
10///
11/// #[derive(Default)]
12/// struct CharCounter {}
13/// impl ComputerMut<&str, usize> for CharCounter {
14/// fn compute(&mut self, s: &str) -> usize {
15/// s.chars().count()
16/// }
17/// }
18/// type CharCountCache<'a> = FrameCache<usize, CharCounter>;
19///
20/// # let mut cache_storage = CacheStorage::default();
21/// let mut cache = cache_storage.cache::<CharCountCache<'_>>();
22/// assert_eq!(cache.get("hello"), 5);
23/// ```
24#[derive(Default)]
25pub struct CacheStorage {
26 caches: ahash::HashMap<std::any::TypeId, Box<dyn CacheTrait>>,
27}
28
29impl CacheStorage {
30 pub fn cache<Cache: CacheTrait + Default>(&mut self) -> &mut Cache {
31 self.caches
32 .entry(std::any::TypeId::of::<Cache>())
33 .or_insert_with(|| Box::<Cache>::default())
34 .as_any_mut()
35 .downcast_mut::<Cache>()
36 .unwrap()
37 }
38
39 /// Total number of cached values
40 fn num_values(&self) -> usize {
41 self.caches.values().map(|cache| cache.len()).sum()
42 }
43
44 /// Call once per frame to evict cache.
45 pub fn update(&mut self) {
46 self.caches.retain(|_, cache| {
47 cache.update();
48 cache.len() > 0
49 });
50 }
51}
52
53impl Clone for CacheStorage {
54 fn clone(&self) -> Self {
55 // We return an empty cache that can be filled in again.
56 Self::default()
57 }
58}
59
60impl std::fmt::Debug for CacheStorage {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 write!(
63 f,
64 "FrameCacheStorage[{} caches with {} elements]",
65 self.caches.len(),
66 self.num_values()
67 )
68 }
69}