LkEngine 0.1.2
 
Loading...
Searching...
No Matches
Entity.h
1#pragma once
2
3#include <vector>
4
6#include "LkEngine/Core/LObject/ObjectPtr.h"
7
8#include "LkEngine/Scene/Scene.h"
9#include "LkEngine/Scene/Components.h"
10
11#include <glm/glm.hpp>
12
13#include <entt/entt.hpp>
14
15namespace LkEngine {
16
17 class LEntity : public LObject
18 {
19 public:
20 LEntity();
21 LEntity(entt::entity InHandle, TObjectPtr<LScene> InScene);
22 LEntity(entt::entity InHandle, LScene* InScene);
23 ~LEntity() = default;
24
25 LEntity(const LEntity& Other) = default;
26
27 void Tick(float ts) {}
28
29 template<typename T, typename ...TArgs>
30 T& AddComponent(TArgs&&... Args)
31 {
32 T& Component = Scene->Registry.emplace<T>(Handle, std::forward<TArgs>(Args)...);
33 Scene->OnComponentAdded<T>(*this, Component);
34
35 return Component;
36 }
37
38 template<typename... T>
39 bool HasComponent()
40 {
41 return Scene->Registry.all_of<T...>(Handle);
42 }
43
44 template<typename... T>
45 bool HasComponent() const
46 {
47 return Scene->Registry.all_of<T...>(Handle);
48 }
49
50 template<typename... T>
51 bool HasAny()
52 {
53 return Scene->Registry.any_of<T...>(Handle);
54 }
55
56 template<typename... T>
57 bool HasAny() const
58 {
59 return Scene->Registry.any_of<T...>(Handle);
60 }
61
62 template<typename T>
63 T& GetComponent()
64 {
65 LK_CORE_ASSERT(HasComponent<T>(), "Entity '{}' does not have that component", Handle);
66 return Scene->Registry.get<T>(Handle);
67 }
68
69 template<typename T>
70 const T& GetComponent() const
71 {
72 LK_CORE_ASSERT(HasComponent<T>(), "Entity '{}' does not have that component", Handle);
73 return Scene->Registry.get<T>(Handle);
74 }
75
76 template<typename T>
77 void RemoveComponent()
78 {
79 LK_CORE_ASSERT(HasComponent<T>(), "Entity does not have that component");
80 Scene->Registry.remove<T>(Handle);
81 }
82
83 template<typename T>
84 void RemoveComponentIfExists()
85 {
86 if (Scene->Registry.all_of<T>(Handle))
87 {
88 Scene->Registry.remove<T>(Handle);
89 }
90 }
91
92 template<typename T, typename... ARGS>
93 void AddExistingComponent(T, ARGS&&... args)
94 {
95 Scene->Registry.emplace<T>(Handle, std::forward<ARGS>(args)...);
96 }
97
98 FORCEINLINE const std::string& Name() const { return GetComponent<LTagComponent>().Tag; }
99 FORCEINLINE LTagComponent& Tag() { return GetComponent<LTagComponent>(); }
100 FORCEINLINE LTransformComponent& Transform() { return GetComponent<LTransformComponent>(); }
101 FORCEINLINE LMeshComponent& GetMesh() { return GetComponent<LMeshComponent>(); }
102
103 operator uint32_t() const { return static_cast<uint32_t>(Handle); }
104 operator entt::entity() const { return Handle; }
105 operator LUUID() const { return GetUUID(); }
106 operator LTransformComponent&() { return GetComponent<LTransformComponent>(); }
107 operator bool() const;
108
109 bool operator==(const LEntity& Other) const
110 {
111 return ((Handle == Other.Handle) && (Scene == Other.Scene));
112 }
113
114 bool operator!=(const LEntity& Other) const { return !(*this == Other); }
115
116 LEntity GetParent();
117
118 FORCEINLINE LUUID GetUUID() const
119 {
120 return GetComponent<LIDComponent>().ID;
121 }
122
123 FORCEINLINE void SetParent(LEntity InParent)
124 {
125 LEntity CurrentParent = GetParent();
126 if (CurrentParent == InParent)
127 {
128 return;
129 }
130
131 /* If changing parent, remove child from existing attached parent. */
132 if (CurrentParent)
133 {
134 CurrentParent.RemoveChild(*this);
135 }
136
137 /* Setting to null is okay. */
138 SetParentUUID(InParent.GetUUID());
139
140 if (InParent)
141 {
142 std::vector<LUUID>& Children = InParent.GetChildren();
143 const LUUID uuid = GetUUID();
144
145 if (std::find(Children.begin(), Children.end(), uuid) == Children.end())
146 {
147 Children.emplace_back(GetUUID());
148 }
149 }
150 }
151
152 LUUID GetSceneUUID() const;
153
154 FORCEINLINE void SetParentUUID(LUUID parent)
155 {
156 GetComponent<LRelationshipComponent>().ParentHandle = parent;
157 }
158
159 FORCEINLINE LUUID GetParentUUID() const
160 {
161 return GetComponent<LRelationshipComponent>().ParentHandle;
162 }
163
164 FORCEINLINE std::vector<LUUID>& GetChildren()
165 {
166 return GetComponent<LRelationshipComponent>().Children;
167 }
168
169 const std::vector<LUUID>& GetChildren() const { return GetComponent<LRelationshipComponent>().Children; }
170
171 bool RemoveChild(LEntity Child)
172 {
173 const LUUID ChildID = Child.GetUUID();
174 std::vector<LUUID>& Children = GetChildren();
175
176 /* FIXME: Use compressed if statement */
177 auto Iter = std::find(Children.begin(), Children.end(), ChildID);
178 if (Iter != Children.end())
179 {
180 Children.erase(Iter);
181 return true;
182 }
183
184 return false;
185 }
186
187 bool IsAncestorOf(LEntity InEntity);
188
189 FORCEINLINE bool IsDescendantOf(LEntity Entity) const
190 {
191 return Entity.IsAncestorOf(*this);
192 }
193
194 private:
195 entt::entity Handle{ entt::null };
196
197 TObjectPtr<LScene> Scene{};
198
199 friend class LEditorLayer;
200 friend class LScene;
201 friend class LSceneManagerPanel;
202
204 };
205
206}
207
208/* Logging formatters. */
209template<>
210struct LK_FMT_LIB::formatter<LkEngine::LEntity> : LK_FMT_LIB::formatter<std::string>
211{
212 template <typename FormatContext>
213 auto format(const LkEngine::LEntity& Entity, FormatContext& Context) const
214 {
215 return LK_FMT_LIB::format_to(Context.out(), "{}", static_cast<entt::id_type>(Entity));
216 }
217};
218
219template<>
220struct LK_FMT_LIB::formatter<entt::entity> : LK_FMT_LIB::formatter<std::string>
221{
222 template <typename FormatContext>
223 auto format(const entt::entity& Entity, FormatContext& Context) const
224 {
225 return LK_FMT_LIB::format_to(Context.out(), "{}", static_cast<entt::id_type>(Entity));
226 }
227};
228
LObject implementation.
Definition Entity.h:18
Definition Object.h:46
Definition Scene.h:47
Definition ObjectPtr.h:102
#define LCLASS(Class)
Definition CoreMacros.h:226
Definition Asset.h:11
Definition Components.h:264
Definition Components.h:40
Definition Components.h:69
Definition UUID.h:13