Search code examples
c++c++11templatescomponentsentity-component-system

c++ entity component system and accessing components using a template


I've been working on creating my own entity component system, and I'm set on being able to get a component by doing the following:

const auto& component = entity->GetComponent<ComponentType>();

The above function would then look something like this:

template <typename TyComponent>
TyComponent* Entity<T>::GetComponent() const
{
  return &(GetComponent(TyComponent::Id());
}

Which then returns a component based on the associated id if found, else nullptr.

  1. Is what I'm doing viable?
  2. Is there a way to ensure only types derived from Component can be used as a parameter for GetComponent?

Solution

  • This design is OK.

    You'll already get a compile time error if anyone tries GetComponent<Foo>, but Foo doesn't have a static Id() function. So that gives you a bit of safety.

    However, it still needs one change to compile. Here's how I'd do it:

    Component * GetComponent(int id) { ... }
    
    template <typename TyComponent>
    TyComponent* Entity<T>::GetComponent() const {
      return dynamic_cast<TyComponent*>(GetComponent(TyComponent::Id()));
    }
    

    This will now generate a compile error when TyComponent is not derived from Component. (Component will need at least one virtual function for this to work though.)