bevy_ecs/observer/
entity_observer.rs

1use crate::{
2    component::{Component, ComponentHooks, StorageType},
3    entity::Entity,
4    observer::ObserverState,
5};
6
7/// Tracks a list of entity observers for the [`Entity`] [`ObservedBy`] is added to.
8#[derive(Default)]
9pub(crate) struct ObservedBy(pub(crate) Vec<Entity>);
10
11impl Component for ObservedBy {
12    const STORAGE_TYPE: StorageType = StorageType::SparseSet;
13
14    fn register_component_hooks(hooks: &mut ComponentHooks) {
15        hooks.on_remove(|mut world, entity, _| {
16            let observed_by = {
17                let mut component = world.get_mut::<ObservedBy>(entity).unwrap();
18                std::mem::take(&mut component.0)
19            };
20            for e in observed_by {
21                let (total_entities, despawned_watched_entities) = {
22                    let Some(mut entity_mut) = world.get_entity_mut(e) else {
23                        continue;
24                    };
25                    let Some(mut state) = entity_mut.get_mut::<ObserverState>() else {
26                        continue;
27                    };
28                    state.despawned_watched_entities += 1;
29                    (
30                        state.descriptor.entities.len(),
31                        state.despawned_watched_entities as usize,
32                    )
33                };
34
35                // Despawn Observer if it has no more active sources.
36                if total_entities == despawned_watched_entities {
37                    world.commands().entity(e).despawn();
38                }
39            }
40        });
41    }
42}