Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I am working on an Entity-System-Component engine for games, which basically means an entity is an object that points to components attached to it, and systems retrieve components to modify their data.

So I have a class, which is the main data holder, containing the entities, components and system, and methods to dispatch things. The current implementation is straightforward (each entity/component has an idea and there are hashtables containing their references). But it means lots of for loop to retrieve data, and I am wondering if there aren't any more clever way to manage all that.

Here are the most important parts of the code. First, the scene and the data it holds

var Scene = function (description) {
    this.description = description; // Just debug texts
    this.name = description.name; // Reference for the list of scenes
    this.entitiesCounter = 0; // This is used to assign ids to entities
    this.entities = {}; // Holds every entity, assigned by their id
    this.componentData = {}; // For each type of component, there is a nested json hashtable working like the entities object
    this.componentCounters = {}; // Counters for components IDs (one per component type)
    this.entityComponents = {}; // A hashtable containing the list of components id associated to an entity ID, used for retrieving an entity's data
    this.functionsUsed = {}; // Keeps a list of the functions that systems have, and which systems use them. For example we can have "update" which would have a reference to every system's update function if they are implemented
};

Scene.prototype.init = function (callback) {
    for (var i in componentTypes) {
        this.componentData[i] = {}; // Initializes the component data holders
        this.componentCounters[i] = 0; // Initializes the counters
    }
            // Fills the system functions array
    for (var s in systems) {
        for (var f in systems[s]) {
            if (typeof systems[s][f] === "function") {
                if (typeof this.functionsUsed[f] === "object") {
                    this.functionsUsed[f].push(s);
                } else {
                    this.functionsUsed[f] = [s];
                }
            }
        }
    }
    callback();
};

See the entire file on Github So then, all this is used like this for example:

  1. The update function is called
  2. The scene searches in its functionsUsed for the list of update systems functions and calls everyone of them
  3. In the system code, I want to modify a certain component type's data for this entity (say renderer)
  4. My system will take the current entity id, and use it to search in the entityComponents table for the renderer component id if it exists, and use its ID
  5. Then if it exists, it will go in the componentData and fetch the component using the component's type renderer and its id
  6. Then the system can modify data

In some scenarios, this implies lots of loop for retrieving the data, for example here. This function takes a list of components type and retrieve any entity that has all of them:

ES.prototype.getEntitiesWithComponents = function (components) {
                    // Empty associative array for holding every correct entity
        var res = {};
                    // Loop through all the entity/components association
        for (var i in this.entityComponents) {
            var valid = true;
                            // For each one, loop through the list of accepted components, to search for a match
            for (var c = 0; c < components.length; c++) {
             // If the entity doesn't have one of the component, let it go
                                 if (!this.entityComponents[i].hasOwnProperty(components[c])) {
                    valid = false;
                    break;
                }
            }
                           // If all the components were found, add it to the answer holder
            if (valid) {
                res[i] = {};
                res[i].entity = this.entities[i];
                for (var comp = 0; comp < components.length; comp++) {
                    var compType = components[comp];
                    res[i][compType] = this.getComponentForEntity(compType, this.entities[i]._id);
                }
            }
        }
        return res;
    };

Entire file with other functions like this one on Github

As you can see, lots of for-loops are needed for most of the data manipulation. And especially since they are not standard array but objects, looping through them is slower (I think, not sure?)

So I'm wondering, is the way I implemented all that efficient, and could it be better?

share|improve this question
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.