galaxy 1.0.0
Real-Time C++23 Game Programming Framework. Built on data-driven design principles and agile software engineering.
Loading...
Searching...
No Matches
Registry.cpp
Go to the documentation of this file.
1
7
8#include <box2d/b2_fixture.h>
9#include <box2d/b2_polygon_shape.h>
10#include <glm/trigonometric.hpp>
11
12#include "galaxy/core/ServiceLocator.hpp"
14#include "galaxy/meta/EntityMeta.hpp"
16
17#include "Registry.hpp"
18
19namespace galaxy
20{
21 namespace core
22 {
24 {
25 // Handle on_* events.
26 m_entt.on_construct<components::RigidBody>().connect<&Registry::construct_rigidbody>(this);
27 m_entt.on_destroy<components::RigidBody>().connect<&Registry::destroy_rigidbody>(this);
28 m_entt.on_construct<components::Script>().connect<&Registry::construct_script>(this);
29 m_entt.on_destroy<components::Script>().connect<&Registry::destruct_script>(this);
30 m_entt.on_construct<flags::Disabled>().connect<&Registry::disable_entity>(this);
31 m_entt.on_destroy<flags::Disabled>().connect<&Registry::enable_entity>(this);
32 }
33
35 {
36 this->m_bodies_to_construct = std::move(r.m_bodies_to_construct);
37 this->m_entt = std::move(r.m_entt);
38 }
39
41 {
42 if (this != &r)
43 {
44 this->m_bodies_to_construct = std::move(r.m_bodies_to_construct);
45 this->m_entt = std::move(r.m_entt);
46 }
47
48 return *this;
49 }
50
54
55 entt::entity Registry::create()
56 {
57 const auto entity = m_entt.create();
58
59 m_entt.emplace<flags::Disabled>(entity);
60
61 auto& tag = m_entt.emplace<components::Tag>(entity);
62 tag.m_tag = "Untagged";
63
64 return entity;
65 }
66
67 entt::entity Registry::create_from_prefab(const std::string& name)
68 {
69 auto& prefabs = core::ServiceLocator<resource::Prefabs>::ref();
70 if (prefabs.has(name))
71 {
72 return prefabs.get(name)->to_entity(m_entt);
73 }
74 else
75 {
76 GALAXY_LOG(GALAXY_WARNING, "Tried to load missing prefab '{0}'.", name);
77 return entt::null;
78 }
79 }
80
81 bool Registry::is_valid(const entt::entity entity)
82 {
83 auto& em = core::ServiceLocator<meta::EntityMeta>::ref();
84
85 for (const auto& hash : em.get_validation_list())
86 {
87 if (!(em.get_validations().at(hash)(entity, m_entt)))
88 {
89 return false;
90 }
91 }
92
93 return true;
94 }
95
96 void Registry::update(b2World& b2World)
97 {
98 for (const auto& [rigidbody, transform] : m_bodies_to_construct)
99 {
100 b2BodyDef def {};
101 def.position.x = transform->m_tf.get_pos().x / GALAXY_WORLD_TO_BOX;
102 def.position.y = transform->m_tf.get_pos().y / GALAXY_WORLD_TO_BOX;
103 def.angle = glm::radians(transform->m_tf.get_rotation());
104 def.type = rigidbody->m_type;
105 def.fixedRotation = rigidbody->m_fixed_rotation;
106 def.bullet = rigidbody->m_bullet;
107
108 rigidbody->m_body = b2World.CreateBody(&def);
109
110 b2PolygonShape shape;
111 shape.SetAsBox(rigidbody->m_shape.x, rigidbody->m_shape.y);
112
113 b2FixtureDef fixture;
114 fixture.shape = &shape;
115 fixture.density = rigidbody->m_density;
116 fixture.friction = rigidbody->m_friction;
117 fixture.restitution = rigidbody->m_restitution;
118 fixture.restitutionThreshold = rigidbody->m_restitution_threshold;
119
120 rigidbody->m_body->CreateFixture(&fixture);
121 rigidbody->m_world = &b2World;
122 }
123
124 m_bodies_to_construct.clear();
125 }
126
128 {
129 m_bodies_to_construct.clear();
130 m_entt.clear();
131 }
132
133 void Registry::construct_rigidbody(entt::registry& registry, entt::entity entity)
134 {
135 auto transform = registry.try_get<components::Transform>(entity);
136 if (!transform)
137 {
138 transform = &registry.emplace<components::Transform>(entity);
139 }
140
141 m_bodies_to_construct.emplace_back(&registry.get<components::RigidBody>(entity), transform);
142 }
143
144 void Registry::destroy_rigidbody(entt::registry& registry, entt::entity entity)
145 {
146 auto& rigidbody = registry.get<components::RigidBody>(entity);
147
148 if (rigidbody.m_body != nullptr)
149 {
150 rigidbody.m_world->DestroyBody(rigidbody.m_body);
151
152 rigidbody.m_body = nullptr;
153 rigidbody.m_world = nullptr;
154 }
155 }
156
157 void Registry::construct_script(entt::registry& registry, entt::entity entity)
158 {
159 auto& script = registry.get<components::Script>(entity);
160 auto& state = core::ServiceLocator<sol::state>::ref();
161
162 auto result = state.load_file(script.file());
163 if (result.valid())
164 {
165 script.m_self = result.call();
166
167 if (script.m_self.valid())
168 {
169 script.m_update = script.m_self["update"];
170
171 if (!script.m_update.valid())
172 {
173 GALAXY_LOG(GALAXY_ERROR, "Update function not present in '{0}'.", script.file());
174 }
175
176 script.m_self["owner"] = std::ref(registry);
177 script.m_self["id"] = sol::readonly_property([entity] {
178 return entity;
179 });
180
181 sol::function init = script.m_self["construct"];
182 if (init.valid())
183 {
184 init(script.m_self);
185 }
186 }
187 else
188 {
189 GALAXY_LOG(GALAXY_ERROR, "Failed to validate script '{0}'. Make sure its in the correct format.", script.file());
190 }
191 }
192 else
193 {
194 GALAXY_LOG(GALAXY_ERROR, "Failed to load script '{0}' because '{1}'.", script.file(), magic_enum::enum_name(result.status()));
195 }
196 }
197
198 void Registry::destruct_script(entt::registry& registry, entt::entity entity)
199 {
200 auto& script = registry.get<components::Script>(entity);
201
202 if (script.m_self.valid())
203 {
204 sol::function destruct = script.m_self["destruct"];
205 if (destruct.valid())
206 {
207 destruct(script.m_self);
208 }
209
210 script.m_self.abandon();
211 }
212 }
213
214 void Registry::construct_nui(entt::registry& registry, entt::entity entity)
215 {
216 auto& ui = registry.get<components::GUI>(entity);
217 auto& state = entt::locator<sol::state>::value();
218 auto& nui = entt::locator<ui::NuklearUI>::value();
219 auto& fs = entt::locator<fs::VirtualFileSystem>::value();
220
221 const auto script = fs.read(ui.file());
222 if (!script.empty())
223 {
224 auto result = state.load(script);
225
226 if (result.valid())
227 {
228 ui.m_self = result.call();
229
230 if (ui.m_self.valid())
231 {
232 ui.m_self["ctx"] = nui.ctx();
233 ui.m_update = ui.m_self["do_ui"];
234
235 if (!ui.m_update.valid())
236 {
237 GALAXY_LOG(GALAXY_ERROR, "Update function not present in ui script '{0}'.", ui.file());
238 }
239 }
240 else
241 {
242 GALAXY_LOG(GALAXY_ERROR, "Failed to validate ui script '{0}'. Make sure its in the correct format.", ui.file());
243 }
244 }
245 else
246 {
247 GALAXY_LOG(GALAXY_ERROR, "Failed to load ui script '{0}' because '{1}'.", ui.file(), magic_enum::enum_name(result.status()));
248 }
249 }
250 else
251 {
252 GALAXY_LOG(GALAXY_ERROR, "Failed to read script '{0}'.", ui.file());
253 }
254 }
255
256 void Registry::destruct_nui(entt::registry& registry, entt::entity entity)
257 {
258 auto& ui = registry.get<components::GUI>(entity);
259 if (ui.m_self.valid())
260 {
261 ui.m_self.abandon();
262 }
263 }*/
264
265 void Registry::enable_entity(entt::registry& registry, entt::entity entity)
266 {
267 /*auto rb = registry.try_get<components::RigidBody>(entity);
268 if (rb)
269 {
270 rb->m_body->SetEnabled(true);
271 }*/
272 }
273
274 void Registry::disable_entity(entt::registry& registry, entt::entity entity)
275 {
276 auto rb = registry.try_get<components::RigidBody>(entity);
277 if (rb)
278 {
279 rb->m_body->SetEnabled(false);
280 }
281 }
282 } // namespace core
283} // namespace galaxy
#define GALAXY_LOG(level, msg,...)
Definition Log.hpp:28
#define GALAXY_ERROR
Definition Log.hpp:24
Script for running an active UI.
Definition GUI.hpp:23
void load(const std::string &file)
Load script and set context.
Definition GUI.cpp:56
Box2D physics body.
Definition RigidBody.hpp:34
High level abstraction of a lua script.
Definition Script.hpp:31
Tag an entity.
Definition Tag.hpp:21
Defines the 2D transformation of an entity.
Definition Transform.hpp:22
Wrapper around entt::registry to expand functionality.
Definition Registry.hpp:21
void construct_script(entt::registry &registry, entt::entity entity)
Function that integrates lua init with entt on construct event.
Definition Registry.cpp:157
void clear()
Clear any pending data.
Definition Registry.cpp:127
Registry & operator=(Registry &&)
Move assignment operator.
Definition Registry.cpp:40
void construct_nui(entt::registry &registry, entt::entity entity)
Function that integrates nuklear init with entt on construct event.
Definition Registry.cpp:214
void destruct_nui(entt::registry &registry, entt::entity entity)
Function that integrates nuklear destroy with entt on destruction event.
Definition Registry.cpp:256
void destruct_script(entt::registry &registry, entt::entity entity)
Function that integrates lua destroy with entt on destruction event.
Definition Registry.cpp:198
void disable_entity(entt::registry &registry, entt::entity entity)
Function that runs when an entity is disabled.
Definition Registry.cpp:274
void destroy_rigidbody(entt::registry &registry, entt::entity entity)
Function that integrates a box2d destruction with entt.
Definition Registry.cpp:144
entt::entity create()
Create an entity with some default components.
Definition Registry.cpp:55
void construct_rigidbody(entt::registry &registry, entt::entity entity)
Function that integrates a box2d construction with entt.
Definition Registry.cpp:133
~Registry()
Destructor.
Definition Registry.cpp:51
void update(b2World &b2World)
Updates pending component data.
Definition Registry.cpp:96
entt::entity create_from_prefab(const std::string &name)
Create an entity from a prefab.
Definition Registry.cpp:67
Registry()
Constructor.
Definition Registry.cpp:23
void enable_entity(entt::registry &registry, entt::entity entity)
Function that runs when an entity is enabled.
Definition Registry.cpp:265
B2BodyConstruction m_bodies_to_construct
List of rigid bodies that need to be constructed.
Definition Registry.hpp:172
entt::registry m_entt
Scene entities.
Definition Registry.hpp:166
bool is_valid(const entt::entity entity)
Validate an entity to make sure all components have met their requirements as defined by register_dep...
Definition Registry.cpp:81
Used to stop an entity from being updated/rendered.
Definition Disabled.hpp:21
Animated.cpp galaxy.
Definition Animated.cpp:16