[font=verdana]dustArtemis[/font]
dustArtemis is a fork of Artemis Entity System, which is a BSD-licenced small Java framework for setting up Entities, Components and Systems.
In the beginning...
Well, we're going to do this method by method. I'll show you the original Artemis ComponentManager method and then I show you dustArtemis one.
Firstmost, the general structure of the class remains the same, it only has two fields:
Bag> componentsByType, which is a Bag of component Bags. Entities have an ID, and you can retrieve an entitity's component by doing componentsByType.get(componentIndex).get(entity.id). That is, component bags are indexed by the component's indices, and in those bags, components are set via the owner Entity ID.
Does this sounds like a huge memory waste to you? It is!
Say that you have one entity in your game that represents the camera, so it has a single instance of a Camera component, Camera components have an index of 5. You only have one camera in your game, and for some reason, the ID of the camera entity is 8002.
This happens: There exists a Bag in componentByType Bag, at index 5 (Camera's component index), and inside of it, there are all the Camera components in the world. Now, since you have only one Camera component and that one is attached to an Entity with the ID 8002, you'll have a Bag with enough space to hold at least 8003 components, so the ComponentManager can set the Camera component to the 8002 index.
I haven't solved this but I'm pretty sure I could work something out by adding HPPC (High Performance Primitive Collections), and using an int -> Object hashmap as a pseudo sparse array. It won't be as fast as direct array indexing but this is quite wasteful, so eff it.
The good thing is that Entity IDs are recycled, so you can be quite sure you'll only have arrays as big as you have entities alive in your World instance.
To the methods!
Disclaimer: I'll copy the examples in K&R for space reasons, actual code in the repository is in beautiful allman style
- initIfAbsent( cmpIndex )
final int prevCap = componentsByType.capacity();// If type bag can't hold this component type.if ( cmpIndex >= prevCap ){componentsByType.ensureCapacity( cmpIndex );// Init all the missing bags.for ( int i = componentsByType.capacity(); i-- != prevCap; ){componentsByType.setUnsafe( i, new Bag<>( Component.class, 4 ) );}}return componentsByType.getUnsafe( cmpIndex );