Entity-Component-System

Documentation

Some effort was spent on making the Entity-Component-System very time efficient. The components are cache-friendly organized and can be added, accessed or removed in constant time. To make this possible, a index is built which needs additional memory. Having the maximum number of entities n and the number of defined components m, the memory usage of the index can be calculated as:
sizeof(index) = n * m * sizeof(int)
Keep this in mind, when you plan to have a huge amount of entities and components.

Component

Use the component class template as base class for the components you define. Derive from Component by using the curiously recurring template pattern as follows:
class MyComponent : public Component<MyComponent>
{
// members of class MyComponent
};
This makes it possible to define your own component interface and at the same time having the functionality of a component. If possible do not add dependencies between different components and do not add member functions to process the component data. Systems are responsible for the processing of components.

Public Members

static ComponentType<T> getType();
Returns the type of your derived component as a templated ComponentType. Use this function to access the component in an entity.
Complexity: Constant.

ComponentType

The class template ComponentType is used to access a component in an entity. The component type consists of an id and a template parameter which makes it easy to access a component by its type (no typecasting is needed).

Public Members

const unsigned int typeId;
The unique id of the components having this type.

Entity

The class Entity represents an entity. It consists of an unique id to address its components and some member functions to directly add, remove or access components. Do not create an entity on your own, use the entity manager to do this.

Public Members

template <class T>
void setComponent(T component);
Assigns a component to the entity. If the entity already has this component, the existing component gets overwritten by the content of the given component.
Complexity: Constant.
template <class T>
bool hasComponent(const ComponentType<T> &type);
Returns true, if the entity contains the component given by the class template ComponentType, otherwise false.
Compexity: Constant.
template <class T>
T& getComponent(const ComponentType<T> &type);
Returns the component specified by the given component type. If the entity doesn't contain the component, an error will occur (like accessing an array at array[-1]. So if you are not sure, if an entity contains the component, first check the existence of the component with the member function hasComponent.
Complexity: Constant.
template <class T>
void removeComponent(const ComponentType<T> &type);
Removes the component specified by its component type from an entity.
Complexity: Constant.
void clear();
Removes all components assigned to the entity.
Complexity: Linear in the number of all components defined.
void destroy();
Removes all components from the entity and destroys it.
Complexity: Linear in the number of all components defined.
unsigned int getId() const;
Returns the unique id of the entity. The id can be used to access this entity through the entity manager.
Complexity: Constant.

EntityManager

The class EntityManager is responsible for creating, holding and destroying entities. Every entity is owned by the entity manager, so an entity that goes out of scope doesn't get destroyed. Take care to manually destroy entities you no longer need. The entity manager is implemented as a singleton. To access the entity manager use the singleton shortcut theEntityManager or EntityManager::getInstance() if you don't like shortcuts ;).

Public Members

static EntityManager& getInstance();
Returns the instance of the entity manager singleton. You can also use the shortcut theEntityManager to access the entity manager. The shortcut is defined as:
#define theEntityManager EntityManager::getInstance()
Complexity: Constant.
Entity createEntity();
Creates and returns a new entity. Use this function to create an entity.
Complexity: Constant.
void destroyEntity(Entity e);
void destroyEntity(unsigned int entityId);
Destroys an entity either by giving the entity itself as a parameter or by giving the id of the entity. Take care you dont access the components of an entity object which you destroyed by the id, but still is in scope.
Complexity: Linear in the number of all components defined.
void clearEntity(Entity e);
void clearEntity(unsigned int entityId);
Removes all components assigned to the entity given either by the entity itself or by the id of the entity.
Complexity: Linear in the number of all components defined.
Entity getEntity(unsigned int entityId);
Returns the entity object of the entity by its id.
Complexity: Constant.

System

Use the system class template as base class for the systems you define. You can define whatever interface you like. Use members to give the system additional information or to store and retrieve results from the calculations of your system. The system template class itself is derived from the class SystemBase. This allows you to store pointers to your systems in a single container. Derive from System by using the curiously recurring template pattern as follows:
class MySystem : public System<MySystem>
{
// members of class MySystem
  protected:
// overwrite this member funtion with your system specific code
void update(Entity e);
};
Overwrite the protected abstract member function update to specify the behaviour of this system. The function update is called for every entity containing the components the system depends on. To set the dependencies of a system call the protected member function setDependency in the constructor of your system as follows:
MySystem::MySystem()
{
setDependency(MyComponent::getType());
setDependency(MyOtherComponent::getType());
}

Public Members

void run();
Updates all entities containing the system-specific components by calling the function void update(Entity) on them.
Complexity: Linear in the number of entities containing the least amount of one of the required components.

Protected Members you'll need

template <class T>
void setDependency(ComponentType<T> type);
Sets the dependencies of this system. The function is protected and should be called in the constructor of your derived system. It is guaranteed that only entities are processed which have the needed components set. Don't forget to set dependencies for your system, otherwise the system would never update any entity.
Complexity: Constant.
virtual void update(Entity e) = 0;
Overwrite this function to give your system the functionality you need. The function update is called by the function run for every entity containing at least the components required by your system (see setDependency). The current entity is given to you as parameter which you can directly use to update the entity. It is guaranteed that every given entity has the required components, so you do not need to test against these using e.hasComponent(...).


You can find some sample code in the section Quick Tutorial.