vizia_core/binding/
store.rs
use hashbrown::HashSet;
use std::any::TypeId;
use std::hash::Hash;
use crate::{model::ModelOrView, prelude::*};
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum StoreId {
Source(TypeId),
Index(TypeId, usize),
Recursive(Box<(StoreId, StoreId)>),
Map(u64),
}
pub(crate) trait Store {
fn update(&mut self, model: ModelOrView) -> bool;
fn observers(&self) -> &HashSet<Entity>;
fn add_observer(&mut self, observer: Entity);
fn remove_observer(&mut self, observer: &Entity);
fn num_observers(&self) -> usize;
fn source(&self) -> TypeId;
#[cfg(debug_assertions)]
fn name(&self) -> String;
}
pub(crate) struct BasicStore<L: Lens, T> {
pub lens: L,
pub old: Option<T>,
pub observers: HashSet<Entity>,
}
impl<L> Store for BasicStore<L, L::Target>
where
L: Lens<Target: Data>,
{
fn source(&self) -> TypeId {
TypeId::of::<L::Source>()
}
fn update(&mut self, model: ModelOrView) -> bool {
let Some(data) = model.downcast_ref::<L::Source>() else { return false };
let Some(new_data) = self.lens.view(data) else { return false };
if matches!(&self.old, Some(old) if old.same(&new_data)) {
return false;
}
self.old = Some(new_data.into_owned());
true
}
fn observers(&self) -> &HashSet<Entity> {
&self.observers
}
fn add_observer(&mut self, observer: Entity) {
self.observers.insert(observer);
}
fn remove_observer(&mut self, observer: &Entity) {
self.observers.remove(observer);
}
fn num_observers(&self) -> usize {
self.observers.len()
}
#[cfg(debug_assertions)]
fn name(&self) -> String {
format!("{:?}", self.lens)
}
}