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
EntityFactory.hpp
Go to the documentation of this file.
1
7
8#ifndef GALAXY_META_ENTITYFACTORY_HPP_
9#define GALAXY_META_ENTITYFACTORY_HPP_
10
11#include <ankerl/unordered_dense.h>
12#include <entt/entt.hpp>
13#include <nlohmann/json.hpp>
14
18
19namespace galaxy
20{
21 namespace meta
22 {
26 class EntityFactory final
27 {
31 struct SerializationData final
32 {
36 std::string name;
37
41 nlohmann::json json;
42 };
43
44 using Validations = ankerl::unordered_dense::map<entt::id_type, std::move_only_function<bool(const entt::entity, entt::registry&)>>;
45 using ComponentJSONFactory = ankerl::unordered_dense::map<std::string, std::move_only_function<void(const entt::entity, entt::registry&, const nlohmann::json&)>>;
46 using AnyJSONFactory = ankerl::unordered_dense::map<std::string, std::move_only_function<entt::any(const nlohmann::json&)>>;
47 using SerializeFactory = ankerl::unordered_dense::map<std::string, std::move_only_function<EntityFactory::SerializationData(void*)>>;
48
49 public:
56 template<valid_component ToValidate, valid_component... Dependencies>
58
66 template<valid_component Component>
67 void register_component(const std::string& name);
68
77 void json_factory(const std::string& type, const entt::entity entity, entt::registry& registry, const nlohmann::json& json);
78
87 [[nodiscard]]
88 entt::any any_from_json(const std::string& type, const nlohmann::json& json);
89
98 [[nodiscard]]
99 nlohmann::json serialize_entity(const entt::entity entity, entt::registry& registry);
100
111 [[maybe_unused]]
112 entt::entity deserialize_entity(const nlohmann::json& json, entt::registry& registry);
113
121 [[nodiscard]]
122 const std::string& get_type(const entt::id_type id);
123
131 [[nodiscard]]
132 entt::id_type get_typeid(const std::string& name);
133
139 [[nodiscard]]
141
147 [[nodiscard]]
148 const std::vector<entt::id_type>& get_validation_list() const;
149
150 private:
154 ankerl::unordered_dense::map<entt::id_type, std::string> m_id_to_name;
155
159 ankerl::unordered_dense::map<std::string, entt::id_type> m_name_to_id;
160
165
170
175
180
184 std::vector<entt::id_type> m_validations_to_run;
185 };
186
187 template<valid_component ToValidate, valid_component... Dependencies>
189 {
190 const auto hash = entt::type_id<ToValidate>().hash();
191 if (!m_validations.contains(hash))
192 {
193 m_validations[hash] = [this](const entt::entity entity, entt::registry& registry) -> bool {
194 const auto* component = registry.try_get<ToValidate>(entity);
195 if (component)
196 {
197 return registry.all_of<Dependencies...>(entity);
198 }
199 else
200 {
201 // If we dont have component needing to be validated, then entity is valid.
202 return true;
203 }
204 };
205
206 m_validations_to_run.push_back(hash);
207 }
208 else
209 {
210 GALAXY_LOG(GALAXY_WARNING, "Attempted to register duplicate validation of a component dependency.");
211 }
212 }
213
214 template<valid_component Component>
215 inline void EntityFactory::register_component(const std::string& name)
216 {
217 if (!m_json_factory.contains(name))
218 {
219 const auto hash = entt::type_id<Component>().hash();
220 m_id_to_name.emplace(hash, name);
221 m_name_to_id.emplace(name, hash);
222
223 if constexpr (std::constructible_from<Component, const nlohmann::json&>)
224 {
225 m_json_factory.emplace(name, [](const entt::entity entity, entt::registry& registry, const nlohmann::json& json) {
226 registry.emplace<Component>(entity, json);
227 });
228
229 m_json_any_factory.emplace(name, [](const nlohmann::json& json) -> entt::any {
230 return entt::make_any<Component>(json);
231 });
232 }
233
234 if constexpr (std::derived_from<Component, fs::Serializable>)
235 {
236 m_serialize_factory.emplace(name, [name](void* component) -> SerializationData {
237 return SerializationData {.name = name, .json = static_cast<Component*>(component)->serialize()};
238 });
239 }
240 }
241 else
242 {
243 GALAXY_LOG(GALAXY_WARNING, "Attempted to register duplicate component of type '{0}'.", name);
244 }
245 }
246 } // namespace meta
247} // namespace galaxy
248
249#endif
#define GALAXY_WARNING
Definition Log.hpp:24
#define GALAXY_LOG(level, msg,...)
Definition Log.hpp:29
Handles entity meta (de)serialization.
ankerl::unordered_dense::map< std::string, std::move_only_function< entt::any(const nlohmann::json &)> > AnyJSONFactory
entt::id_type get_typeid(const std::string &name)
Get an entity type id from a string.
std::vector< entt::id_type > m_validations_to_run
Validations to run upon request.
const std::string & get_type(const entt::id_type id)
Get a string representation of an entity type id.
void register_dependencies()
Defines a dependency validation for components.
ankerl::unordered_dense::map< std::string, std::move_only_function< void(const entt::entity, entt::registry &, const nlohmann::json &)> > ComponentJSONFactory
entt::entity deserialize_entity(const nlohmann::json &json, entt::registry &registry)
Create an entity from a JSON object.
SerializeFactory m_serialize_factory
Serializes an entity from a void* pointer.
entt::any any_from_json(const std::string &type, const nlohmann::json &json)
Construct an entt::any from a json object.
ComponentJSONFactory m_json_factory
Used to allow for component creation from json.
void json_factory(const std::string &type, const entt::entity entity, entt::registry &registry, const nlohmann::json &json)
Construct component from json and assign to provided entity and registry.
ankerl::unordered_dense::map< std::string, std::move_only_function< EntityFactory::SerializationData(void *)> > SerializeFactory
ankerl::unordered_dense::map< std::string, entt::id_type > m_name_to_id
Maps a string name to an entt id.
Validations & get_validations()
Get a list of configurations.
const std::vector< entt::id_type > & get_validation_list() const
Get a list of validations to run.
ankerl::unordered_dense::map< entt::id_type, std::move_only_function< bool(const entt::entity, entt::registry &)> > Validations
void register_component(const std::string &name)
Registers a component definition.
ankerl::unordered_dense::map< entt::id_type, std::string > m_id_to_name
Maps an entt type id to a string.
AnyJSONFactory m_json_any_factory
Creates an entt::any from a json component data.
nlohmann::json serialize_entity(const entt::entity entity, entt::registry &registry)
Serialise a single entity.
Validations m_validations
Stores validation configurations.
Makes sure a type is a valid component.
Definition Concepts.hpp:87
Timer.hpp galaxy.
Definition Async.hpp:17
Data needed to serialize an entity.
std::string name
Name of the component.
nlohmann::json json
Component data as a json object.