reactive_graph_behaviour_service_impl/
entity_behaviour_manager_impl.rs1use std::sync::Arc;
2
3use async_trait::async_trait;
4use log::trace;
5use springtime_di::Component;
6use springtime_di::component_alias;
7use uuid::Uuid;
8
9use reactive_graph_behaviour_model_api::BehaviourConnectFailed;
10use reactive_graph_behaviour_model_api::BehaviourDisconnectFailed;
11use reactive_graph_behaviour_model_api::BehaviourState;
12use reactive_graph_behaviour_model_api::BehaviourTransitionError;
13use reactive_graph_behaviour_model_api::BehaviourTypeId;
14use reactive_graph_behaviour_model_impl::EntityBehaviourStorage;
15use reactive_graph_behaviour_service_api::EntityBehaviourManager;
16use reactive_graph_behaviour_service_api::EntityBehaviourRegistry;
17use reactive_graph_lifecycle::Lifecycle;
18use reactive_graph_reactive_model_impl::ReactiveEntity;
19
20#[derive(Component)]
21pub struct EntityBehaviourManagerImpl {
22 entity_behaviour_registry: Arc<dyn EntityBehaviourRegistry + Send + Sync>,
23
24 #[component(default = "EntityBehaviourStorage::new")]
25 entity_behaviour_storage: EntityBehaviourStorage,
26}
27
28#[async_trait]
29#[component_alias]
30impl EntityBehaviourManager for EntityBehaviourManagerImpl {
31 fn add_behaviours(&self, entity_instance: ReactiveEntity) {
32 for factory in self.entity_behaviour_registry.get(&entity_instance.ty) {
33 if let Ok(behaviour) = factory.create(entity_instance.clone()) {
34 let behaviour_ty = behaviour.ty().clone();
35 self.entity_behaviour_storage.insert(entity_instance.id, behaviour_ty.clone(), behaviour);
36 trace!("Added entity behaviour {} to {}", &behaviour_ty, entity_instance.id);
37 }
38 }
39 }
40
41 fn add_behaviour(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) {
42 if let Some(factory) = self.entity_behaviour_registry.get_factory_by_behaviour_type(behaviour_ty) {
43 if let Ok(behaviour) = factory.create(entity_instance.clone()) {
44 let behaviour_ty = behaviour.ty().clone();
45 self.entity_behaviour_storage.insert(entity_instance.id, behaviour_ty.clone(), behaviour);
46 trace!("Added entity behaviour {} to {}", &behaviour_ty, entity_instance.id);
47 }
48 }
49 }
50
51 fn remove_behaviour(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) {
52 let id = entity_instance.id;
53 let _ = self.disconnect(entity_instance, behaviour_ty);
54 self.entity_behaviour_storage.remove(&id, behaviour_ty);
55 trace!("Removed entity behaviour {} from {}", &behaviour_ty, id);
56 }
57
58 fn remove_behaviours(&self, entity_instance: ReactiveEntity) {
59 self.entity_behaviour_storage.remove_all(&entity_instance.id);
60 }
61
62 fn remove_behaviours_by_id(&self, id: &Uuid) {
63 self.entity_behaviour_storage.remove_all(id);
64 }
65
66 fn remove_behaviours_by_behaviour(&self, behaviour_ty: &BehaviourTypeId) {
67 self.entity_behaviour_storage.remove_by_behaviour(behaviour_ty);
68 trace!("Removed all entity behaviours of type {}", &behaviour_ty);
69 }
70
71 fn has(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) -> bool {
72 self.entity_behaviour_storage.has(&entity_instance.id, behaviour_ty)
73 }
74
75 fn get_all(&self, entity_instance: ReactiveEntity) -> Vec<BehaviourTypeId> {
76 self.entity_behaviour_storage.get_behaviours_by_instance(&entity_instance.id)
77 }
78
79 fn get_instances_by_behaviour(&self, ty: &BehaviourTypeId) -> Vec<ReactiveEntity> {
80 self.entity_behaviour_storage.get_instances_by_behaviour(ty)
81 }
82
83 fn connect(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
84 if let Some(fsm) = self.entity_behaviour_storage.get(&entity_instance.id, behaviour_ty) {
85 return fsm.transition(BehaviourState::Connected);
86 }
87 Err(BehaviourTransitionError::BehaviourConnectFailed(BehaviourConnectFailed {}))
88 }
89
90 fn disconnect(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
91 if let Some(fsm) = self.entity_behaviour_storage.get(&entity_instance.id, behaviour_ty) {
92 return fsm.transition(BehaviourState::Ready);
93 }
94 Err(BehaviourTransitionError::BehaviourDisconnectFailed(BehaviourDisconnectFailed {}))
95 }
96
97 fn reconnect(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
98 if let Some(fsm) = self.entity_behaviour_storage.get(&entity_instance.id, behaviour_ty) {
99 return fsm.transition(BehaviourState::Ready).and_then(|_| fsm.transition(BehaviourState::Connected));
100 }
101 Err(BehaviourTransitionError::InvalidTransition)
102 }
103}
104
105#[async_trait]
106impl Lifecycle for EntityBehaviourManagerImpl {}