44#include < entt/entt.hpp>
55
66#include " Common.hpp"
7+ #include " Debug/Logger.hpp"
78#include " TypeId.hpp"
89
910namespace Pixf ::Core::Entities {
@@ -16,17 +17,28 @@ namespace Pixf::Core::Entities {
1617
1718 template <typename Archive, typename T>
1819 void Register (const std::string &name) {
19- m_SerializeFns[GetTypeId<Archive>()][entt::type_hash<T>::value ()] = [name](void *archivePtr, void *self) {
20+ m_SerializeFns[GetTypeId<Archive>()][entt::type_hash<T>::value ()] = [name](void *archivePtr,
21+ void *self) -> bool {
2022 auto &archive = *static_cast <Archive *>(archivePtr);
2123 auto *comp = static_cast <T *>(self);
22- archive (name, *comp);
24+ return archive (name, *comp);
2325 };
26+
27+ // Initialize the storage
28+ m_Registry.storage <T>();
2429 }
2530
2631 template <typename Archive>
2732 void SerializeEntity (Archive &archive, Entity &entity) {
28- archive.AddObject (" components" , [&](Archive &ar) { SerializeEntityComponents (ar, entity); });
29- archive (" id" , entity);
33+ std::uint32_t uint = static_cast <std::uint32_t >(entity);
34+ archive (" id" , uint);
35+ // This is bad, but it hopefully shouldn't matter too much
36+ while (!m_Registry.valid (static_cast <entt::basic_registry<>::entity_type>(uint))) {
37+ m_Registry.create ();
38+ }
39+
40+ entity = static_cast <Entity>(uint);
41+ archive.Recurse (" components" , [&](Archive &ar) { SerializeEntityComponents (ar, entity); });
3042 }
3143
3244 template <typename Archive>
@@ -36,18 +48,27 @@ namespace Pixf::Core::Entities {
3648 return ;
3749 }
3850
39- for (auto [id, storage]: m_Registry.storage ()) {
40- if (!storage.contains (entity)) {
51+ for (const auto &[id, storage]: m_Registry.storage ()) {
52+ // If the component is not registered, skip to the next one
53+ if (!m_SerializeFns[archiveTypeId].contains (id)) {
4154 continue ;
4255 }
4356
44- if (!m_SerializeFns[archiveTypeId].contains (id)) {
57+ // If we're serializing and the entity doesn't have the component, skip to the next one
58+ if (!storage.contains (entity) && archive.IsOutput ()) {
4559 continue ;
4660 }
4761
48- void *component = storage.value (entity);
49- auto func = m_SerializeFns[archiveTypeId][id];
50- func (&archive, component);
62+ // If we're deserializing and the entity doesn't have the component, add it
63+ if (!storage.contains (entity) && archive.IsInput ()) {
64+ storage.push (entity);
65+ }
66+
67+ // If the archive function fails (the component key wasn't found in the archive) then remove
68+ // the component that was added earlier
69+ if (!m_SerializeFns[archiveTypeId][id](&archive, storage.value (entity))) {
70+ storage.erase (entity);
71+ }
5172 }
5273 }
5374
@@ -90,16 +111,29 @@ namespace Pixf::Core::Entities {
90111 m_Registry.view <Args...>().each (func);
91112 }
92113
93- template <typename ... Args, typename Func>
114+ template <typename Func>
94115 void ForEachEntity (Func func) {
95- m_Registry.view <Args... >().each (func);
116+ m_Registry.view <Entity >().each (func);
96117 }
97118
98119 private:
99120 entt::registry m_Registry;
100- std::unordered_map<TypeId, std::unordered_map<entt::id_type, std::function<void (void *, void *)>>>
101- m_SerializeFns;
121+ std::map<TypeId, std::map<entt::id_type, std::function<bool (void *, void *)>>> m_SerializeFns;
102122 };
123+
124+ template <typename Archive>
125+ void Serialize (Archive &archive, Registry ®istry) {
126+ std::vector<Entity> entities;
127+ registry.ForEachEntity ([&](const Entity entity) { entities.push_back (entity); });
128+
129+ archive.template AddArray <Entity>(" entities" , entities, [&](Archive &ar, Entity &entity) {
130+ registry.SerializeEntity (ar, entity);
131+ });
132+ }
103133} // namespace Pixf::Core::Entities
104134
135+ #define PIXF_REGISTER_COMP (Component, Registry ) \
136+ Registry.Register<Pixf::Core::Serial::JsonOutputArchive, Component>(#Component); \
137+ Registry.Register<Pixf::Core::Serial::JsonInputArchive, Component>(#Component)
138+
105139#endif // PIXF_REGISTRY_HPP
0 commit comments