ferroui_dynamic_data/cache/
intermediate_cache.rs1use super::{Change, ChangeSet, ICacheUpdater, IChangeSet, IConnectableCache, IObservableCache, ObservableCache};
6use ferroui_system::collections::generic::Dictionary;
7use ferroui_system::{IDisposable, IObservable};
8use std::hash::Hash;
9use std::rc::Rc;
10
11pub trait IIntermediateCache<T, K>: IObservableCache<T, K> {
13 fn edit(&self, update: &mut dyn FnMut(&mut dyn ICacheUpdater<T, K>));
15}
16
17pub struct IntermediateCache<T, K> {
21 inner: ObservableCache<T, K>,
22}
23
24impl<T, K> Clone for IntermediateCache<T, K> {
25 fn clone(&self) -> Self {
26 Self { inner: self.inner.clone() }
27 }
28}
29
30impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> Default for IntermediateCache<T, K> {
31 fn default() -> Self {
32 Self::new()
33 }
34}
35
36impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IntermediateCache<T, K> {
37 pub fn new() -> Self {
39 Self { inner: ObservableCache::without_key_selector() }
40 }
41
42 pub fn from_source<C: IChangeSet<T, K>>(source: Rc<dyn IObservable<C>>) -> Self {
44 Self { inner: ObservableCache::from_source(source) }
45 }
46
47 pub fn edit(&self, update: impl FnOnce(&mut dyn ICacheUpdater<T, K>)) {
49 self.inner.update_from_intermediate(update);
50 }
51
52 pub fn suspend_count(&self) -> Rc<dyn IDisposable> {
54 self.inner.suspend_count()
55 }
56
57 pub fn suspend_notifications(&self) -> Rc<dyn IDisposable> {
60 self.inner.suspend_notifications()
61 }
62
63 pub fn add_or_update(&self, item: T, key: K) {
66 self.edit(|updater| updater.add_or_update_with_key(item, key));
67 }
68
69 pub fn clear(&self) {
71 self.edit(|updater| updater.clear());
72 }
73
74 pub fn remove_key(&self, key: K) {
76 self.edit(|updater| updater.remove_key(&key));
77 }
78
79 pub fn remove_keys(&self, keys: impl IntoIterator<Item = K>) {
81 let keys: Vec<K> = keys.into_iter().collect();
82 self.edit(|updater| updater.remove_keys(&mut keys.into_iter()));
83 }
84}
85
86impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IConnectableCache<T, K> for IntermediateCache<T, K> {
87 fn count_changed(&self) -> Rc<dyn IObservable<usize>> {
88 self.inner.count_changed()
89 }
90
91 fn connect_with(&self, predicate: Option<Rc<dyn Fn(&T) -> bool>>, suppress_empty_change_sets: bool) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
92 self.inner.connect_with(predicate, suppress_empty_change_sets)
93 }
94
95 fn preview_with(&self, predicate: Option<Rc<dyn Fn(&T) -> bool>>) -> Rc<dyn IObservable<ChangeSet<T, K>>> {
96 self.inner.preview_with(predicate)
97 }
98
99 fn watch(&self, key: K) -> Rc<dyn IObservable<Change<T, K>>> {
100 self.inner.watch(key)
101 }
102}
103
104impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IObservableCache<T, K> for IntermediateCache<T, K> {
105 fn count(&self) -> usize {
106 self.inner.count()
107 }
108
109 fn items(&self) -> Vec<T> {
110 self.inner.items()
111 }
112
113 fn keys(&self) -> Vec<K> {
114 self.inner.keys()
115 }
116
117 fn key_values(&self) -> Dictionary<K, T> {
118 self.inner.key_values()
119 }
120
121 fn lookup(&self, key: &K) -> Option<T> {
122 self.inner.lookup(key)
123 }
124}
125
126impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IIntermediateCache<T, K> for IntermediateCache<T, K> {
127 fn edit(&self, update: &mut dyn FnMut(&mut dyn ICacheUpdater<T, K>)) {
128 self.inner.update_from_intermediate(|updater| update(updater));
129 }
130}
131
132impl<T: Clone + 'static, K: Eq + Hash + Clone + 'static> IDisposable for IntermediateCache<T, K> {
133 fn dispose(&self) {
134 self.inner.dispose();
135 }
136}