Hub Entity Component System
View On Github (currently private)
After much deliberation, I decided to create my own ECS that I could use for other projects. This project in particular is a Sparse Set implementation, written in C++17.
Not only was this a chance to keep myself learning, but was also a deviation from a lot of my past C++ experience, which was mainly just within Unreal Engine.
What?
ECS, or entity-component-system, is a pattern of code architecture, in the same vein as OOP, where instead of having potentially complex inheritance trees, you have entities (some ID) that have attached components (usually POD) and systems that work with them. This project is mainly for my own use, which I made as a learning project for myself, although feel free to use this how you see fit.
This implementation uses a Sparse Set structure, where a dense and sparse set are used for very fast (usually O(1) and O(n) iteration) operations. For this, a sparse set of indexes point to a dense set of Entity IDs and Components. These sets are stored in Pools which are reserved at compile time, and can be accessed via a Registry. On top of all of this is the World, which acts as a single point of entry into the registry, and allows for multiple different ways for iterating on Pools.
Currently, Systems are not handled by the World, but do take a shared_ptr during initialisation so they are able to access entities and components.
Basic Example
struct Position {
Vector3 position;
};
class MovementSystem : ISystem {
void OnCreate() override {
_entities = _world->EntitiesWith<Position>();
}
//...
void Update(float dt) override {
// use range-for
for(Entity ent : _entities) {
auto& pos = _world->GetComponent<Position>(ent);
// update position
}
// use callback
_world->Each<Position>([&](Entity e, Position& pos) {
// update position
});
}
};
int main() {
_world = std::make_shared();
const auto entity = _world->CreateEntity();
_world->AddComponent<Position>(entity, Position{10f,10f,0f});
MovementSystem.OnCreate(_world);
// In some Tick function
MovementSystem.Update(tick);
}