#[derive(Debug, Clone)]
pub struct Lazy<T: Clone> {
value: Option<T>,
dirty: bool,
}
impl<T: Clone> Default for Lazy<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Clone> Lazy<T> {
pub fn new() -> Self {
Self {
value: None,
dirty: true,
}
}
pub fn with_value(value: T) -> Self {
Self {
value: Some(value),
dirty: false,
}
}
pub fn is_dirty(&self) -> bool {
self.dirty || self.value.is_none()
}
pub fn get_or_compute<F: FnOnce() -> T>(&mut self, compute: F) -> &T {
if self.is_dirty() {
self.value = Some(compute());
self.dirty = false;
}
match self.value.as_ref() {
Some(v) => v,
None => unreachable!("value is Some after get_or_compute"),
}
}
pub fn invalidate(&mut self) {
self.dirty = true;
}
pub fn set(&mut self, value: T) {
self.value = Some(value);
self.dirty = false;
}
pub fn get_if_clean(&self) -> Option<&T> {
if self.is_dirty() {
None
} else {
self.value.as_ref()
}
}
pub fn into_inner(self) -> Option<T> {
self.value
}
}
#[derive(Default)]
pub struct DirtyTracker {
dirty_ids: std::collections::HashSet<crate::WindowA11yId>,
generation: u64,
}
impl DirtyTracker {
pub fn new() -> Self {
Self {
dirty_ids: std::collections::HashSet::new(),
generation: 0,
}
}
pub fn mark_dirty(&mut self, id: crate::WindowA11yId) {
self.dirty_ids.insert(id);
self.generation += 1;
}
pub fn is_dirty(&self, id: crate::WindowA11yId) -> bool {
self.dirty_ids.contains(&id)
}
pub fn clear(&mut self, id: crate::WindowA11yId) {
self.dirty_ids.remove(&id);
}
pub fn generation(&self) -> u64 {
self.generation
}
}