Jump to content

April 2017 »

232425 26 272829

Recent Comments

- - - - -

ComponentManager and its Impact on Modern Society

dustArtemis artemis ecs entity component system java
4: Adsense

ComponentManager and its Impact on Modern Society Hi! In this entry I'm going to describe the ComponentManager class and the changes I made to it in dustArtemis, including a few bug fixes Posted Image


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<Bag<Component>> 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<Component> 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<Component> 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 Posted Image
  • 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 );
And That's All You Get!

Yup, that's because the editor sucks donkey balls and decided to erase 80% of the entry when I saved it as a draft, what you saw is what the editor decided to save, the rest is gone. Ironically, when I saved this last part as a draft it worked fine. See you next time I'm in the mood of wasting 2 hours of my life again...

EDIT: Great, it also ignores spacing after the code box so the "And thats all you get!" title is too near the box above it.

Note: GameDev.net moderates comments.