reactive_graph_behaviour_service_impl/
relation_component_behaviour_manager_impl.rs

1use async_trait::async_trait;
2use log::trace;
3use std::sync::Arc;
4
5use reactive_graph_behaviour_model_api::BehaviourConnectFailed;
6use reactive_graph_behaviour_model_api::BehaviourDisconnectFailed;
7use reactive_graph_behaviour_model_api::BehaviourState;
8use reactive_graph_behaviour_model_api::BehaviourTransitionError;
9use reactive_graph_behaviour_model_api::BehaviourTypeId;
10use reactive_graph_behaviour_model_api::ComponentBehaviourTypeId;
11use reactive_graph_behaviour_model_impl::RelationBehaviourStorage;
12use reactive_graph_behaviour_service_api::RelationComponentBehaviourManager;
13use reactive_graph_behaviour_service_api::RelationComponentBehaviourRegistry;
14use reactive_graph_graph::ComponentContainer;
15use reactive_graph_graph::RelationInstanceId;
16use reactive_graph_lifecycle::Lifecycle;
17use reactive_graph_reactive_model_api::ReactiveInstance;
18use reactive_graph_reactive_model_impl::ReactiveRelation;
19use springtime_di::Component;
20use springtime_di::component_alias;
21
22#[derive(Component)]
23pub struct RelationComponentBehaviourManagerImpl {
24    relation_component_behaviour_registry: Arc<dyn RelationComponentBehaviourRegistry + Send + Sync>,
25
26    #[component(default = "RelationBehaviourStorage::new")]
27    relation_behaviour_storage: RelationBehaviourStorage,
28}
29
30#[async_trait]
31#[component_alias]
32impl RelationComponentBehaviourManager for RelationComponentBehaviourManagerImpl {
33    fn add_behaviours_to_relation(&self, relation_instance: ReactiveRelation) {
34        let relation_instance_id = relation_instance.id();
35        for component_ty in relation_instance.get_components() {
36            for factory in self.relation_component_behaviour_registry.get(&component_ty) {
37                if let Ok(behaviour) = factory.create(relation_instance.clone()) {
38                    let behaviour_ty = behaviour.ty().clone();
39                    self.relation_behaviour_storage
40                        .insert(relation_instance_id.clone(), behaviour_ty.clone(), behaviour);
41                    trace!("Added relation component behaviour {}", &behaviour_ty);
42                }
43            }
44        }
45    }
46
47    fn add_behaviours_to_relation_component(&self, relation_instance: ReactiveRelation, component: reactive_graph_graph::Component) {
48        let relation_instance_id = relation_instance.id();
49        for factory in self.relation_component_behaviour_registry.get(&component.ty) {
50            if let Ok(behaviour) = factory.create(relation_instance.clone()) {
51                let behaviour_ty = behaviour.ty().clone();
52                self.relation_behaviour_storage
53                    .insert(relation_instance_id.clone(), behaviour_ty.clone(), behaviour);
54                trace!("Added relation component behaviour {}", &behaviour_ty);
55            }
56        }
57    }
58
59    fn add_behaviour_to_relation_component(&self, relation_instance: ReactiveRelation, component_behaviour_ty: &ComponentBehaviourTypeId) {
60        let relation_instance_id = relation_instance.id();
61        for factory in self.relation_component_behaviour_registry.get(&component_behaviour_ty.component_ty) {
62            if let Ok(behaviour) = factory.create(relation_instance.clone()) {
63                let behaviour_ty = behaviour.ty().clone();
64                self.relation_behaviour_storage
65                    .insert(relation_instance_id.clone(), behaviour_ty.clone(), behaviour);
66                trace!("Added relation component behaviour {}", &behaviour_ty);
67            }
68        }
69    }
70
71    fn remove_behaviour_from_relation(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) {
72        let relation_instance_id = relation_instance.id();
73        let _ = self.disconnect(relation_instance, behaviour_ty);
74        self.relation_behaviour_storage.remove(&relation_instance_id, behaviour_ty);
75        trace!("Removed relation behaviour {}", &behaviour_ty);
76    }
77
78    fn remove_behaviours_from_relation(&self, relation_instance: ReactiveRelation) {
79        self.relation_behaviour_storage.remove_all(&relation_instance.id());
80    }
81
82    fn remove_behaviours_from_relation_component(&self, relation_instance: ReactiveRelation, component: reactive_graph_graph::Component) {
83        let relation_instance_id = relation_instance.id();
84        for factory in self.relation_component_behaviour_registry.get(&component.ty) {
85            self.relation_behaviour_storage.remove(&relation_instance_id, factory.behaviour_ty());
86            trace!("Removed relation component behaviour {}", factory.behaviour_ty());
87        }
88    }
89
90    fn remove_behaviours_by_key(&self, relation_instance_id: &RelationInstanceId) {
91        self.relation_behaviour_storage.remove_all(relation_instance_id);
92    }
93
94    fn remove_behaviours_by_behaviour(&self, behaviour_ty: &BehaviourTypeId) {
95        self.relation_behaviour_storage.remove_by_behaviour(behaviour_ty);
96        trace!("Removed all relation behaviours of type {}", &behaviour_ty);
97    }
98
99    fn has(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) -> bool {
100        self.relation_behaviour_storage.has(&relation_instance.id(), behaviour_ty)
101    }
102
103    fn get_all(&self, relation_instance: ReactiveRelation) -> Vec<BehaviourTypeId> {
104        self.relation_behaviour_storage.get_behaviours_by_instance(&relation_instance.id())
105    }
106
107    fn get_instances_by_behaviour(&self, ty: &BehaviourTypeId) -> Vec<ReactiveRelation> {
108        self.relation_behaviour_storage.get_instances_by_behaviour(ty)
109    }
110
111    fn connect(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
112        if let Some(fsm) = self.relation_behaviour_storage.get(&relation_instance.id(), behaviour_ty) {
113            return fsm.transition(BehaviourState::Connected);
114        }
115        Err(BehaviourTransitionError::BehaviourConnectFailed(BehaviourConnectFailed {}))
116    }
117
118    fn disconnect(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
119        if let Some(fsm) = self.relation_behaviour_storage.get(&relation_instance.id(), behaviour_ty) {
120            return fsm.transition(BehaviourState::Ready);
121        }
122        Err(BehaviourTransitionError::BehaviourDisconnectFailed(BehaviourDisconnectFailed {}))
123    }
124
125    fn reconnect(&self, relation_instance: ReactiveRelation, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
126        if let Some(fsm) = self.relation_behaviour_storage.get(&relation_instance.id(), behaviour_ty) {
127            return fsm.transition(BehaviourState::Ready).and_then(|_| fsm.transition(BehaviourState::Connected));
128        }
129        Err(BehaviourTransitionError::InvalidTransition)
130    }
131}
132
133#[async_trait]
134impl Lifecycle for RelationComponentBehaviourManagerImpl {}