Issues with Component Retrieval in C++ ECS Implementation

28 views Asked by At

I'm working on an Entity-Component-System (ECS) for a game engine in C++, but I've run into a couple of issues related to component management within entities. My Entity class stores components in a std::unordered_map using std::type_index as keys for type-safe component retrieval. Here's a simplified version of my Entity class:

#include <unordered_map>
#include <typeindex>
#include <memory>
#include <type_traits>
#include <stdexcept>

class Component {};

template<typename T>
class ComponentT : public Component {
    // Component implementation
};

class Entity {
  std::unordered_map<std::type_index, std::shared_ptr<Component>> m_Components;

public:
  template<typename T, typename... Args>
  void AddComponent(Args&&... args) {
    static_assert(std::is_base_of<Component, T>::value, "T must be a Component.");
    m_Components[std::type_index(typeid(T))] = std::make_shared<T>(std::forward<Args>(args)...);
  }

  template<typename T>
  void RemoveComponent() {
    static_assert(std::is_base_of<Component, T>::value, "T must be a Component.");
    m_Components.erase(std::type_index(typeid(T)));
  }

  template<typename T>
  T& GetComponent() const {
    static_assert(std::is_base_of<Component, T>::value, "T must be a Component.");
    auto it = m_Components.find(std::type_index(typeid(T)));
    if (it != m_Components.end())
      return *std::static_pointer_cast<T>(it->second);
    throw std::runtime_error("Component not found.");
  }

  template<typename T>
  bool HasComponent() const {
    return m_Components.find(std::type_index(typeid(T))) != m_Components.end();
  }
};

I'm encountering two main issues:

  1. Component Not Found Error: Even after successfully adding a Mesh component to an entity, attempts to retrieve it in the rendering system throw a "Component not found" error. Debugging shows that m_Components is empty at the time of retrieval, suggesting the component was either not added properly or was somehow removed.

  2. Performance Concerns: I'm worried about the potential overhead of using RTTI (typeid and std::type_index) for component retrieval, especially in performance-critical parts of the engine like the rendering loop.

Questions:

How can I ensure that components added to an entity are reliably retrievable later in other systems of the ECS? Are there more efficient, possibly RTTI-free, ways to implement type-safe component retrieval in a C++ ECS?

Any advice or alternative approaches to improve the reliability and performance of my ECS implementation would be greatly appreciated. Thank you!

0

There are 0 answers