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
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use crate::{Entity, BitSetVec, create_bitset, BitSet, BITSET_SLICE_COUNT, BITSET_SIZE, EntityIterator};

/// Holds a list of alive entities.
/// It also holds a list of entities that were recently killed, which allows
/// to remove components of deleted entities at the end of a game frame.
pub struct Entities {
    alive: BitSetVec,
    generation: Vec<u32>,
    killed: Vec<Entity>,
    max_id: usize,
    /// helps to know if we should directly append after
    /// max_id or if we should look through the bitset.
    has_deleted: bool,
}

impl Default for Entities {
    fn default() -> Self {
        Self {
            alive: create_bitset(),
            generation: vec![0u32; BITSET_SIZE],
            killed: vec![],
            max_id: 0,
            has_deleted: false,
        }
    }
}

impl Entities {
    /// Creates a new `Entity` and returns it.
    /// This function will not reuse the index of an entity that is still in
    /// the killed entities.
    pub fn create(&mut self) -> Entity {
        if !self.has_deleted {
            let i = self.max_id;
            self.max_id += 1;
            self.alive.bit_set(i);
            Entity::new(i as u32, self.generation[i])
        } else {
            let mut section = 0;
            // Find section where at least one bit isn't set
            while self.alive[section].bit_all() {
                section += 1;
                if section > BITSET_SLICE_COUNT {
                    panic!("Exceeded maximum amount of concurrent entities.");
                }
            }
            let mut i = section * (32 * 8);
            while self.alive.bit_test(i) || self.killed.iter().any(|e| e.index() == i as u32) {
                i += 1;
            }
            self.alive.bit_set(i);
            if i >= self.max_id {
                self.max_id = i;
                self.has_deleted = false;
            }
            Entity::new(i as u32, self.generation[i])
        }
    }
    /// Checks if the `Entity` is still alive.
    /// Returns true if it is alive.
    /// Returns false if it has been killed.
    pub fn is_alive(&self, entity: Entity) -> bool {
        self.alive.bit_test(entity.index() as usize)
            && self.generation[entity.index() as usize] == entity.generation()
    }
    /// Kill an entity.
    pub fn kill(&mut self, entity: Entity) {
        if self.alive.bit_test(entity.index() as usize) {
            self.alive.bit_reset(entity.index() as usize);
            self.generation[entity.index() as usize] += 1;
            self.killed.push(entity);
            self.has_deleted = true;
        }
    }
    /// Returns entities in the killed list.
    pub fn killed(&self) -> &Vec<Entity> {
        &self.killed
    }
    /// Clears the killed entity list.
    pub fn clear_killed(&mut self) {
        self.killed.clear();
    }
    /// Returns a bitset where each index where the bit is set to 1 indicates
    /// the index of an alive entity.
    /// Useful for joining over `Entity` and `Component<T>` at the same time.
    pub fn bitset(&self) -> &BitSetVec {
        &self.alive
    }
    /// Iterates over entities using the provided bitset.
    pub fn iter_with_bitset<'a>(&'a self, bitset: std::rc::Rc<BitSetVec>) -> EntityIterator<'a> {
        EntityIterator {
            current_id: 0,
            max_id: self.max_id,
            entities: &self.alive,
            generations: &self.generation,
            bitset,
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::*;
    #[test]
    fn create_kill_entities() {
        let mut entities = Entities::default();
        let e1 = entities.create();
        let e2 = entities.create();
        let e3 = entities.create();
        assert_eq!(e1.index(), 0);
        assert_eq!(e2.index(), 1);
        assert_eq!(e3.index(), 2);
        assert_eq!(e1.generation(), 0);
        assert!(entities.is_alive(e1));
        assert!(entities.is_alive(e2));
        assert!(entities.is_alive(e3));
        entities.kill(e1);
        assert!(!entities.is_alive(e1));
        assert!(entities.is_alive(e2));
        assert!(entities.is_alive(e3));
        let e4 = entities.create();
        assert!(!entities.is_alive(e1));
        assert!(entities.is_alive(e2));
        assert!(entities.is_alive(e3));
        assert!(entities.is_alive(e4));

        assert_eq!(*entities.killed(), vec![e1]);
        entities.clear_killed();
        assert_eq!(*entities.killed(), vec![]);
    }
}