reactive_graph_behaviour_service_impl/
entity_component_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_api::ComponentBehaviourTypeId;
15use reactive_graph_behaviour_model_impl::EntityBehaviourStorage;
16use reactive_graph_behaviour_service_api::EntityComponentBehaviourManager;
17use reactive_graph_behaviour_service_api::EntityComponentBehaviourRegistry;
18use reactive_graph_graph::ComponentContainer;
19use reactive_graph_lifecycle::Lifecycle;
20use reactive_graph_reactive_model_impl::ReactiveEntity;
21
22#[derive(Component)]
23pub struct EntityComponentBehaviourManagerImpl {
24 entity_component_behaviour_registry: Arc<dyn EntityComponentBehaviourRegistry + Send + Sync>,
25
26 #[component(default = "EntityBehaviourStorage::new")]
27 entity_behaviour_storage: EntityBehaviourStorage,
28}
29
30#[async_trait]
31#[component_alias]
32impl EntityComponentBehaviourManager for EntityComponentBehaviourManagerImpl {
33 fn add_behaviours_to_entity(&self, entity_instance: ReactiveEntity) {
34 for component_ty in entity_instance.get_components() {
35 for factory in self.entity_component_behaviour_registry.get(&component_ty) {
36 if let Ok(behaviour) = factory.create(entity_instance.clone()) {
37 let behaviour_ty = behaviour.ty().clone();
38 self.entity_behaviour_storage.insert(entity_instance.id, behaviour.ty().clone(), behaviour);
39 trace!("Added entity component behaviour {}", &behaviour_ty);
40 }
41 }
42 }
43 }
44
45 fn add_behaviours_to_entity_component(&self, entity_instance: ReactiveEntity, component: reactive_graph_graph::Component) {
46 for factory in self.entity_component_behaviour_registry.get(&component.ty) {
47 if let Ok(behaviour) = factory.create(entity_instance.clone()) {
48 let behaviour_ty = behaviour.ty().clone();
49 self.entity_behaviour_storage.insert(entity_instance.id, behaviour_ty.clone(), behaviour);
50 trace!("Added entity component behaviour {}", &behaviour_ty);
51 }
52 }
53 }
54
55 fn add_behaviour_to_entity_component(&self, entity_instance: ReactiveEntity, component_behaviour_ty: &ComponentBehaviourTypeId) {
56 for factory in self.entity_component_behaviour_registry.get(&component_behaviour_ty.component_ty) {
57 if let Ok(behaviour) = factory.create(entity_instance.clone()) {
58 let behaviour_ty = behaviour.ty().clone();
59 self.entity_behaviour_storage.insert(entity_instance.id, behaviour_ty.clone(), behaviour);
60 trace!("Added entity component behaviour {}", &behaviour_ty);
61 }
62 }
63 }
64
65 fn remove_behaviour_from_entity(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) {
66 let id = entity_instance.id;
67 let _ = self.disconnect(entity_instance, behaviour_ty);
68 self.entity_behaviour_storage.remove(&id, behaviour_ty);
69 trace!("Removed entity behaviour {} from {}", &behaviour_ty, id);
70 }
71
72 fn remove_behaviours_from_entity(&self, entity_instance: ReactiveEntity) {
73 self.entity_behaviour_storage.remove_all(&entity_instance.id);
74 }
75
76 fn remove_behaviours_from_entity_component(&self, entity_instance: ReactiveEntity, component: reactive_graph_graph::Component) {
77 for factory in self.entity_component_behaviour_registry.get(&component.ty) {
78 self.entity_behaviour_storage.remove(&entity_instance.id, factory.behaviour_ty());
79 trace!("Removed entity component behaviour {}", factory.behaviour_ty());
80 }
81 }
82
83 fn remove_behaviours_by_id(&self, id: &Uuid) {
84 self.entity_behaviour_storage.remove_all(id);
85 }
86
87 fn remove_behaviours_by_behaviour(&self, behaviour_ty: &BehaviourTypeId) {
88 self.entity_behaviour_storage.remove_by_behaviour(behaviour_ty);
89 trace!("Removed all entity component behaviours of type {}", &behaviour_ty);
90 }
91
92 fn has(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) -> bool {
93 self.entity_behaviour_storage.has(&entity_instance.id, behaviour_ty)
94 }
95
96 fn get_all(&self, entity_instance: ReactiveEntity) -> Vec<BehaviourTypeId> {
97 self.entity_behaviour_storage.get_behaviours_by_instance(&entity_instance.id)
98 }
99
100 fn get_instances_by_behaviour(&self, ty: &BehaviourTypeId) -> Vec<ReactiveEntity> {
101 self.entity_behaviour_storage.get_instances_by_behaviour(ty)
102 }
103
104 fn connect(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
105 if let Some(fsm) = self.entity_behaviour_storage.get(&entity_instance.id, behaviour_ty) {
106 return fsm.transition(BehaviourState::Connected);
107 }
108 Err(BehaviourTransitionError::BehaviourConnectFailed(BehaviourConnectFailed {}))
109 }
110
111 fn disconnect(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
112 if let Some(fsm) = self.entity_behaviour_storage.get(&entity_instance.id, behaviour_ty) {
113 return fsm.transition(BehaviourState::Ready);
114 }
115 Err(BehaviourTransitionError::BehaviourDisconnectFailed(BehaviourDisconnectFailed {}))
116 }
117
118 fn reconnect(&self, entity_instance: ReactiveEntity, behaviour_ty: &BehaviourTypeId) -> Result<(), BehaviourTransitionError> {
119 if let Some(fsm) = self.entity_behaviour_storage.get(&entity_instance.id, behaviour_ty) {
120 return fsm.transition(BehaviourState::Ready).and_then(|_| fsm.transition(BehaviourState::Connected));
121 }
122 Err(BehaviourTransitionError::InvalidTransition)
123 }
124}
125
126#[async_trait]
127impl Lifecycle for EntityComponentBehaviourManagerImpl {}