reactive_graph_behaviour_service_impl/
relation_component_behaviour_manager_impl.rs1use 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 {}