reactive_graph_behaviour_service_impl/
entity_behaviour_manager_impl.rs

1use 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 {}