Browse code

Merge branch 'worlds-within-worlds'

Adrian Papari authored on 16/07/2014 23:12:54
Showing 13 changed files
... ...
@@ -3,6 +3,8 @@ package com.artemis;
3 3
 import java.util.BitSet;
4 4
 import java.util.Collection;
5 5
 
6
+import com.artemis.utils.Bag;
7
+
6 8
 
7 9
 /**
8 10
  * An Aspect is used by systems as a matcher against entities, to check if a
... ...
@@ -33,11 +35,16 @@ import java.util.Collection;
33 35
 public class Aspect {
34 36
 
35 37
 	/** Component bits the entity must all possess. */
36
-	private final BitSet allSet;
38
+	private BitSet allSet;
37 39
 	/** Component bits the entity must not possess. */
38
-	private final BitSet exclusionSet;
40
+	private BitSet exclusionSet;
39 41
 	/** Component bits of which the entity must possess at least one. */
40
-	private final BitSet oneSet;
42
+	private BitSet oneSet;
43
+	
44
+	private boolean isInitialized;
45
+	private final Bag<Class<? extends Component>> allTypes;
46
+	private final Bag<Class<? extends Component>> exclusionTypes;
47
+	private final Bag<Class<? extends Component>> oneTypes;
41 48
 
42 49
 
43 50
 	/**
... ...
@@ -46,9 +53,35 @@ public class Aspect {
46 53
 	 * or {@link #getEmpty}.
47 54
 	 */
48 55
 	private Aspect() {
56
+		allTypes = new Bag<Class<? extends Component>>();
57
+		exclusionTypes = new Bag<Class<? extends Component>>();
58
+		oneTypes = new Bag<Class<? extends Component>>();
59
+	}
60
+	
61
+	public void initialize(World world) {
62
+		if (isInitialized)
63
+			return;
64
+		
49 65
 		this.allSet = new BitSet();
50 66
 		this.exclusionSet = new BitSet();
51 67
 		this.oneSet = new BitSet();
68
+		
69
+		ComponentTypeFactory tf = world.getComponentManager().typeFactory;
70
+		associate(tf, allTypes, allSet);
71
+		associate(tf, exclusionTypes, exclusionSet);
72
+		associate(tf, oneTypes, oneSet);
73
+		
74
+		allTypes.clear();
75
+		exclusionTypes.clear();
76
+		oneTypes.clear();
77
+		
78
+		isInitialized = true;
79
+	}
80
+	
81
+	private static void associate(ComponentTypeFactory tf, Bag<Class<? extends Component>> types, BitSet componentBits) {
82
+		for (Class<? extends Component> t : types) {
83
+			componentBits.set(tf.getIndexFor(t));
84
+		}
52 85
 	}
53 86
 
54 87
 
... ...
@@ -137,10 +170,10 @@ public class Aspect {
137 170
 	 */
138 171
 	@SuppressWarnings("unchecked")
139 172
 	public Aspect all(Class<? extends Component> type, Class<? extends Component>... types) {
140
-		allSet.set(ComponentType.getIndexFor(type));
173
+		allTypes.add(type);
141 174
 		
142 175
 		for (Class<? extends Component> t : types) {
143
-			allSet.set(ComponentType.getIndexFor(t));
176
+			allTypes.add(t);
144 177
 		}
145 178
 
146 179
 		return this;
... ...
@@ -161,7 +194,7 @@ public class Aspect {
161 194
 	@SuppressWarnings("unchecked")
162 195
 	public Aspect all(Collection<Class<? extends Component>> types) {
163 196
 		for (Class<? extends Component> t : types) {
164
-			allSet.set(ComponentType.getIndexFor(t));
197
+			allTypes.add(t);
165 198
 		}
166 199
 
167 200
 		return this;
... ...
@@ -183,10 +216,10 @@ public class Aspect {
183 216
 	 */
184 217
 	@SuppressWarnings("unchecked")
185 218
 	public Aspect exclude(Class<? extends Component> type, Class<? extends Component>... types) {
186
-		exclusionSet.set(ComponentType.getIndexFor(type));
219
+		exclusionTypes.add(type);
187 220
 		
188 221
 		for (Class<? extends Component> t : types) {
189
-			exclusionSet.set(ComponentType.getIndexFor(t));
222
+			exclusionTypes.add(t);
190 223
 		}
191 224
 		return this;
192 225
 	}
... ...
@@ -209,7 +242,7 @@ public class Aspect {
209 242
 	@SuppressWarnings("unchecked")
210 243
 	public Aspect exclude(Collection<Class<? extends Component>> types) {
211 244
 		for (Class<? extends Component> t : types) {
212
-			exclusionSet.set(ComponentType.getIndexFor(t));
245
+			exclusionTypes.add(t);
213 246
 		}
214 247
 		return this;
215 248
 	}
... ...
@@ -227,10 +260,10 @@ public class Aspect {
227 260
 	 */
228 261
 	@SuppressWarnings("unchecked")
229 262
 	public Aspect one(Class<? extends Component> type, Class<? extends Component>... types) {
230
-		oneSet.set(ComponentType.getIndexFor(type));
263
+		oneTypes.add(type);
231 264
 		
232 265
 		for (Class<? extends Component> t : types) {
233
-			oneSet.set(ComponentType.getIndexFor(t));
266
+			oneTypes.add(t);
234 267
 		}
235 268
 		return this;
236 269
 	}
... ...
@@ -249,7 +282,7 @@ public class Aspect {
249 282
 	@SuppressWarnings("unchecked")
250 283
 	public Aspect one(Collection<Class<? extends Component>> types) {
251 284
 		for (Class<? extends Component> t : types) {
252
-			oneSet.set(ComponentType.getIndexFor(t));
285
+			oneTypes.add(t);
253 286
 		}
254 287
 		return this;
255 288
 	}
... ...
@@ -259,27 +292,6 @@ public class Aspect {
259 292
 	 * component types.
260 293
 	 * 
261 294
 	 * @param type
262
-	 *			the type the entity must possess
263
-	 * @param types
264
-	 *			the type the entity must possess
265
-	 *
266
-	 * @return an aspect that can be matched against entities
267
-	 * 
268
-	 * @deprecated
269
-	 * 
270
-	 * @see getAspectForAll
271
-	 */
272
-	@Deprecated
273
-	@SuppressWarnings("unchecked")
274
-	public static Aspect getAspectFor(Class<? extends Component> type, Class<? extends Component>... types) {
275
-		return getAspectForAll(type, types);
276
-	}
277
-	
278
-	/**
279
-	 * Creates an aspect where an entity must possess all of the specified
280
-	 * component types.
281
-	 * 
282
-	 * @param type
283 295
 	 *			a required component type
284 296
 	 * @param types
285 297
 	 *			a required component type
... ...
@@ -36,7 +36,8 @@ class BasicComponentMapper<A extends Component> extends ComponentMapper<A> {
36 36
 	 *			the world to handle components for
37 37
 	 */
38 38
 	BasicComponentMapper(Class<A> type, World world) {
39
-		this.type = ComponentType.getTypeFor(type);
39
+		ComponentTypeFactory tf = world.getComponentManager().typeFactory;
40
+		this.type = tf.getTypeFor(type);
40 41
 		components = world.getComponentManager().getComponentsByType(this.type);
41 42
 		this.classType = type;
42 43
 	}
... ...
@@ -31,6 +31,8 @@ public class ComponentManager extends Manager {
31 31
 	private final ComponentPool pooledComponents;
32 32
 	
33 33
 	private int entityContainerSize;
34
+	
35
+	protected final ComponentTypeFactory typeFactory;
34 36
 
35 37
 	/**
36 38
 	 * Creates a new instance of {@link ComponentManager}.
... ...
@@ -42,11 +44,13 @@ public class ComponentManager extends Manager {
42 44
 		packedComponentOwners = new Bag<BitSet>();
43 45
 		pooledComponents = new ComponentPool();
44 46
 		deleted = new WildBag<Entity>();
47
+		
48
+		typeFactory = new ComponentTypeFactory();
45 49
 	}
46 50
 
47 51
 	@SuppressWarnings("unchecked")
48 52
 	protected <T extends Component> T create(Entity owner, Class<T> componentClass) {
49
-		ComponentType type = ComponentType.getTypeFor(componentClass);
53
+		ComponentType type = typeFactory.getTypeFor(componentClass);
50 54
 		switch (type.getTaxonomy())
51 55
 		{
52 56
 			case BASIC:
... ...
@@ -98,7 +102,7 @@ public class ComponentManager extends Manager {
98 102
 	private void removeComponentsOfEntity(Entity e) {
99 103
 		BitSet componentBits = e.getComponentBits();
100 104
 		for (int i = componentBits.nextSetBit(0); i >= 0; i = componentBits.nextSetBit(i+1)) {
101
-			switch (ComponentType.getTaxonomy(i)) {
105
+			switch (typeFactory.getTaxonomy(i)) {
102 106
 				case BASIC:
103 107
 					componentsByType.get(i).set(e.getId(), null);
104 108
 					break;
... ...
@@ -111,7 +115,7 @@ public class ComponentManager extends Manager {
111 115
 					packedComponents.get(i).forEntity(e).reset();
112 116
 					break;
113 117
 				default:
114
-					throw new InvalidComponentException(Component.class, " unknown component type: " + ComponentType.getTaxonomy(i));
118
+					throw new InvalidComponentException(Component.class, " unknown component type: " + typeFactory.getTaxonomy(i));
115 119
 			}
116 120
 		}
117 121
 		componentBits.clear();
... ...
@@ -243,7 +247,7 @@ public class ComponentManager extends Manager {
243 247
 	public Bag<Component> getComponentsFor(Entity e, Bag<Component> fillBag) {
244 248
 		BitSet componentBits = e.getComponentBits();
245 249
 		for (int i = componentBits.nextSetBit(0); i >= 0; i = componentBits.nextSetBit(i+1)) {
246
-			if (ComponentType.isPackedComponent(i)) {
250
+			if (typeFactory.isPackedComponent(i)) {
247 251
 				fillBag.add(packedComponents.get(i));
248 252
 			} else {
249 253
 				fillBag.add(componentsByType.get(i).get(e.getId()));
... ...
@@ -90,7 +90,8 @@ public abstract class ComponentMapper<A extends Component> {
90 90
 	 */
91 91
 	@SuppressWarnings("unchecked")
92 92
 	public static <T extends Component> ComponentMapper<T> getFor(Class<T> type, World world) {
93
-		if (ComponentType.getTypeFor(type).isPackedComponent())
93
+		ComponentTypeFactory tf = world.getComponentManager().typeFactory;
94
+		if (tf.getTypeFor(type).isPackedComponent())
94 95
 			return (ComponentMapper<T>)PackedComponentMapper.create((Class<PackedComponent>)type, world);
95 96
 		else
96 97
 			return new BasicComponentMapper<T>(type, world);
... ...
@@ -1,8 +1,5 @@
1 1
 package com.artemis;
2 2
 
3
-import java.util.IdentityHashMap;
4
-
5
-import com.artemis.utils.Bag;
6 3
 import com.artemis.utils.reflect.ClassReflection;
7 4
 
8 5
 
... ...
@@ -20,22 +17,13 @@ public class ComponentType {
20 17
 		BASIC, POOLED, PACKED;
21 18
 	}
22 19
 
23
-	/**
24
-	 * Contains all generated component types, newly generated component types
25
-	 * will be stored here.
26
-	 */
27
-	private static final IdentityHashMap<Class<? extends Component>, ComponentType> componentTypes
28
-			= new IdentityHashMap<Class<? extends Component>, ComponentType>();
29
-
30
-	/** Amount of generated component types. */
31
-	private static int INDEX = 0;
32
-	/** Index of this component type in componentTypes. */
33
-	private final int index;
20
+	
34 21
 	/** The class type of the component type. */
35 22
 	private final Class<? extends Component> type;
36 23
 	/** True if component type is a {@link PackedComponent} */
37 24
 	private final Taxonomy taxonomy;
38
-	private static final Bag<ComponentType> types = new Bag<ComponentType>();
25
+	
26
+	private final int index;
39 27
 
40 28
 	/**
41 29
 	 * <b>Do not call this constructor!</b> This method is only public so that
... ...
@@ -43,9 +31,9 @@ public class ComponentType {
43 31
 	 * 
44 32
 	 *  @@see {@link ComponentType#getTypeFor(Class)}
45 33
 	 */
46
-	public ComponentType(Class<? extends Component> type) {
47
-		types.set(INDEX, this);
48
-		index = INDEX++;
34
+	public ComponentType(Class<? extends Component> type, int index) {
35
+		
36
+		this.index = index;
49 37
 		this.type = type;
50 38
 		if (ClassReflection.isAssignableFrom(PackedComponent.class, type)) {
51 39
 			taxonomy = Taxonomy.PACKED;
... ...
@@ -64,80 +52,21 @@ public class ComponentType {
64 52
 	public int getIndex() {
65 53
 		return index;
66 54
 	}
67
-
68
-	@Override
69
-	public String toString() {
70
-		return "ComponentType["+ ClassReflection.getSimpleName(type) +"] ("+index+")";
71
-	}
72 55
 	
73 56
 	protected Taxonomy getTaxonomy() {
74 57
 		return taxonomy;
75 58
 	}
76 59
 	
77
-	protected static Taxonomy getTaxonomy(int index) {
78
-		ComponentType type = types.get(index);
79
-		return type != null ? type.getTaxonomy() : Taxonomy.BASIC;
80
-	}
81
-	
82 60
 	public boolean isPackedComponent() {
83 61
 		return taxonomy == Taxonomy.PACKED;
84 62
 	}
85 63
 	
86
-	protected static boolean isPackedComponent(int index) {
87
-		ComponentType type = types.get(index);
88
-		return type != null ? type.isPackedComponent() : false;
89
-	}
90
-	
91 64
 	protected Class<? extends Component> getType() {
92 65
 		return type;
93 66
 	}
94 67
 	
95
-	/**
96
-	 * Gets the component type for the given component class.
97
-	 * <p>
98
-	 * If no component type exists yet, a new one will be created and stored
99
-	 * for later retrieval.
100
-	 * </p>
101
-	 *
102
-	 * @param c
103
-	 *			the component's class to get the type for
104
-	 *
105
-	 * @return the component's {@link ComponentType}
106
-	 */
107
-	public static ComponentType getTypeFor(Class<? extends Component> c) {
108
-		ComponentType type = componentTypes.get(c);
109
-
110
-		if (type == null) {
111
-			type = new ComponentType(c);
112
-			componentTypes.put(c, type);
113
-		}
114
-
115
-		return type;
116
-	}
117
-	
118
-	/**
119
-	 * Gets the component type for the given component class.
120
-	 * <p>
121
-	 *
122
-	 * @param c
123
-	 *			the component's class to get the type for
124
-	 *
125
-	 * @return the component's {@link ComponentType}
126
-	 */
127
-	public static ComponentType getTypeFor(int index) {
128
-		return types.get(index);
129
-	}
130
-
131
-	/**
132
-	 * Get the index of the component type of given component class.
133
-	 *
134
-	 * @param c
135
-	 *			the component class to get the type index for
136
-	 *
137
-	 * @return the component type's index
138
-	 */
139
-	public static int getIndexFor(Class<? extends Component> c) {
140
-		return getTypeFor(c).getIndex();
68
+	@Override
69
+	public String toString() {
70
+		return "ComponentType["+ ClassReflection.getSimpleName(type) +"] ("+index+")";
141 71
 	}
142
-	
143 72
 }
144 73
new file mode 100644
... ...
@@ -0,0 +1,82 @@
1
+package com.artemis;
2
+
3
+import java.util.IdentityHashMap;
4
+
5
+import com.artemis.ComponentType.Taxonomy;
6
+import com.artemis.utils.Bag;
7
+
8
+public class ComponentTypeFactory {
9
+	/**
10
+	 * Contains all generated component types, newly generated component types
11
+	 * will be stored here.
12
+	 */
13
+	private final IdentityHashMap<Class<? extends Component>, ComponentType> componentTypes
14
+			= new IdentityHashMap<Class<? extends Component>, ComponentType>();
15
+	
16
+	/** Amount of generated component types. */
17
+	private int componentTypeCount = 0;
18
+	/** Index of this component type in componentTypes. */
19
+	
20
+	private static final Bag<ComponentType> types = new Bag<ComponentType>();
21
+	
22
+	
23
+	/**
24
+	 * Gets the component type for the given component class.
25
+	 * <p>
26
+	 * If no component type exists yet, a new one will be created and stored
27
+	 * for later retrieval.
28
+	 * </p>
29
+	 *
30
+	 * @param c
31
+	 *			the component's class to get the type for
32
+	 *
33
+	 * @return the component's {@link ComponentType}
34
+	 */
35
+	public ComponentType getTypeFor(Class<? extends Component> c) {
36
+		ComponentType type = componentTypes.get(c);
37
+
38
+		if (type == null) {
39
+			int index = componentTypeCount++;
40
+			type = new ComponentType(c, index);
41
+			componentTypes.put(c, type);
42
+			types.set(index, type);
43
+		}
44
+
45
+		return type;
46
+	}
47
+	
48
+	/**
49
+	 * Gets the component type for the given component class.
50
+	 * <p>
51
+	 *
52
+	 * @param c
53
+	 *			the component's class to get the type for
54
+	 *
55
+	 * @return the component's {@link ComponentType}
56
+	 */
57
+	public ComponentType getTypeFor(int index) {
58
+		return types.get(index);
59
+	}
60
+	
61
+	/**
62
+	 * Get the index of the component type of given component class.
63
+	 *
64
+	 * @param c
65
+	 *			the component class to get the type index for
66
+	 *
67
+	 * @return the component type's index
68
+	 */
69
+	public int getIndexFor(Class<? extends Component> c) {
70
+		return getTypeFor(c).getIndex();
71
+	}
72
+	
73
+	protected Taxonomy getTaxonomy(int index) {
74
+		ComponentType type = types.get(index);
75
+		return type != null ? type.getTaxonomy() : Taxonomy.BASIC;
76
+	}
77
+	
78
+	protected boolean isPackedComponent(int index) {
79
+		ComponentType type = types.get(index);
80
+		return type != null ? type.isPackedComponent() : false;
81
+	}
82
+}
... ...
@@ -104,7 +104,8 @@ public final class Entity {
104 104
 	public <T extends Component> T createComponent(Class<T> componentKlazz) {
105 105
 		ComponentManager componentManager = world.getComponentManager();
106 106
 		T component = componentManager.create(this, componentKlazz);
107
-		componentManager.addComponent(this, ComponentType.getTypeFor(componentKlazz), component);
107
+		ComponentTypeFactory tf = world.getComponentManager().typeFactory;
108
+		componentManager.addComponent(this, tf.getTypeFor(componentKlazz), component);
108 109
 		return component;
109 110
 	}
110 111
 
... ...
@@ -118,7 +119,8 @@ public final class Entity {
118 119
 	 * @see {@link #createComponent(Class)}
119 120
 	 */
120 121
 	public Entity addComponent(Component component) {
121
-		addComponent(component, ComponentType.getTypeFor(component.getClass()));
122
+		ComponentTypeFactory tf = world.getComponentManager().typeFactory;
123
+		addComponent(component, tf.getTypeFor(component.getClass()));
122 124
 		return this;
123 125
 	}
124 126
 	
... ...
@@ -181,7 +183,8 @@ public final class Entity {
181 183
 	 * @return this entity for chaining
182 184
 	 */
183 185
 	public Entity removeComponent(Class<? extends Component> type) {
184
-		removeComponent(ComponentType.getTypeFor(type));
186
+		ComponentTypeFactory tf = world.getComponentManager().typeFactory;
187
+		removeComponent(tf.getTypeFor(type));
185 188
 		return this;
186 189
 	}
187 190
 
... ...
@@ -245,7 +248,8 @@ public final class Entity {
245 248
 	 */
246 249
 	@SuppressWarnings("unchecked")
247 250
 	public <T extends Component> T getComponent(Class<T> type) {
248
-		return (T)getComponent(ComponentType.getTypeFor(type));
251
+		ComponentTypeFactory tf = world.getComponentManager().typeFactory;
252
+		return (T)getComponent(tf.getTypeFor(type));
249 253
 	}
250 254
 
251 255
 	/**
... ...
@@ -1,7 +1,6 @@
1 1
 package com.artemis;
2 2
 
3 3
 import java.util.BitSet;
4
-import java.util.IdentityHashMap;
5 4
 
6 5
 import com.artemis.utils.ImmutableBag;
7 6
 
... ...
@@ -19,7 +18,7 @@ import com.artemis.utils.ImmutableBag;
19 18
 public abstract class EntitySystem implements EntityObserver {
20 19
 
21 20
 	/** The system's index in the SystemIndexManager. */
22
-	private final int systemIndex;
21
+	private int systemIndex;
23 22
 	/** The world this system belongs to. */
24 23
 	protected World world;
25 24
 	
... ...
@@ -34,19 +33,20 @@ public abstract class EntitySystem implements EntityObserver {
34 33
 	/** Collects entities to be deleted from the system after processing. */
35 34
 	private final WildBag<Entity> delayedDeletion;
36 35
 	/** Component bits entities must possess for the system to be interested. */
37
-	private final BitSet allSet;
36
+	private BitSet allSet;
38 37
 	/** Component bits entities must not possess for the system to be interested. */
39
-	private final BitSet exclusionSet;
38
+	private BitSet exclusionSet;
40 39
 	/** Component bits entities must at least possess one for the system to be interested. */
41
-	private final BitSet oneSet;
40
+	private BitSet oneSet;
42 41
 	/** If the system is passive or not. */
43 42
 	private boolean passive;
44 43
 	/** If the system is enabled or not. */
45 44
 	private boolean enabled;
46 45
 	/** If the system is interested in no entities at all. */
47
-	private final boolean dummy;
46
+	private boolean dummy;
48 47
 	/** If the system is currently processing. */
49 48
 	private boolean isProcessing;
49
+	private Aspect aspect;
50 50
 
51 51
 	/**
52 52
 	 * Creates an entity system that uses the specified aspect as a matcher
... ...
@@ -56,15 +56,11 @@ public abstract class EntitySystem implements EntityObserver {
56 56
 	 *			to match against entities
57 57
 	 */
58 58
 	public EntitySystem(Aspect aspect) {
59
+		this.aspect = aspect;
59 60
 		activeIds = new BitSet();
60 61
 		actives = new WildBag<Entity>();
61 62
 		
62 63
 		delayedDeletion = new WildBag<Entity>();
63
-		allSet = aspect.getAllSet();
64
-		exclusionSet = aspect.getExclusionSet();
65
-		oneSet = aspect.getOneSet();
66
-		systemIndex = SystemIndexManager.getIndexFor(this.getClass());
67
-		dummy = allSet.isEmpty() && oneSet.isEmpty(); // This system can't possibly be interested in any entity, so it must be "dummy"
68 64
 		
69 65
 		enabled = true;
70 66
 		isProcessing = false;
... ...
@@ -351,6 +347,14 @@ public abstract class EntitySystem implements EntityObserver {
351 347
 	 *			the world to set
352 348
 	 */
353 349
 	protected final void setWorld(World world) {
350
+		aspect.initialize(world);
351
+		allSet = aspect.getAllSet();
352
+		exclusionSet = aspect.getExclusionSet();
353
+		oneSet = aspect.getOneSet();
354
+		dummy = allSet.isEmpty() && oneSet.isEmpty(); // This system can't possibly be interested in any entity, so it must be "dummy"
355
+		
356
+		systemIndex = world.systemIndex.getIndexFor(this.getClass());
357
+		
354 358
 		this.world = world;
355 359
 	}
356 360
 
... ...
@@ -397,44 +401,4 @@ public abstract class EntitySystem implements EntityObserver {
397 401
 	 * see {@link World#dispose()}
398 402
 	 */
399 403
 	protected void dispose() {}
400
-
401
-	/**
402
-	 * Used to generate a unique bit for each system.
403
-	 * <p>
404
-	 * Only used internally in EntitySystem.
405
-	 * </p>
406
-	 */
407
-	private static final class SystemIndexManager {
408
-
409
-		/** Amount of EntitySystem indices. */
410
-		private static int INDEX = 0;
411
-		
412
-		/**
413
-		 * Contains the class types of all created systems.
414
-		 * <p>
415
-		 * Only one system per class is permitted in the world.
416
-		 * </p>
417
-		 */
418
-		private static final IdentityHashMap<Class<? extends EntitySystem>, Integer> indices
419
-				= new IdentityHashMap<Class<? extends EntitySystem>, Integer>();
420
-
421
-		/**
422
-		 * Called by the EntitySystem constructor.
423
-		 * Will give the new EntitySystem the next index, and store the systems
424
-		 * class as an (Index, Class) entry.
425
-		 *
426
-		 * @param es
427
-		 *			the systems class type
428
-		 *
429
-		 * @return the systems index
430
-		 */
431
-		private static int getIndexFor(Class<? extends EntitySystem> es) {
432
-			Integer index = indices.get(es);
433
-			if(index == null) {
434
-				index = INDEX++;
435
-				indices.put(es, index);
436
-			}
437
-			return index;
438
-		}
439
-	}
440 404
 }
... ...
@@ -38,7 +38,7 @@ class PackedComponentMapper<A extends PackedComponent> extends ComponentMapper<A
38 38
 	 */
39 39
 	private PackedComponentMapper(Class<A> type, World world) {
40 40
 		ComponentManager cm = world.getComponentManager();
41
-		owners = cm.getPackedComponentOwners(ComponentType.getTypeFor(type));
41
+		owners = cm.getPackedComponentOwners(cm.typeFactory.getTypeFor(type));
42 42
 		
43 43
 		this.classType = type;
44 44
 		component = newInstance(type);
45 45
new file mode 100644
... ...
@@ -0,0 +1,43 @@
1
+package com.artemis;
2
+
3
+import java.util.IdentityHashMap;
4
+
5
+/**
6
+ * Used to generate a unique bit for each system.
7
+ * <p>
8
+ * Only used internally in EntitySystem.
9
+ * </p>
10
+ */
11
+final class SystemIndexManager {
12
+
13
+	/** Amount of EntitySystem indices. */
14
+	private int INDEX = 0;
15
+	
16
+	/**
17
+	 * Contains the class types of all created systems.
18
+	 * <p>
19
+	 * Only one system per class is permitted in the world.
20
+	 * </p>
21
+	 */
22
+	private final IdentityHashMap<Class<? extends EntitySystem>, Integer> indices
23
+			= new IdentityHashMap<Class<? extends EntitySystem>, Integer>();
24
+
25
+	/**
26
+	 * Called by the EntitySystem constructor.
27
+	 * Will give the new EntitySystem the next index, and store the systems
28
+	 * class as an (Index, Class) entry.
29
+	 *
30
+	 * @param es
31
+	 *			the systems class type
32
+	 *
33
+	 * @return the systems index
34
+	 */
35
+	int getIndexFor(Class<? extends EntitySystem> es) {
36
+		Integer index = indices.get(es);
37
+		if(index == null) {
38
+			index = INDEX++;
39
+			indices.put(es, index);
40
+		}
41
+		return index;
42
+	}
43
+}
0 44
\ No newline at end of file
... ...
@@ -90,6 +90,8 @@ public class World {
90 90
 	 * Contains all uninitilized systems. *
91 91
 	 */
92 92
 	private final Bag<EntitySystem> systemsToInit;
93
+	final SystemIndexManager systemIndex;
94
+	
93 95
 	private boolean registerUuids;
94 96
 
95 97
 
... ...
@@ -130,6 +132,8 @@ public class World {
130 132
 		enabledPerformer = new EnabledPerformer();
131 133
 		disabledPerformer = new DisabledPerformer();
132 134
 
135
+		systemIndex = new SystemIndexManager();
136
+		
133 137
 		cm = new ComponentManager(expectedEntityCount);
134 138
 		setManager(cm);
135 139
 
... ...
@@ -20,8 +20,8 @@ public class ComponentManagerTest {
20 20
 		world.initialize();
21 21
 
22 22
 		try {
23
-			Field field = field("INDEX");
24
-			field.setInt(null, 0xffff);
23
+			Field field = field("componentTypeCount");
24
+			field.setInt(world.getComponentManager().typeFactory, 0xffff);
25 25
 		} catch (NoSuchFieldException e) {
26 26
 			fail(e.getMessage());
27 27
 		} catch (SecurityException e) {
... ...
@@ -36,26 +36,29 @@ public class ComponentManagerTest {
36 36
 	@Test
37 37
 	public void ensure_basic_components_dont_throw_aioob() throws Exception {
38 38
 		world.getMapper(Basic.class);
39
-		assertTrue(0xffff <= field("INDEX").getInt(null));
40
-		assertEquals(0xffff, ComponentType.getIndexFor(Basic.class));
39
+		ComponentTypeFactory typeFactory = world.getComponentManager().typeFactory;
40
+		assertTrue(0xffff <= field("componentTypeCount").getInt(typeFactory));
41
+		assertEquals(0xffff, typeFactory.getTypeFor(Basic.class).getIndex());
41 42
 	}
42 43
 	
43 44
 	@Test
44 45
 	public void ensure_pooled_components_dont_throw_aioob() throws Exception {
45 46
 		world.getMapper(Pooled.class);
46
-		assertTrue(0xffff <= field("INDEX").getInt(null));
47
-		assertEquals(0xffff, ComponentType.getIndexFor(Pooled.class));
47
+		ComponentTypeFactory typeFactory = world.getComponentManager().typeFactory;
48
+		assertTrue(0xffff <= field("componentTypeCount").getInt(typeFactory));
49
+		assertEquals(0xffff, typeFactory.getIndexFor(Pooled.class));
48 50
 	}
49 51
 	
50 52
 	@Test
51 53
 	public void ensure_packed_components_dont_throw_aioob() throws Exception {
52 54
 		world.getMapper(Packed.class);
53
-		assertTrue(0xffff <= field("INDEX").getInt(null));
54
-		assertEquals(0xffff, ComponentType.getIndexFor(Packed.class));
55
+		ComponentTypeFactory typeFactory = world.getComponentManager().typeFactory;
56
+		assertTrue(0xffff <= field("componentTypeCount").getInt(typeFactory));
57
+		assertEquals(0xffff, typeFactory.getIndexFor(Packed.class));
55 58
 	}
56 59
 	
57 60
 	private static Field field(String f) throws NoSuchFieldException {
58
-		Field field = ComponentType.class.getDeclaredField(f);
61
+		Field field = ComponentTypeFactory.class.getDeclaredField(f);
59 62
 		field.setAccessible(true);
60 63
 		return field;
61 64
 	}
62 65
new file mode 100644
... ...
@@ -0,0 +1,104 @@
1
+package com.artemis;
2
+
3
+import static org.junit.Assert.assertEquals;
4
+import static org.junit.Assert.assertNotEquals;
5
+import static org.junit.Assert.fail;
6
+
7
+import java.lang.reflect.Field;
8
+
9
+import org.junit.Assert;
10
+import org.junit.Test;
11
+
12
+import com.artemis.component.ComponentX;
13
+import com.artemis.component.ComponentY;
14
+import com.artemis.systems.VoidEntitySystem;
15
+
16
+public class MultiWorldTest
17
+{
18
+	private World world;
19
+
20
+	@Test
21
+	public void uniqie_component_ids_per_world()
22
+	{
23
+		World innerWorld = new World();
24
+		innerWorld.initialize();
25
+		
26
+		world = new World();
27
+		world.setSystem(new InnerWorldProcessingSystem(innerWorld));
28
+		world.initialize();
29
+		
30
+		world.createEntity().createComponent(ComponentX.class);
31
+		innerWorld.createEntity().createComponent(ComponentY.class);
32
+		createEntity(innerWorld);
33
+		
34
+		world.process();
35
+		
36
+		int xIndexOuter = 
37
+				world.getComponentManager().typeFactory.getTypeFor(ComponentX.class).getIndex();
38
+		int yIndexInner = 
39
+				innerWorld.getComponentManager().typeFactory.getTypeFor(ComponentY.class).getIndex();
40
+		
41
+		assertEquals(xIndexOuter, yIndexInner);
42
+	}
43
+	
44
+	@Test
45
+	public void unique_system_bits_per_world() {
46
+		World innerWorld = new World();
47
+		VoidSystem innerVoid = innerWorld.setSystem(new VoidSystem());
48
+		innerWorld.initialize();
49
+		
50
+		world = new World();
51
+		world.setSystem(new InnerWorldProcessingSystem(innerWorld));
52
+		VoidSystem outerVoid = world.setSystem(new VoidSystem());
53
+		world.initialize();
54
+		
55
+		world.process();
56
+		
57
+		assertNotEquals(getSystemBit(innerVoid), getSystemBit(outerVoid));
58
+	}
59
+	
60
+	private static int getSystemBit(EntitySystem es) {
61
+		try {
62
+			Field f = EntitySystem.class.getDeclaredField("systemIndex");
63
+			f.setAccessible(true);
64
+			return f.getInt(es);
65
+		} catch (IllegalArgumentException e) {
66
+			fail(e.getMessage());
67
+		} catch (IllegalAccessException e) {
68
+			fail(e.getMessage());
69
+		} catch (NoSuchFieldException e) {
70
+			fail(e.getMessage());
71
+		} catch (SecurityException e) {
72
+			fail(e.getMessage());
73
+		}
74
+		return -1;
75
+	}
76
+
77
+	private static void createEntity(World w) {
78
+		Entity e = w.createEntity();
79
+		e.createComponent(ComponentX.class);
80
+		e.createComponent(ComponentY.class);
81
+	}
82
+	
83
+	public static class InnerWorldProcessingSystem extends VoidEntitySystem {
84
+
85
+		private final World inner;
86
+
87
+		public InnerWorldProcessingSystem(World inner) {
88
+			super();
89
+			this.inner = inner;
90
+		}
91
+
92
+		@Override
93
+		protected void processSystem() {
94
+			inner.delta = world.delta;
95
+			inner.process();
96
+		}
97
+		
98
+	}
99
+	
100
+	private static class VoidSystem extends VoidEntitySystem {
101
+		@Override
102
+		protected void processSystem() {}
103
+	}
104
+}