1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use crate::ecs::{Entity, Universe, WorldRef};
use std::collections::HashSet;

#[derive(Debug, Default)]
pub struct EntityChanges {
    entities: HashSet<Entity>,
    spawned: HashSet<Entity>,
    despawned: HashSet<Entity>,
}

impl EntityChanges {
    pub fn has_changed(&self) -> bool {
        !self.spawned.is_empty() || !self.despawned.is_empty()
    }

    pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
        self.entities.iter().copied()
    }

    pub fn spawned(&self) -> impl Iterator<Item = Entity> + '_ {
        self.spawned.iter().copied()
    }

    pub fn despawned(&self) -> impl Iterator<Item = Entity> + '_ {
        self.despawned.iter().copied()
    }
}

pub type EntityLifeCycleSystemResources<'a> = (WorldRef, &'a mut EntityChanges);

pub fn entity_life_cycle_system(universe: &mut Universe) {
    let (world, mut changes) = universe.query_resources::<EntityLifeCycleSystemResources>();

    let old = std::mem::replace(
        &mut changes.entities,
        world.iter().map(|id| id.entity()).collect(),
    );
    changes.spawned = changes.entities.difference(&old).copied().collect();
    changes.despawned = old.difference(&changes.entities).copied().collect();
}