1 module artemisd.world; 2 3 import artemisd.utils.bag; 4 import artemisd.entitymanager; 5 import artemisd.entity; 6 import artemisd.entitytemplate; 7 import artemisd.componentmanager; 8 import artemisd.entitysystem; 9 import artemisd.manager; 10 import artemisd.entityobserver; 11 12 class World 13 { 14 private EntityManager em; 15 private ComponentManager cm; 16 17 public float delta; 18 private Bag!Entity added; 19 private Bag!Entity changed; 20 private Bag!Entity deleted; 21 private Bag!Entity enabled; 22 private Bag!Entity disabled; 23 24 private Manager[] managers; 25 26 private EntitySystem[] systems; 27 28 this() 29 { 30 managers.length = 1; 31 systems.length = 1; 32 33 added = new Bag!Entity(); 34 changed = new Bag!Entity(); 35 deleted = new Bag!Entity(); 36 enabled = new Bag!Entity(); 37 disabled = new Bag!Entity(); 38 39 cm = new ComponentManager(); 40 setManager(cm); 41 42 em = new EntityManager(); 43 setManager(em); 44 } 45 46 void initialize() 47 { 48 foreach(m; managers) 49 { 50 if(m) m.initialize(); 51 } 52 53 foreach(s;systems) 54 { 55 if(s) s.initialize(); 56 } 57 } 58 59 EntityManager getEntityManager() 60 { 61 return em; 62 } 63 64 ComponentManager getComponentManager() 65 { 66 return cm; 67 } 68 69 T setManager(T)(T manager) 70 if( is(T:Manager) ) 71 { 72 import std.stdio; 73 if(managers.length <= T.TypeId) 74 managers.length = T.TypeId + 1; 75 managers[T.TypeId] = manager; 76 manager.setWorld(this); 77 78 debug 79 { 80 import std.stdio; 81 writeln(typeid(manager), "(", T.TypeId, ")", " added"); 82 } 83 return manager; 84 } 85 86 T getManager(T)() 87 if( is(T:Manager) ) 88 { 89 return cast(T)managers[T.TypeId]; 90 } 91 92 void deleteManager(M)() 93 if( is(M:Manager)) 94 { 95 managers[M.TypeId] = null; 96 } 97 98 float getDelta() 99 { 100 return delta; 101 } 102 103 void setDelta(float delta) 104 { 105 this.delta = delta; 106 } 107 108 void addEntity(Entity e) 109 { 110 added.add(e); 111 } 112 113 void changedEntity(Entity e) 114 { 115 changed.add(e); 116 } 117 118 void deleteEntity(Entity e) 119 { 120 if (!deleted.contains(e)) 121 { 122 deleted.add(e); 123 } 124 } 125 126 void enable(Entity e) 127 { 128 enabled.add(e); 129 } 130 131 void disable(Entity e) 132 { 133 disabled.add(e); 134 } 135 136 Entity createEntity() 137 { 138 return em.createEntityInstance(); 139 } 140 141 Entity createEntityFromTemplate(T : EntityTemplate, Args...)(Args args) { 142 Entity entity = em.createEntityInstance(); 143 T.buildEntity(entity, this, args); 144 return entity; 145 } 146 147 Entity getEntity(int entityId) 148 { 149 return em.getEntity(entityId); 150 } 151 152 EntitySystem[] getSystems() 153 { 154 return systems; 155 } 156 157 T setSystem(T)(T system) 158 if( is(T:EntitySystem) ) 159 { 160 return setSystem!T(system, false); 161 } 162 163 T setSystem(T)(T system, bool passive) 164 { 165 system.setWorld(this); 166 system.setPassive(passive); 167 168 if( systems.length <= T.TypeId ) 169 systems.length = T.TypeId + 1; 170 systems[T.TypeId] = system; 171 172 debug 173 { 174 import std.stdio; 175 writeln(typeid(system), "(", T.TypeId, ")", " added"); 176 } 177 178 return system; 179 } 180 181 void deleteSystem(E)() 182 if( is(E:EntitySystem) ) 183 { 184 systems[E.TypeId] = null; 185 } 186 187 private void notifySystems(Performer performer, Entity e) 188 { 189 foreach(s;systems) 190 { 191 if(s) performer.perform(s,e); 192 } 193 } 194 195 private void notifyManagers(Performer performer, Entity e) 196 { 197 foreach(m;managers) 198 { 199 if(m) performer.perform(m,e); 200 } 201 } 202 203 T getSystem(T)() 204 if( is(T:EntitySystem) ) 205 { 206 return systems[T.TypeId]; 207 } 208 209 private void check(Bag!Entity entities, Performer performer) 210 { 211 if (!entities.isEmpty()) 212 { 213 for (int i = 0; entities.size() > i; i++) 214 { 215 Entity e = entities.get(i); 216 notifyManagers(performer, e); 217 notifySystems(performer, e); 218 } 219 entities.clear(); 220 } 221 } 222 223 void process() 224 { 225 check(added, new class Performer { 226 public void perform(EntityObserver observer, Entity e) { 227 observer.added(e); 228 } 229 }); 230 231 check(changed, new class Performer { 232 public void perform(EntityObserver observer, Entity e) { 233 observer.changed(e); 234 } 235 }); 236 237 check(disabled, new class Performer { 238 public void perform(EntityObserver observer, Entity e) { 239 observer.disabled(e); 240 } 241 }); 242 243 check(enabled, new class Performer { 244 public void perform(EntityObserver observer, Entity e) { 245 observer.enabled(e); 246 } 247 }); 248 249 check(deleted, new class Performer { 250 public void perform(EntityObserver observer, Entity e) { 251 observer.deleted(e); 252 } 253 }); 254 255 cm.clean(); 256 257 foreach(s;systems) 258 { 259 if( s && !s.isPassive() ) 260 s.process(); 261 } 262 } 263 264 private interface Performer 265 { 266 void perform(EntityObserver observer, Entity e); 267 } 268 }