vizia_core/binding/
store.rs
1use hashbrown::HashSet;
2use std::any::TypeId;
3use std::hash::Hash;
4
5use crate::{model::ModelOrView, prelude::*};
6
7#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
8pub enum StoreId {
9 Source(TypeId),
10 Index(TypeId, usize),
11 Recursive(Box<(StoreId, StoreId)>),
12 Map(u64),
13}
14
15pub(crate) trait Store {
16 fn update(&mut self, model: ModelOrView) -> bool;
18 fn observers(&self) -> &HashSet<Entity>;
20 fn add_observer(&mut self, observer: Entity);
22 fn remove_observer(&mut self, observer: &Entity);
24 fn num_observers(&self) -> usize;
26 fn source(&self) -> TypeId;
28
29 #[cfg(debug_assertions)]
30 fn name(&self) -> String;
31}
32
33pub(crate) struct BasicStore<L: Lens, T> {
34 pub lens: L,
35 pub old: Option<T>,
36 pub observers: HashSet<Entity>,
37}
38
39impl<L> Store for BasicStore<L, L::Target>
40where
41 L: Lens<Target: Data>,
42{
43 fn source(&self) -> TypeId {
44 TypeId::of::<L::Source>()
45 }
46
47 fn update(&mut self, model: ModelOrView) -> bool {
48 let Some(data) = model.downcast_ref::<L::Source>() else { return false };
49 let Some(new_data) = self.lens.view(data) else { return false };
50
51 if matches!(&self.old, Some(old) if old.same(&new_data)) {
52 return false;
53 }
54
55 self.old = Some(new_data.into_owned());
56
57 true
58 }
59
60 fn observers(&self) -> &HashSet<Entity> {
61 &self.observers
62 }
63
64 fn add_observer(&mut self, observer: Entity) {
65 self.observers.insert(observer);
66 }
67
68 fn remove_observer(&mut self, observer: &Entity) {
69 self.observers.remove(observer);
70 }
71
72 fn num_observers(&self) -> usize {
73 self.observers.len()
74 }
75
76 #[cfg(debug_assertions)]
77 fn name(&self) -> String {
78 format!("{:?}", self.lens)
79 }
80}