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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! TODO: Add documentation including describing how the derive macros work

use component::ComponentManager;
use entity::{BuildData, Entity, EntityBuilder, EntityData, EntityIter, EntityManager,
             EntityModifier, ModifyData};
use services::ServiceManager;
use system::SystemManager;

pub struct World<S>
where
    S: SystemManager,
{
    pub systems: S,
    pub data: DataHelper<S::Components, S::Services>,
}

pub struct DataHelper<C, M>
where
    C: ComponentManager,
    M: ServiceManager,
{
    pub components: C,
    pub services: M,
    pub(crate) entities: EntityManager<C>,
}

impl<C, M> DataHelper<C, M>
where
    C: ComponentManager,
    M: ServiceManager,
{
    pub fn with_entity_data<F, R>(&mut self, entity: Entity, closure: F) -> Option<R>
    where
        F: FnOnce(EntityData<C>, &mut C, &mut M) -> R,
    {
        if self.entities.is_valid(entity) {
            Some(closure(
                EntityData(self.entities.indexed(entity)),
                &mut self.components,
                &mut self.services,
            ))
        } else {
            None
        }
    }

    pub fn create_entity<F>(&mut self, builder: F) -> Entity
    where
        F: FnOnce(BuildData<C>, &mut C, &mut M),
    {
        self.create_entity_with_builder(builder)
    }

    pub fn create_entity_with_builder<B>(&mut self, builder: B) -> Entity
    where
        B: EntityBuilder<C, M>,
    {
        self.entities
            .create_entity(builder, &mut self.components, &mut self.services)
    }

    pub fn remove_entity(&mut self, entity: Entity) -> bool {
        self.entities.remove_entity(entity)
    }

    pub fn entities(&self) -> EntityIter<C> {
        self.entities.iter()
    }
}

impl<S> World<S>
where
    S: SystemManager,
{
    pub fn new() -> Self
    where
        S::Services: Default,
    {
        World::with_services(Default::default())
    }

    pub fn with_services(services: S::Services) -> Self {
        World {
            systems: S::build_manager(),
            data: DataHelper {
                services,
                components: S::Components::build_manager(),
                entities: EntityManager::new(),
            },
        }
    }

    pub fn entities(&self) -> EntityIter<S::Components> {
        self.data.entities.iter()
    }

    pub fn modify_entity<F>(&mut self, entity: Entity, modifier: F)
    where
        F: FnOnce(ModifyData<S::Components>, &mut S::Components, &mut S::Services),
    {
        self.modify_entity_with_modifer(entity, modifier)
    }

    pub fn modify_entity_with_modifer<M>(&mut self, entity: Entity, modifier: M)
    where
        M: EntityModifier<S::Components, S::Services>,
    {
        let indexed = self.data.entities.indexed(entity);
        modifier.modify(
            ModifyData(indexed),
            &mut self.data.components,
            &mut self.data.services,
        );
        self.systems.reactivated(
            EntityData(indexed),
            &self.data.components,
            &mut self.data.services,
        );
    }

    pub fn refresh(&mut self) {
        self.flush_queue();

        for entity in self.data.entities.iter() {
            self.systems
                .reactivated(entity, &self.data.components, &mut self.data.services);
        }
    }

    pub fn flush_queue(&mut self) {
        self.data.entities.flush_queue(
            &mut self.data.components,
            &mut self.data.services,
            &mut self.systems,
        );
    }

    pub fn update(&mut self) {
        self.flush_queue();
        self.systems.update(&mut self.data);
        self.flush_queue();
    }

    /// Mass delete all entities and their data
    pub fn wipe(&mut self) {
        self.flush_queue();

        for entity in self.data.entities.iter() {
            self.systems.deactivated(entity, &self.data.components, &mut self.data.services);
        }

        self.data.entities.clear();
        self.data.components.__wipe_all();
    }
}