I'm implementing a game engine in C++ which uses an ECS (Entity-Component-System).
Each GameObject
can have multiple Component
s (stored in GameObject
's std::vector<Component*> _components
).
I have a method that allows me to get a Component
of a GameObject
by specifying the type of Component
I want:
// In GameObject.h
template <typename T> T* GetComponent() {
for (Component* c : _components) {
if (typeid(*c) == typeid(T)) return (T*)c;
}
return nullptr;
}
// In main.cpp
RandomComponent* RC = gameObject.GetComponent<RandomComponent>();
Now let's say I have those Component
s defined:
class TerrainComponent { /* ... */ }
class PerlinTerrainComponent : public TerrainComponent { /* ... */ }
class FlatTerrainComponent : public TerrainComponent { /* ... */ }
// And possibly many more
And have world GameObject
s, which all have a TerrainComponent
's derived class attached to it.
My problem is that I would need a way to get the TerrainComponent
of a world, like so:
TerrainComponent* TC = world.GetComponent<TerrainComponent>();
And get any type of TerrainComponent
attached to the world (which, in reality, will be a TerrainComponent
derived class).
Is it possible, in C++, to implement a method that would allow me to do that (get all derived classes of a class), without having to manually update a list of TerrainComponent
derived classes?
Assuming these classes are all polymorphic/dynamic (which they need to be to use typeid like this), you can just use dynamic_cast instead:
template <typename T> T* GetComponent() {
for (Component* c : _components) {
if (T *tc = dynamic_cast<T *>(c)) return tc;
}
return nullptr;
}