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
use crate::entity::{EntityStore, EntityId};
use crate::arch::{ArchStore, ArchetypeId, NewEntityResult};
use crate::component::Component;

pub struct World {
    entity_store: EntityStore,
    arch_store: ArchStore,
}

impl World {
    pub fn new() -> Self {
        Self {
            entity_store: EntityStore::new(),
            arch_store: ArchStore::new(),
        }
    }

    kiwi_internal_macros::gen_spawn_entity!();

    /// Kills an entity
    pub fn kill(&mut self, ent_id: EntityId) {
        let ent = &self.entity_store.entities()[ent_id as usize];
        self.arch_store.remove_entity(ent);

        self.entity_store.kill(ent_id);
    }
    
    pub fn entity_count(&self) -> usize {
        self.entity_store.entity_count()
    }

    /// Returns the component of type `T` for entity with id `entity`.
    ///
    /// # Panics
    /// if the component does not exist for the given entity
    pub fn get_component<T: Component + 'static>(&self, entity: EntityId) -> &T {
        let entity = &self.entity_store.entities()[entity as usize];
        let comp = self.arch_store.get_archetype(entity.arch_id).get_component::<T>(entity.arch_row); // Panics if the component does not exist for this entity
        let dyn_comp = &**unsafe { comp.assume_init_ref() }; // The user always needs to specify the components for the entity
        let comp: Option<&T> = dyn_comp.as_any().downcast_ref::<T>();
        let comp: &T = unsafe { comp.unwrap_unchecked() };
        comp
    }
    
    /// Set an entity's component.
    ///
    /// # Panics
    /// if the component does not exist for the given entity
    pub fn set_component<T: Component + 'static>(&mut self, entity: EntityId, comp: T) {
        let entity = &self.entity_store.entities()[entity as usize];
        self.arch_store.get_archetype_mut(entity.arch_id).set_component(entity.arch_row, comp);
    }
    
    /// Check whether an enttity contains the given component
    pub fn has_component<C: Component>(&self, entity: EntityId) -> bool {
        let entity = &self.entity_store.entities()[entity as usize];
        self.arch_store.get_archetype(entity.arch_id).has_component(C::id())
    }
}

// Queries
impl World {
    pub fn query_ids0(&self) -> Vec<EntityId> {
        self.entity_store.entities().iter()
            .enumerate()
            .map(|(id, _)| id as EntityId)
            .filter(|id| {
            self.entity_store.is_alive(*id)
        }).collect()
    }
    
    kiwi_internal_macros::gen_query!();
}