Skip to content

Commit dcfd2f7

Browse files
committed
Add registry serialization
1 parent e71c35e commit dcfd2f7

19 files changed

Lines changed: 414 additions & 195 deletions

File tree

Core/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ target_include_directories(imgui PUBLIC
9595
${imgui_SOURCE_DIR}/backends
9696
)
9797

98-
target_link_libraries(imgui PUBLIC glfw OpenGL::GL)
98+
target_link_libraries(imgui PRIVATE glfw OpenGL::GL)
9999

100100
set(PROJECT_SOURCES
101101
Pch.hpp
@@ -187,7 +187,7 @@ set(PROJECT_SOURCES
187187
src/Uuid/Uuid.cpp
188188
src/Files/File.hpp
189189
src/Files/File.cpp
190-
src/Entities/Components/Graphics/Model.hpp
190+
src/Entities/Components/Graphics/ModelRenderer.hpp
191191
src/Entities/World.hpp
192192
src/Json/Json.cpp
193193
src/Json/Json.hpp

Core/include/Pixf.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include "Application/Application.hpp"
55
#include "Debug/Logger.hpp"
6-
#include "Entities/Components/Graphics/Model.hpp"
6+
#include "Entities/Components/Graphics/ModelRenderer.hpp"
77
#include "Entities/Components/RigidTransform.hpp"
88
#include "Entities/Components/Transform.hpp"
99
#include "Entities/System.hpp"

Core/src/Application/Application.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,10 @@ namespace Pixf::Core::Application {
5656
app.Run(); \
5757
}
5858

59+
#define PIXF_CREATE_APPLICATION(application) \
60+
extern "C" { \
61+
Pixf::Core::Application::Application *CreateApplication() { return new application(); } \
62+
void DestroyApplication(Pixf::Core::Application::Application *app) { delete app; } \
63+
}
64+
5965
#endif // PIXF_APPLICATION_HPP

Core/src/Entities/Components/Graphics/Model.hpp renamed to Core/src/Entities/Components/Graphics/ModelRenderer.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
#ifndef PIXF_MODEL_HPP
22
#define PIXF_MODEL_HPP
33

4+
#include "Common.hpp"
45
#include "Uuid/Uuid.hpp"
56

67
namespace Pixf::Core::Entities::Graphics {
7-
struct Model {
8+
struct ModelRenderer {
89
Uuid::Uuid uuid;
910
};
1011

1112
template<typename Archive>
12-
void Serialize(Archive &archive, Model &model) {
13-
archive("uuid", model.uuid);
13+
PIXF_API void Serialize(Archive &archive, ModelRenderer &model) {
14+
Serialize(archive, model.uuid);
1415
}
1516
} // namespace Pixf::Core::Entities::Graphics
1617

Core/src/Entities/Components/RigidTransform.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "Math/Matrix.hpp"
55
#include "Math/Quaternion.hpp"
66
#include "Math/Vector.hpp"
7+
#include "Common.hpp"
78

89
namespace Pixf::Core::Entities::Components {
910
struct RigidTransform {
@@ -23,14 +24,13 @@ namespace Pixf::Core::Entities::Components {
2324
Math::Matrix4f GetMatrix() const {
2425
return Math::Matrix4f::Rotate(rotation) * Math::Matrix4f::Translate(position);
2526
}
26-
27-
template<class Archive>
28-
static void Serialize(Archive &archive, RigidTransform &transform) {
29-
archive("rx", transform.position.x);
30-
archive("ry", transform.position.y);
31-
archive("rz", transform.position.z);
32-
}
3327
};
28+
29+
template<class Archive>
30+
PIXF_API void Serialize(Archive &archive, RigidTransform &transform) {
31+
archive("position", transform.position);
32+
archive("rotation", transform.rotation);
33+
}
3434
} // namespace Pixf::Core::Entities::Components
3535

3636
#endif // PIXF_RIGIDTRANSFORM_HPP

Core/src/Entities/Components/Transform.hpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef PIXF_TRANSFORM_HPP
22
#define PIXF_TRANSFORM_HPP
33

4+
#include "Common.hpp"
45
#include "Math/Matrix.hpp"
56
#include "Math/Quaternion.hpp"
67
#include "Math/Vector.hpp"
@@ -27,14 +28,14 @@ namespace Pixf::Core::Entities::Components {
2728
return Math::Matrix4f::Rotate(rotation) * Math::Matrix4f::Scale(scale) *
2829
Math::Matrix4f::Translate(position);
2930
}
30-
31-
template<class Archive>
32-
static void Serialize(Archive &archive, Transform &transform) {
33-
archive("position", transform.position);
34-
archive("rotation", transform.rotation);
35-
archive("scale", transform.scale);
36-
}
3731
};
32+
33+
template<class Archive>
34+
PIXF_API void Serialize(Archive &archive, Transform &transform) {
35+
archive("position", transform.position);
36+
archive("rotation", transform.rotation);
37+
archive("scale", transform.scale);
38+
}
3839
} // namespace Pixf::Core::Entities::Components
3940

4041
#endif // PIXF_TRANSFORM_HPP

Core/src/Entities/Registry.hpp

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <entt/entt.hpp>
55

66
#include "Common.hpp"
7+
#include "Debug/Logger.hpp"
78
#include "TypeId.hpp"
89

910
namespace 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 &registry) {
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

Core/src/Error/Error.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
#include "Error.hpp"
22

3+
#include <cxxabi.h>
4+
35
namespace Pixf::Core::Error {
6+
std::string Demangle(const char* name) {
7+
int status = 0;
8+
std::unique_ptr<char, void(*)(void*)> res {
9+
abi::__cxa_demangle(name, nullptr, nullptr, &status),
10+
std::free
11+
};
12+
13+
return (status == 0) ? res.get() : name;
14+
}
15+
416
void HandleTerminate() {
517
if (const std::exception_ptr exceptionPtr = std::current_exception()) {
618
try {
719
std::rethrow_exception(exceptionPtr);
820
} catch (const std::exception &e) {
9-
PIXF_CORE_LOG_FATAL("Exception type: {}, message: {}", typeid(e).name(), e.what());
21+
PIXF_CORE_LOG_FATAL("Exception type: {}, message: {}", Demangle(typeid(e).name()), e.what());
1022
} catch (...) {
1123
PIXF_CORE_LOG_FATAL("Unknown exception");
1224
}

Core/src/Json/Json.cpp

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,19 @@
33
namespace Pixf::Core::Json {
44
static constexpr unsigned int s_IndentLevel = 4;
55

6-
Array::Array(const nlohmann::json::array_t &array) : m_Array(array) {}
7-
8-
void Array::PushObject(const Json &object) { m_Array.push_back(object.m_Json); }
9-
10-
size_t Array::Size() const { return m_Array.size(); }
11-
12-
std::string Json::ToString() const { return m_Json.dump(s_IndentLevel); }
13-
14-
void Json::AddObject(const std::string &key, std::function<void(Json &)> &&func) {
15-
const auto fn = std::move(func);
16-
Json obj;
17-
fn(obj);
18-
Add(key, obj.m_Json);
19-
}
20-
21-
void Json::AddObject(const std::string &key, const Json &object) { Add(key, object.m_Json); }
22-
23-
Json Json::GetObject(const std::string &key) const { return m_Json.at(key); }
24-
25-
void Json::AddArray(const std::string &key, const Array &array) { Add(key, array.m_Array); }
26-
27-
void Json::AddArray(const std::string &key, std::function<void(Array &)> &&func) {
28-
const auto fn = std::move(func);
29-
Array array;
30-
fn(array);
31-
Add(key, array.m_Array);
6+
Json Json::Parse(std::string str) {
7+
Json json;
8+
json.m_Json = nlohmann::json::parse(str);
9+
return json;
3210
}
3311

34-
Array Json::GetArray(const std::string &key) const {
35-
return Array(static_cast<nlohmann::json::array_t>(m_Json.at(key)));
36-
}
12+
std::string Json::ToString() const { return m_Json.dump(s_IndentLevel); }
3713

3814
bool Json::Contains(const std::string &key) const { return m_Json.contains(key); }
3915

4016
Json::Json(const nlohmann::ordered_json &json) : m_Json(json) {}
4117

42-
Json Json::Parse(std::string str) {
43-
Json json;
44-
json.m_Json = nlohmann::json::parse(str);
45-
return json;
18+
Json::operator nlohmann::basic_json<nlohmann::ordered_map>() const {
19+
return m_Json;
4620
}
4721
} // namespace Pixf::Core::Json

0 commit comments

Comments
 (0)