reactive_graph_behaviour_model_impl/behaviour/relation/
observer.rs1use dashmap::DashMap;
2use dashmap::DashSet;
3use log::trace;
4use serde_json::Value;
5use uuid::Uuid;
6
7use crate::PropertyObserverContainer;
8use reactive_graph_graph::PropertyInstanceSetter;
9use reactive_graph_reactive_model_api::ReactivePropertyContainer;
10use reactive_graph_reactive_model_impl::ReactiveRelation;
11
12pub struct RelationPropertyObserverContainerImpl {
14 pub reactive_instance: ReactiveRelation,
15 pub handles: DashMap<String, DashSet<u128>>,
16}
17
18impl RelationPropertyObserverContainerImpl {
19 pub fn new(reactive_instance: ReactiveRelation) -> Self {
21 RelationPropertyObserverContainerImpl {
22 reactive_instance,
23 handles: DashMap::new(),
24 }
25 }
26}
27
28impl PropertyObserverContainer for RelationPropertyObserverContainerImpl {
29 fn observe_with_handle<F>(&self, name: &str, subscriber: F) -> u128
30 where
31 F: FnMut(&Value) + 'static + Send,
32 {
33 let handle_id = Uuid::new_v4().as_u128();
34 match self.handles.get(name) {
35 None => {
36 let property_handles = DashSet::new();
37 property_handles.insert(handle_id);
38 self.handles.insert(name.to_string(), property_handles);
39 }
40 Some(property_handles) => {
41 property_handles.insert(handle_id);
42 }
43 }
44 trace!("Adding observer {} {} {}", self.reactive_instance, name, handle_id);
45 self.reactive_instance.observe_with_handle(name, subscriber, handle_id);
46 handle_id
47 }
48
49 fn propagate(&self, name: &str, target_property_name: &str) {
50 let reactive_instance = self.reactive_instance.clone();
51 let target_property_name = target_property_name.to_string();
52 self.observe_with_handle(name, move |value| {
53 reactive_instance.set(&target_property_name, value.clone());
54 });
55 }
56
57 fn remove_observer(&self, name: &str, handle_id: u128) {
58 self.reactive_instance.remove_observer(name, handle_id);
59 if let Some(property_handles) = self.handles.get(name) {
60 trace!("Removing observer {} {} {}", self.reactive_instance, property_handles.key(), &handle_id);
61 property_handles.remove(&handle_id.clone());
62 }
63 }
64
65 fn remove_observers(&self, name: &str) {
66 if let Some(property_handles) = self.handles.get(name) {
67 for handle_id in property_handles.iter() {
68 trace!("Removing observer {} {} {}", self.reactive_instance, property_handles.key(), handle_id.key());
69 self.reactive_instance.remove_observer(name, *handle_id.key());
70 }
71 }
72 self.handles.remove(name);
73 }
74
75 fn remove_all_observers(&self) {
76 for property_handles in self.handles.iter() {
77 for handle_id in property_handles.iter() {
78 trace!("Removing observer {} {} {}", self.reactive_instance, property_handles.key(), handle_id.key());
79 self.reactive_instance.remove_observer(property_handles.key(), *handle_id.key());
80 }
81 }
82 self.handles.clear();
83 }
84}