reactive_graph_reactive_service_impl/
reactive_entity_manager_impl.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3use std::sync::RwLock;
4use std::sync::atomic::AtomicBool;
5use std::sync::atomic::Ordering;
6
7use async_trait::async_trait;
8use dashmap::DashMap;
9use log::error;
10use path_tree::PathTree;
11use serde_json::Value;
12use springtime_di::Component;
13use springtime_di::component_alias;
14use tokio::time::sleep;
15use uuid::Uuid;
16
17use reactive_graph_behaviour_model_api::BehaviourTypeId;
18use reactive_graph_behaviour_model_api::BehaviourTypesContainer;
19use reactive_graph_behaviour_model_api::ComponentBehaviourTypeId;
20use reactive_graph_behaviour_model_api::EntityBehaviourTypeId;
21use reactive_graph_behaviour_service_api::EntityBehaviourManager;
22use reactive_graph_behaviour_service_api::EntityComponentBehaviourManager;
23use reactive_graph_graph::ComponentContainer;
24use reactive_graph_graph::ComponentTypeId;
25use reactive_graph_graph::EntityInstance;
26use reactive_graph_graph::EntityTypeId;
27use reactive_graph_graph::Mutability;
28use reactive_graph_graph::NamespacedTypeGetter;
29use reactive_graph_graph::PropertyInstanceGetter;
30use reactive_graph_graph::PropertyInstances;
31use reactive_graph_graph::PropertyTypeContainer;
32use reactive_graph_graph::PropertyTypeDefinition;
33use reactive_graph_graph::TypeDefinitionComponent;
34use reactive_graph_graph::TypeDefinitionGetter;
35use reactive_graph_graph::TypeDefinitionProperty;
36use reactive_graph_lifecycle::Lifecycle;
37use reactive_graph_reactive_model_api::ReactivePropertyContainer;
38use reactive_graph_reactive_model_impl::ReactiveEntity;
39use reactive_graph_reactive_service_api::ReactiveEntityComponentAddError;
40use reactive_graph_reactive_service_api::ReactiveEntityCreationError;
41use reactive_graph_reactive_service_api::ReactiveEntityManager;
42use reactive_graph_reactive_service_api::ReactiveEntityPropertyAddError;
43use reactive_graph_reactive_service_api::ReactiveEntityPropertyRemoveError;
44use reactive_graph_reactive_service_api::ReactiveEntityRegistrationError;
45use reactive_graph_reactive_service_api::ReactiveInstanceEvent;
46use reactive_graph_reactive_service_api::ReactiveInstanceEventManager;
47use reactive_graph_reactive_service_api::event_channels::EventChannels;
48use reactive_graph_runtime_model::EventProperties::EVENT;
49use reactive_graph_runtime_model::LabeledProperties::LABEL;
50use reactive_graph_type_system_api::ComponentManager;
51use reactive_graph_type_system_api::EntityTypeManager;
52use reactive_graph_type_system_api::TypeSystemEventManager;
53use reactive_graph_type_system_api::TypeSystemEventSubscriber;
54use reactive_graph_type_system_api::TypeSystemEventTypes;
55
56static HANDLE_ID_ENTITY_TYPE_COMPONENT_ADDED: u128 = 0x6ba7b8109e1513d350b300c04fe530c7;
57static HANDLE_ID_ENTITY_TYPE_COMPONENT_REMOVED: u128 = 0x6ba8b8119e1513d350b300c04fe630c7;
58static HANDLE_ID_ENTITY_TYPE_PROPERTY_ADDED: u128 = 0x6ba7b8109e2613d350b300c04fe640c7;
59static HANDLE_ID_ENTITY_TYPE_PROPERTY_REMOVED: u128 = 0x7ca8b8119e1523d361b311c050e630c7;
60
61fn create_label_path_tree() -> RwLock<PathTree<Uuid>> {
62    RwLock::new(PathTree::<Uuid>::new())
63}
64
65fn create_running_state() -> Arc<AtomicBool> {
66    Arc::new(AtomicBool::new(true))
67}
68
69fn create_event_channels() -> EventChannels {
70    let event_channels = EventChannels::new();
71    event_channels.insert(HANDLE_ID_ENTITY_TYPE_COMPONENT_ADDED, crossbeam::channel::unbounded());
72    event_channels.insert(HANDLE_ID_ENTITY_TYPE_COMPONENT_REMOVED, crossbeam::channel::unbounded());
73    event_channels.insert(HANDLE_ID_ENTITY_TYPE_PROPERTY_ADDED, crossbeam::channel::unbounded());
74    event_channels.insert(HANDLE_ID_ENTITY_TYPE_PROPERTY_REMOVED, crossbeam::channel::unbounded());
75    event_channels
76}
77
78#[derive(Component)]
79pub struct ReactiveEntityManagerImpl {
80    reactive_instance_event_manager: Arc<dyn ReactiveInstanceEventManager + Send + Sync>,
81
82    type_system_event_manager: Arc<dyn TypeSystemEventManager + Send + Sync>,
83
84    component_manager: Arc<dyn ComponentManager + Send + Sync>,
85
86    entity_type_manager: Arc<dyn EntityTypeManager + Send + Sync>,
87
88    entity_behaviour_manager: Arc<dyn EntityBehaviourManager + Send + Sync>,
89
90    entity_component_behaviour_manager: Arc<dyn EntityComponentBehaviourManager + Send + Sync>,
91
92    #[component(default = "DashMap::new")]
93    reactive_entity_instances: DashMap<Uuid, ReactiveEntity>,
94
95    #[component(default = "create_label_path_tree")]
96    label_path_tree: RwLock<PathTree<Uuid>>,
97
98    #[component(default = "create_running_state")]
99    running: Arc<AtomicBool>,
100
101    #[component(default = "create_event_channels")]
102    event_channels: EventChannels,
103    // TODO: Type Cache
104}
105
106#[async_trait]
107#[component_alias]
108impl ReactiveEntityManager for ReactiveEntityManagerImpl {
109    fn has(&self, id: Uuid) -> bool {
110        self.reactive_entity_instances.contains_key(&id)
111    }
112
113    fn get(&self, id: Uuid) -> Option<ReactiveEntity> {
114        self.reactive_entity_instances.get(&id).map(|entity_instance| entity_instance.value().clone())
115    }
116
117    fn get_by_label(&self, label: &str) -> Option<ReactiveEntity> {
118        let reader = self.label_path_tree.read().unwrap();
119        reader.find(label).and_then(|result| self.get(*result.0))
120    }
121
122    fn get_by_label_with_params(&self, label: &str) -> Option<(ReactiveEntity, HashMap<String, String>)> {
123        let reader = self.label_path_tree.read().unwrap();
124        reader.find(label).and_then(|result| match self.get(*result.0) {
125            Some(instance) => {
126                let params = result.1.params_iter().map(|param| (param.0.to_string(), param.1.to_string())).collect();
127                Some((instance, params))
128            }
129            None => None,
130        })
131    }
132
133    fn get_all(&self) -> Vec<ReactiveEntity> {
134        self.reactive_entity_instances.iter().map(|e| e.value().clone()).collect()
135    }
136
137    fn get_by_type(&self, ty: &EntityTypeId) -> Vec<ReactiveEntity> {
138        self.reactive_entity_instances
139            .iter()
140            .filter(|e| &e.ty == ty)
141            .map(|e| e.value().clone())
142            .collect()
143    }
144
145    fn get_by_component(&self, ty: &ComponentTypeId) -> Vec<ReactiveEntity> {
146        self.reactive_entity_instances
147            .iter()
148            .filter(|e| e.is_a(ty))
149            .map(|e| e.value().clone())
150            .collect()
151    }
152
153    fn get_by_behaviour(&self, behaviour_ty: &BehaviourTypeId) -> Vec<ReactiveEntity> {
154        self.reactive_entity_instances
155            .iter()
156            .filter(|e| e.behaves_as(behaviour_ty))
157            .map(|e| e.value().clone())
158            .collect()
159    }
160
161    fn get_by_namespace(&self, namespace: &str) -> Vec<ReactiveEntity> {
162        self.reactive_entity_instances
163            .iter()
164            .filter(|r| r.namespace() == namespace)
165            .map(|r| r.value().clone())
166            .collect()
167    }
168
169    fn count(&self) -> usize {
170        self.reactive_entity_instances.len()
171    }
172
173    fn count_by_type(&self, ty: &EntityTypeId) -> usize {
174        self.reactive_entity_instances.iter().filter(|e| &e.ty == ty).count()
175    }
176
177    fn count_by_component(&self, component_ty: &ComponentTypeId) -> usize {
178        self.reactive_entity_instances.iter().filter(|e| e.is_a(component_ty)).count()
179    }
180
181    fn count_by_behaviour(&self, behaviour_ty: &BehaviourTypeId) -> usize {
182        self.reactive_entity_instances.iter().filter(|e| e.behaves_as(behaviour_ty)).count()
183    }
184
185    fn get_ids(&self) -> Vec<Uuid> {
186        self.reactive_entity_instances.iter().map(|e| *e.key()).collect()
187    }
188
189    fn create_reactive_entity(&self, ty: &EntityTypeId, properties: PropertyInstances) -> Result<ReactiveEntity, ReactiveEntityCreationError> {
190        let entity_instance = EntityInstance::builder().ty(ty.clone()).properties(properties).build();
191        self.create_reactive_instance(entity_instance)
192    }
193
194    fn create_with_id(&self, ty: &EntityTypeId, id: Uuid, properties: PropertyInstances) -> Result<ReactiveEntity, ReactiveEntityCreationError> {
195        if self.has(id) {
196            return Err(ReactiveEntityCreationError::UuidTaken(id));
197        }
198
199        let entity_instance = EntityInstance::builder().ty(ty.clone()).id(id).properties(properties).build();
200        self.create_reactive_instance(entity_instance)
201    }
202
203    fn create_reactive_instance(&self, entity_instance: EntityInstance) -> Result<ReactiveEntity, ReactiveEntityCreationError> {
204        let reactive_entity = ReactiveEntity::from(entity_instance);
205
206        // Initialize property mutability states
207        if let Some(entity_type) = self.entity_type_manager.get(&reactive_entity.ty) {
208            for component_ty in entity_type.components {
209                if let Some(component) = self.component_manager.get(&component_ty) {
210                    for property_type in component.properties.iter() {
211                        if let Some(mut property) = reactive_entity.properties.get_mut(&property_type.name) {
212                            property.set_mutability(property_type.mutability);
213                        }
214                    }
215                }
216            }
217            for property_type in entity_type.properties.iter() {
218                if let Some(mut property) = reactive_entity.properties.get_mut(&property_type.name) {
219                    property.set_mutability(property_type.mutability);
220                }
221            }
222        }
223
224        self.register_reactive_instance(reactive_entity)
225            .map_err(ReactiveEntityCreationError::ReactiveEntityRegistrationError)
226    }
227
228    fn register_reactive_instance(&self, reactive_entity: ReactiveEntity) -> Result<ReactiveEntity, ReactiveEntityRegistrationError> {
229        if self.reactive_entity_instances.contains_key(&reactive_entity.id) {
230            return Err(ReactiveEntityRegistrationError::UuidTaken(reactive_entity.id));
231        }
232        if !self.entity_type_manager.has(&reactive_entity.ty) {
233            return Err(ReactiveEntityRegistrationError::UnknownEntityType(reactive_entity.ty.clone()));
234        }
235        self.reactive_entity_instances.insert(reactive_entity.id, reactive_entity.clone());
236        // Apply all components that are predefined in the entity type
237        if let Some(components) = self.entity_type_manager.get(&reactive_entity.ty).map(|entity_type| entity_type.components) {
238            components.iter().for_each(|component_ty| {
239                reactive_entity.components.insert(component_ty.clone());
240            });
241        }
242        // Add component behaviours
243        self.entity_component_behaviour_manager.add_behaviours_to_entity(reactive_entity.clone());
244        // Add entity behaviours
245        self.entity_behaviour_manager.add_behaviours(reactive_entity.clone());
246        // Register label
247        if let Some(value) = reactive_entity.get(LABEL.property_name()).and_then(|v| v.as_str().map(|s| s.to_string())) {
248            let mut writer = self.label_path_tree.write().unwrap();
249            let _ = writer.insert(&value, reactive_entity.id);
250        }
251        self.reactive_instance_event_manager
252            .emit_event(ReactiveInstanceEvent::EntityInstanceCreated(reactive_entity.id));
253        Ok(reactive_entity)
254        //
255        // match self
256        //     .entity_instance_manager
257        //     .create_from_instance_if_not_exist(reactive_entity_instance.clone().into())
258        // {
259        //     Ok(_id) => {
260        //         self.reactive_entity_instances
261        //
262        //             .insert(reactive_entity_instance.id, reactive_entity_instance.clone());
263        //         // Apply all components that are predefined in the entity type
264        //         if let Some(components) = self
265        //             .entity_type_manager
266        //             .get(&reactive_entity_instance.ty)
267        //             .map(|entity_type| entity_type.components)
268        //         {
269        //             components.iter().for_each(|component_ty| {
270        //                 reactive_entity_instance.components.insert(component_ty.clone());
271        //             });
272        //         }
273        //         // Add component behaviours
274        //         self.entity_component_behaviour_manager
275        //             .add_behaviours_to_entity(reactive_entity_instance.clone());
276        //         // Add entity behaviours
277        //         self.entity_behaviour_manager.add_behaviours(reactive_entity_instance.clone());
278        //         // Register label
279        //         if let Some(value) = reactive_entity_instance
280        //             .get(LABEL.property_name())
281        //             .and_then(|v| v.as_str().map(|s| s.to_string()))
282        //         {
283        //             let mut writer = self.label_path_tree.write().unwrap();
284        //             writer.insert(&value, reactive_entity_instance.id);
285        //         }
286        //         self.event_manager.emit_event(SystemEvent::EntityInstanceCreated(reactive_entity_instance.id));
287        //         Ok(reactive_entity_instance)
288        //     }
289        //     Err(e) => Err(ReactiveEntityRegistrationError::EntityInstanceCreationError(e)),
290        // }
291    }
292
293    fn register_or_merge_reactive_instance(&self, entity_instance: ReactiveEntity) -> Result<ReactiveEntity, ReactiveEntityRegistrationError> {
294        match self.get(entity_instance.id) {
295            // No instance with the given id exists: register as new instance and return it
296            None => self.register_reactive_instance(entity_instance),
297            // Instance with the given id exists. Don't register but return the existing reactive instance instead of the given instance
298            Some(entity_instance) => Ok(entity_instance),
299        }
300    }
301
302    fn add_component(&self, id: Uuid, component_ty: &ComponentTypeId) -> Result<(), ReactiveEntityComponentAddError> {
303        match self.component_manager.get(component_ty) {
304            Some(component) => {
305                match self.get(id) {
306                    Some(entity_instance) => {
307                        // Add components with properties
308                        entity_instance.add_component_with_properties(&component);
309                        // Add component behaviours
310                        self.entity_component_behaviour_manager
311                            .add_behaviours_to_entity_component(entity_instance, component);
312                        Ok(())
313                    }
314                    None => Err(ReactiveEntityComponentAddError::MissingInstance(id)),
315                }
316            }
317            None => Err(ReactiveEntityComponentAddError::MissingComponent(component_ty.clone())),
318        }
319    }
320
321    fn remove_component(&self, id: Uuid, component_ty: &ComponentTypeId) {
322        if let Some(component) = self.component_manager.get(component_ty) {
323            if let Some(entity_instance) = self.get(id) {
324                // Remove component
325                entity_instance.remove_component(component_ty);
326                // We do not remove properties because we cannot asure that the removal is intended
327                // Remove component behaviours
328                self.entity_component_behaviour_manager
329                    .remove_behaviours_from_entity_component(entity_instance, component);
330            }
331        }
332    }
333
334    fn add_property(&self, id: Uuid, property_name: &str, mutability: Mutability, value: Value) -> Result<(), ReactiveEntityPropertyAddError> {
335        match self.get(id) {
336            Some(entity_instance) => {
337                if entity_instance.has_property(property_name) {
338                    return Err(ReactiveEntityPropertyAddError::PropertyAlreadyExists(property_name.to_string()));
339                }
340                entity_instance.add_property(property_name, mutability, value);
341                Ok(())
342            }
343            None => Err(ReactiveEntityPropertyAddError::MissingInstance(id)),
344        }
345    }
346
347    fn remove_property(&self, id: Uuid, property_name: &str) -> Result<(), ReactiveEntityPropertyRemoveError> {
348        match self.get(id) {
349            Some(entity_instance) => {
350                if !entity_instance.has_property(property_name) {
351                    return Err(ReactiveEntityPropertyRemoveError::MissingProperty(property_name.to_string()));
352                }
353                for component_ty in entity_instance.get_components() {
354                    if let Some(component) = self.component_manager.get(&component_ty) {
355                        if component.has_own_property(property_name) {
356                            return Err(ReactiveEntityPropertyRemoveError::PropertyInUseByComponent(property_name.to_string(), component_ty.clone()));
357                        }
358                    }
359                }
360                entity_instance.remove_property(property_name);
361                Ok(())
362            }
363            None => Err(ReactiveEntityPropertyRemoveError::MissingInstance(id)),
364        }
365    }
366
367    fn add_behaviour_to_all_entity_instances(&self, entity_behaviour_ty: &EntityBehaviourTypeId) {
368        for entity_instance in self.reactive_entity_instances.iter() {
369            if entity_instance.ty == entity_behaviour_ty.entity_ty {
370                self.entity_behaviour_manager
371                    .add_behaviour(entity_instance.clone(), &entity_behaviour_ty.behaviour_ty);
372            }
373        }
374    }
375
376    fn add_behaviour_to_all_entity_components(&self, component_behaviour_ty: &ComponentBehaviourTypeId) {
377        for entity_instance in self.reactive_entity_instances.iter() {
378            if entity_instance.components.contains(&component_behaviour_ty.component_ty) {
379                self.entity_component_behaviour_manager
380                    .add_behaviour_to_entity_component(entity_instance.clone(), component_behaviour_ty);
381            }
382        }
383    }
384
385    // fn commit(&self, id: Uuid) {
386    //     if let Some(reactive_entity_instance) = self.get(id) {
387    //         self.entity_instance_manager.commit(reactive_entity_instance.into());
388    //     }
389    // }
390
391    // TODO: Important: Check if the entity is part of relations
392    fn delete(&self, id: Uuid) -> bool {
393        let mut result = false;
394        if self.has(id) {
395            // TODO: check for relations
396            result = self.unregister_reactive_instance(id);
397        }
398        // TODO: remove label
399        // self.entity_instance_manager.delete(id);
400        self.reactive_instance_event_manager
401            .emit_event(ReactiveInstanceEvent::EntityInstanceDeleted(id));
402        result
403    }
404
405    // TODO: fn delete_and_delete_relations(&self, id: Uuid) {}
406
407    fn unregister_reactive_instance(&self, id: Uuid) -> bool {
408        match self.get(id) {
409            Some(entity_instance) => {
410                // Remove entity behaviours
411                self.entity_behaviour_manager.remove_behaviours(entity_instance.clone());
412                // Remove entity component behaviours
413                self.entity_component_behaviour_manager.remove_behaviours_from_entity(entity_instance);
414            }
415            None => {
416                // Remove entity behaviours
417                self.entity_behaviour_manager.remove_behaviours_by_id(&id);
418                // Remove entity component behaviours
419                self.entity_component_behaviour_manager.remove_behaviours_by_id(&id);
420            }
421        }
422        self.reactive_entity_instances.remove(&id).is_some()
423    }
424
425    fn handle_component_added_events(&self) {
426        let component_manager = self.component_manager.clone();
427        let component_behaviour_manager = self.entity_component_behaviour_manager.clone();
428        let reactive_entity_instances = self.reactive_entity_instances.clone();
429        let running = self.running.clone();
430        if let Some(receiver) = self.event_channels.receiver(&HANDLE_ID_ENTITY_TYPE_COMPONENT_ADDED) {
431            tokio::spawn(async move {
432                while running.load(Ordering::Relaxed) {
433                    match receiver.try_recv() {
434                        Ok(type_definition_component_event) => {
435                            if let Ok(type_definition_component) = TypeDefinitionComponent::try_from(type_definition_component_event.clone()) {
436                                if let Some(component) = component_manager.get(&type_definition_component.component_ty) {
437                                    for instance in reactive_entity_instances
438                                        .iter()
439                                        .filter(|instance| instance.ty.type_definition() == type_definition_component.type_definition)
440                                        .map(|instance| instance.value().clone())
441                                    {
442                                        instance.add_component_with_properties(&component);
443                                        component_behaviour_manager.add_behaviours_to_entity_component(instance, component.clone());
444                                    }
445                                }
446                            }
447                        }
448                        Err(_) => {
449                            sleep(tokio::time::Duration::from_millis(100)).await;
450                        }
451                    }
452                }
453            });
454        }
455    }
456
457    fn handle_component_removed_events(&self) {
458        let component_manager = self.component_manager.clone();
459        let component_behaviour_manager = self.entity_component_behaviour_manager.clone();
460        let reactive_entity_instances = self.reactive_entity_instances.clone();
461        let running = self.running.clone();
462        if let Some(receiver) = self.event_channels.receiver(&HANDLE_ID_ENTITY_TYPE_COMPONENT_REMOVED) {
463            tokio::spawn(async move {
464                while running.load(Ordering::Relaxed) {
465                    match receiver.try_recv() {
466                        Ok(type_definition_component_event) => {
467                            if let Ok(type_definition_component) = TypeDefinitionComponent::try_from(type_definition_component_event.clone()) {
468                                if let Some(component) = component_manager.get(&type_definition_component.component_ty) {
469                                    for reactive_entity_instance in reactive_entity_instances
470                                        .iter()
471                                        .filter(|entity_instance| entity_instance.type_definition() == type_definition_component.type_definition)
472                                        .map(|entity_instance| entity_instance.value().clone())
473                                    {
474                                        reactive_entity_instance.remove_component(&component.ty);
475                                        component_behaviour_manager.remove_behaviours_from_entity_component(reactive_entity_instance, component.clone());
476                                    }
477                                }
478                            }
479                        }
480                        Err(_) => {
481                            sleep(tokio::time::Duration::from_millis(100)).await;
482                        }
483                    }
484                }
485            });
486        }
487    }
488
489    fn handle_property_added_events(&self) {
490        let entity_type_manager = self.entity_type_manager.clone();
491        let reactive_entity_instances = self.reactive_entity_instances.clone();
492        let running = self.running.clone();
493        if let Some(receiver) = self.event_channels.receiver(&HANDLE_ID_ENTITY_TYPE_PROPERTY_ADDED) {
494            tokio::spawn(async move {
495                while running.load(Ordering::Relaxed) {
496                    match receiver.try_recv() {
497                        Ok(type_definition_property_event) => {
498                            if let Ok(type_definition_property) = TypeDefinitionProperty::try_from(type_definition_property_event.clone()) {
499                                if let Ok(entity_ty) = EntityTypeId::try_from(&type_definition_property.type_definition) {
500                                    if let Some(entity_type) = entity_type_manager.get(&entity_ty) {
501                                        for reactive_entity_instance in reactive_entity_instances
502                                            .iter()
503                                            .filter(|entity_instance| entity_instance.ty == entity_ty)
504                                            .map(|entity_instance| entity_instance.value().clone())
505                                        {
506                                            if let Some(property_type) = entity_type.get_own_property(&type_definition_property.property) {
507                                                reactive_entity_instance.add_property_by_type(&property_type);
508                                            }
509                                        }
510                                    }
511                                }
512                            }
513                        }
514                        Err(_) => {
515                            sleep(tokio::time::Duration::from_millis(100)).await;
516                        }
517                    }
518                }
519            });
520        }
521    }
522
523    fn handle_property_removed_events(&self) {
524        let reactive_entity_instances = self.reactive_entity_instances.clone();
525        let running = self.running.clone();
526        if let Some(receiver) = self.event_channels.receiver(&HANDLE_ID_ENTITY_TYPE_PROPERTY_REMOVED) {
527            tokio::spawn(async move {
528                while running.load(Ordering::Relaxed) {
529                    match receiver.try_recv() {
530                        Ok(type_definition_property_event) => {
531                            if let Ok(type_definition_property) = TypeDefinitionProperty::try_from(type_definition_property_event.clone()) {
532                                if let Ok(entity_ty) = EntityTypeId::try_from(&type_definition_property.type_definition) {
533                                    for reactive_entity_instance in reactive_entity_instances
534                                        .iter()
535                                        .filter(|entity_instance| entity_instance.ty == entity_ty)
536                                        .map(|entity_instance| entity_instance.value().clone())
537                                    {
538                                        reactive_entity_instance.remove_property(&type_definition_property.property);
539                                    }
540                                }
541                            }
542                        }
543                        Err(_) => {
544                            sleep(tokio::time::Duration::from_millis(100)).await;
545                        }
546                    }
547                }
548            });
549        }
550    }
551}
552
553impl TypeSystemEventSubscriber for ReactiveEntityManagerImpl {
554    fn subscribe_type_system_event(&self, event_type: TypeSystemEventTypes, handle_id: u128) {
555        if let Some(entity_instance) = self.type_system_event_manager.get_type_system_event_instance(event_type) {
556            if let Some(sender) = self.event_channels.sender(&handle_id) {
557                entity_instance.observe_with_handle(
558                    &EVENT.property_name(),
559                    move |v| {
560                        let _ = sender.send(v.clone());
561                    },
562                    handle_id,
563                );
564            }
565        }
566    }
567
568    fn unsubscribe_type_system_event(&self, event_type: TypeSystemEventTypes, handle_id: u128) {
569        if let Some(entity_instance) = self.type_system_event_manager.get_type_system_event_instance(event_type) {
570            entity_instance.remove_observer(&EVENT.property_name(), handle_id);
571        }
572    }
573}
574
575#[async_trait]
576impl Lifecycle for ReactiveEntityManagerImpl {
577    async fn post_init(&self) {
578        for type_system_event_instance in self.type_system_event_manager.get_type_system_event_instances() {
579            if let Err(e) = self.register_reactive_instance(type_system_event_instance) {
580                error!("Failed to register type system event instance: {e:?}");
581                // TODO: Propagate this error
582            }
583        }
584
585        for reactive_instance_event_instance in self.reactive_instance_event_manager.get_reactive_instance_event_instances() {
586            if let Err(e) = self.register_reactive_instance(reactive_instance_event_instance) {
587                error!("Failed to register reactive instance event instance: {e:?}");
588                // TODO: Propagate this error
589            }
590        }
591
592        self.subscribe_type_system_event(TypeSystemEventTypes::EntityTypeComponentAdded, HANDLE_ID_ENTITY_TYPE_COMPONENT_ADDED);
593        self.subscribe_type_system_event(TypeSystemEventTypes::EntityTypeComponentRemoved, HANDLE_ID_ENTITY_TYPE_COMPONENT_REMOVED);
594        self.subscribe_type_system_event(TypeSystemEventTypes::EntityTypePropertyAdded, HANDLE_ID_ENTITY_TYPE_PROPERTY_ADDED);
595        self.subscribe_type_system_event(TypeSystemEventTypes::EntityTypePropertyRemoved, HANDLE_ID_ENTITY_TYPE_PROPERTY_REMOVED);
596
597        self.handle_component_added_events();
598        self.handle_component_removed_events();
599        self.handle_property_added_events();
600        self.handle_property_removed_events();
601    }
602
603    async fn pre_shutdown(&self) {
604        self.running.store(false, Ordering::Relaxed);
605
606        self.unsubscribe_type_system_event(TypeSystemEventTypes::EntityTypePropertyRemoved, HANDLE_ID_ENTITY_TYPE_PROPERTY_REMOVED);
607        self.unsubscribe_type_system_event(TypeSystemEventTypes::EntityTypePropertyAdded, HANDLE_ID_ENTITY_TYPE_PROPERTY_ADDED);
608        self.unsubscribe_type_system_event(TypeSystemEventTypes::EntityTypeComponentRemoved, HANDLE_ID_ENTITY_TYPE_COMPONENT_REMOVED);
609        self.unsubscribe_type_system_event(TypeSystemEventTypes::EntityTypeComponentAdded, HANDLE_ID_ENTITY_TYPE_COMPONENT_ADDED);
610        for event_instance in self.reactive_instance_event_manager.get_reactive_instance_event_instances() {
611            self.unregister_reactive_instance(event_instance.id);
612        }
613        for event_instance in self.type_system_event_manager.get_type_system_event_instances() {
614            self.unregister_reactive_instance(event_instance.id);
615        }
616    }
617}
618
619#[cfg(test)]
620mod tests {
621    use default_test::DefaultTest;
622
623    // Do not remove! This import is necessary to make the dependency injection work
624    #[allow(unused_imports)]
625    use reactive_graph_behaviour_service_impl::BehaviourSystemImpl;
626    use reactive_graph_graph::EntityType;
627    use reactive_graph_graph::EntityTypeId;
628    use reactive_graph_graph::PropertyTypes;
629    use reactive_graph_reactive_model_impl::ReactiveEntity;
630    use reactive_graph_reactive_service_api::ReactiveSystem;
631    use reactive_graph_utils_test::r_string;
632    // Do not remove! This import is necessary to make the dependency injection work
633    #[allow(unused_imports)]
634    use reactive_graph_type_system_impl::TypeSystemImpl;
635
636    use crate::ReactiveSystemImpl;
637
638    #[test]
639    fn test_register_reactive_entity_instance() {
640        reactive_graph_utils_test::init_logger();
641
642        let reactive_system = reactive_graph_di::get_container::<ReactiveSystemImpl>();
643        let type_system = reactive_system.type_system();
644
645        let entity_type_manager = type_system.get_entity_type_manager();
646        let reactive_entity_manager = reactive_system.get_reactive_entity_manager();
647
648        let entity_type = EntityType::default_test();
649        let reactive_entity = ReactiveEntity::builder_from_entity_type(&entity_type).build();
650
651        // Check that we cannot register an reactive entity with an entity type which doesn't exist
652        assert!(reactive_entity_manager.register_reactive_instance(reactive_entity.clone()).is_err());
653        // assert_eq!(ReactiveEntityRegistrationError::UnknownEntityType(entity_type.ty.clone()), result.unwrap_err(), "It shouldn't be allowed to register a reactive entity for a non-existent entity type!");
654        assert!(!reactive_entity_manager.has(reactive_entity.id), "There shouldn't be a reactive entity with the id");
655
656        // Register entity type
657        let entity_type = entity_type_manager.register(entity_type).expect("Failed to register entity type");
658        // Register the reactive entity
659        let reactive_entity = reactive_entity_manager
660            .register_reactive_instance(reactive_entity)
661            .expect("Failed to register the reactive entity");
662        // Register the reactive entity
663        assert!(
664            reactive_entity_manager.has(reactive_entity.id),
665            "The reactive entity with the id should be known by the reactive_entity_manager!"
666        );
667        // Get the reactive entity by id
668        let id = reactive_entity.id;
669        let reactive_entity = reactive_entity_manager
670            .get(reactive_entity.id)
671            .expect("Failed to get the reactive entity by id!");
672        assert_eq!(id, reactive_entity.id, "The id of the reactive entity doesn't match!");
673        assert_eq!(entity_type.ty, reactive_entity.ty, "The entity type id doesn't match!");
674    }
675
676    #[test]
677    fn test_unregister_reactive_entity_instance() {
678        reactive_graph_utils_test::init_logger();
679
680        let reactive_system = reactive_graph_di::get_container::<ReactiveSystemImpl>();
681        let type_system = reactive_system.type_system();
682        let entity_type_manager = type_system.get_entity_type_manager();
683        let reactive_entity_manager = reactive_system.get_reactive_entity_manager();
684
685        let entity_type = EntityType::builder()
686            .ty(EntityTypeId::default_test())
687            .properties(PropertyTypes::new_with_string_property(r_string()))
688            .build();
689        // Register entity type
690        let entity_type = entity_type_manager.register(entity_type).expect("Failed to register entity type");
691
692        let reactive_entity = ReactiveEntity::builder_from_entity_type(&entity_type).build();
693        let id = reactive_entity.id;
694
695        // Register the reactive entity
696        let _reactive_entity = reactive_entity_manager
697            .register_reactive_instance(reactive_entity)
698            .expect("Failed to register the reactive entity");
699
700        assert!(reactive_entity_manager.has(id), "The reactive entity should be registered!");
701        assert!(reactive_entity_manager.unregister_reactive_instance(id), "The reactive entity should have been unregistered!");
702        assert!(!reactive_entity_manager.has(id), "The reactive entity shouldn't be registered anymore!");
703    }
704
705    #[test]
706    fn test_not_register_twice_reactive_entity_instance() {
707        reactive_graph_utils_test::init_logger();
708
709        let reactive_system = reactive_graph_di::get_container::<ReactiveSystemImpl>();
710        let type_system = reactive_system.type_system();
711        let entity_type_manager = type_system.get_entity_type_manager();
712        let reactive_entity_manager = reactive_system.get_reactive_entity_manager();
713
714        let entity_type = EntityType::builder()
715            .ty(EntityTypeId::default_test())
716            .properties(PropertyTypes::new_with_string_property(r_string()))
717            .build();
718
719        let reactive_entity = ReactiveEntity::builder_from_entity_type(&entity_type).build();
720        let id = reactive_entity.id;
721
722        // Check that we cannot create an entity instance with a type which doesn't exist
723        assert!(
724            reactive_entity_manager.register_reactive_instance(reactive_entity.clone()).is_err(),
725            "The reactive entity shouldn't have been registered because the entity type was not registered!"
726        );
727
728        assert!(!reactive_entity_manager.has(id), "There shouldn't be a reactive entity with id!");
729        assert_eq!(reactive_entity_manager.count(), 0);
730
731        // Register entity type
732        let _entity_type = entity_type_manager.register(entity_type).expect("Failed to register entity type");
733
734        let reactive_entity = reactive_entity_manager
735            .register_reactive_instance(reactive_entity)
736            .expect("Failed to register the reactive entity!");
737
738        assert!(reactive_entity_manager.has(id), "The reactive entity with id should be registered!");
739        assert_eq!(reactive_entity_manager.count(), 1);
740
741        assert!(
742            reactive_entity_manager.register_reactive_instance(reactive_entity).is_err(),
743            "The reactive entity was registered twice!"
744        );
745
746        assert!(reactive_entity_manager.has(id), "The reactive entity with id should be registered!");
747        assert_eq!(reactive_entity_manager.count(), 1);
748    }
749}