Chira Engine
A customizable MIT-licensed game engine.
Entity.h
1 #pragma once
2 
3 #include <glm/glm.hpp>
4 #include <entt/entt.hpp>
5 
6 #include <core/Assertions.h>
7 #include "component/NameComponent.h"
8 #include "component/TagComponents.h"
9 #include "component/TransformComponent.h"
10 #include "component/UUIDComponent.h"
11 #include "component/LayerComponents.h"
12 #include "Scene.h"
13 
14 namespace chira {
15 
17 class Entity {
18  friend Scene;
19 
20 protected:
21  explicit Entity(Scene* scene_)
22  : scene(scene_)
23  , handle(scene_->getRegistry().create()) {
24  this->addComponent<TransformComponent>();
25  this->addTagComponent<LayerComponent<0>>();
26  }
27 
28 public:
29  Entity(const Entity&) = default;
30  Entity& operator=(const Entity&) = default;
31  Entity(Entity&&) = default;
32  Entity& operator=(Entity&&) = default;
33 
34  template<typename T, typename... Args>
35  T& addComponent(Args&& ...args) {
36  runtime_assert(!this->hasComponent<T>(), "Entity already has this component!");
37  auto& component = this->scene->getRegistry().emplace<T>(this->handle, std::forward<Args>(args)...);
38  if constexpr (CComponentHasTransform<T>) {
39  component.transform = &this->getComponent<TransformComponent>();
40  }
41  return component;
42  }
43 
44  template<typename T>
45  void addTagComponent() {
46  runtime_assert(!this->hasComponent<T>(), "Entity already has this component!");
47  this->scene->getRegistry().emplace<T>(this->handle);
48  }
49 
50  template<typename T>
51  [[nodiscard]] T& getComponent() {
52  runtime_assert(this->hasComponent<T>(), "Entity doesn't have this component!");
53  return this->scene->getRegistry().get<T>(this->handle);
54  }
55 
56  template<typename T>
57  [[nodiscard]] T& getComponent() const {
58  runtime_assert(this->hasComponent<T>(), "Entity doesn't have this component!");
59  return this->scene->getRegistry().get<T>(this->handle);
60  }
61 
62  template<typename T>
63  [[nodiscard]] T* tryGetComponent() const {
64  return this->scene->getRegistry().try_get<T>(this->handle);
65  }
66 
67  template<typename T>
68  [[nodiscard]] bool hasComponent() const {
69  return this->scene->getRegistry().all_of<T>(this->handle);
70  }
71 
72  template<typename T>
73  void tryRemoveComponent() {
74  this->scene->getRegistry().remove<T>(this->handle);
75  }
76 
77  template<typename T>
78  void removeComponent() {
79  runtime_assert(this->hasComponent<T>(), "Entity doesn't have this component!");
80  this->scene->getRegistry().erase<T>(this->handle);
81  }
82 
83  [[nodiscard]] bool getVisible() const {
84  return !this->hasComponent<NoRenderTagComponent>();
85  }
86 
87  void setVisible(bool visible) {
88  if (visible) {
89  this->tryRemoveComponent<NoRenderTagComponent>();
90  } else if (!this->hasComponent<NoRenderTagComponent>()) {
91  this->addTagComponent<NoRenderTagComponent>();
92  }
93  }
94 
95  [[nodiscard]] std::string getName() const {
96  if (auto nameComponent = this->tryGetComponent<NameComponent>()) {
97  return nameComponent->name;
98  }
99  return uuids::to_string(this->getComponent<UUIDComponent>().uuid);
100  }
101 
102  [[nodiscard]] TransformComponent& getTransform() {
103  return this->scene->getRegistry().get<TransformComponent>(this->handle);
104  }
105 
106  [[nodiscard]] const TransformComponent& getTransform() const {
107  return this->scene->getRegistry().get<TransformComponent>(this->handle);
108  }
109 
110  uuids::uuid getUUID() {
111  return this->getComponent<UUIDComponent>().uuid;
112  }
113 
114  uuids::uuid getSceneUUID() {
115  return this->scene->getUUID();
116  }
117 
118  [[nodiscard]] entt::entity getRawHandle() const {
119  return this->handle;
120  }
121 
122  explicit operator bool() const {
123  return this->scene->getRegistry().valid(this->handle);
124  }
125 
126  bool operator!() const {
127  return !static_cast<bool>(*this);
128  }
129 
130  bool operator==(const Entity& other) const {
131  return this->handle == other.handle && this->scene == other.scene;
132  }
133 
134  bool operator!=(const Entity& other) const {
135  return !(*this == other);
136  }
137 
138 protected:
139  Scene* scene = nullptr;
140  entt::entity handle = entt::null;
141 };
142 
143 } // namespace chira
The base entity class.
Definition: Entity.h:17