entity.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #pragma once
  2. #include <cstdint>
  3. #include <functional>
  4. #include <memory>
  5. #include <type_traits>
  6. #include <typeindex>
  7. #include <unordered_map>
  8. #include <vector>
  9. namespace Engine::Core {
  10. using EntityID = std::uint32_t;
  11. constexpr EntityID NULL_ENTITY = 0;
  12. class Component {
  13. public:
  14. virtual ~Component() = default;
  15. };
  16. using ComponentChangeCallback =
  17. std::function<void(EntityID, std::type_index, bool)>;
  18. class Entity {
  19. public:
  20. Entity(EntityID id);
  21. auto get_id() const -> EntityID;
  22. void set_component_change_callback(ComponentChangeCallback callback);
  23. template <typename T, typename... Args>
  24. auto add_component(Args &&...args) -> T * {
  25. static_assert(std::is_base_of_v<Component, T>,
  26. "T must inherit from Component");
  27. auto component = std::make_unique<T>(std::forward<Args>(args)...);
  28. auto ptr = component.get();
  29. std::type_index const type_idx = std::type_index(typeid(T));
  30. m_components[type_idx] = std::move(component);
  31. if (m_component_change_callback) {
  32. m_component_change_callback(m_id, type_idx, true);
  33. }
  34. return ptr;
  35. }
  36. template <typename T> auto get_component() -> T * {
  37. auto it = m_components.find(std::type_index(typeid(T)));
  38. if (it != m_components.end()) {
  39. return static_cast<T *>(it->second.get());
  40. }
  41. return nullptr;
  42. }
  43. template <typename T> auto get_component() const -> const T * {
  44. auto it = m_components.find(std::type_index(typeid(T)));
  45. if (it != m_components.end()) {
  46. return static_cast<const T *>(it->second.get());
  47. }
  48. return nullptr;
  49. }
  50. template <typename T> void remove_component() {
  51. std::type_index const type_idx = std::type_index(typeid(T));
  52. auto it = m_components.find(type_idx);
  53. if (it != m_components.end()) {
  54. m_components.erase(it);
  55. if (m_component_change_callback) {
  56. m_component_change_callback(m_id, type_idx, false);
  57. }
  58. }
  59. }
  60. template <typename T> auto has_component() const -> bool {
  61. return m_components.find(std::type_index(typeid(T))) != m_components.end();
  62. }
  63. private:
  64. EntityID m_id;
  65. std::unordered_map<std::type_index, std::unique_ptr<Component>> m_components;
  66. ComponentChangeCallback m_component_change_callback;
  67. };
  68. } // namespace Engine::Core