lazy_observer/
dirty_marker.rs1use std::cell::{Cell, RefCell};
2use std::collections::HashSet;
3use std::hash::*;
4use std::pin::Pin;
5use std::rc::Rc;
6
7pub(crate) struct DirtyMarker {
8 dirty: Cell<bool>,
9 send: RefCell<HashSet<Pin<Rc<Self>>>>,
10 listen: RefCell<HashSet<Pin<Rc<Self>>>>,
11}
12
13impl DirtyMarker {
14 pub(crate) fn new(dirty: bool) -> Self {
15 Self {
16 dirty: Cell::new(dirty),
17 send: RefCell::new(HashSet::new()),
18 listen: RefCell::new(HashSet::new()),
19 }
20 }
21 pub(crate) fn destroy(&self) {
22 self.send.borrow_mut().clear();
23 }
24 pub(crate) fn mark_dirty(&self) {
25 if !self.dirty.replace(true) {
26 for c in self.send.borrow().iter() {
27 c.mark_dirty();
28 }
29 }
30 }
31 pub(crate) fn mark_connected_dirty(&self) {
32 for c in self.send.borrow().iter() {
33 c.mark_dirty();
34 }
35 }
36 pub(crate) fn clear_dirty(&self) -> bool {
37 self.dirty.replace(false)
38 }
39 pub(crate) fn update_listen_targets(s: &Pin<Rc<Self>>, targets: HashSet<Pin<Rc<Self>>>) {
40 let mut old = s.listen.borrow_mut();
41 let remove = old.difference(&targets);
42 for target in remove {
43 target.send.borrow_mut().remove(s);
44 }
45 let add = targets.difference(&old);
46 for target in add {
47 target.send.borrow_mut().insert(s.clone());
48 }
49 *old = targets;
50 }
51}
52
53impl PartialEq for DirtyMarker {
54 fn eq(&self, other: &Self) -> bool {
55 self as *const _ == other as *const _
56 }
57}
58
59impl Eq for DirtyMarker {}
60
61impl Hash for DirtyMarker {
62 fn hash<H: Hasher>(&self, state: &mut H) {
63 (self as *const _ as usize).hash(state);
64 }
65}