Recreating serialization

This commit is contained in:
Chewico 2026-02-10 13:41:31 +01:00
parent 398b655f3d
commit 6ee3cc146f
22 changed files with 231 additions and 244 deletions

View File

@ -61,7 +61,7 @@ namespace Deer {
private: private:
uint16_t m_mainCamera = 0; uint16_t m_mainCamera = 0;
std::stack<u_int16_t> unused_entities_spaces; std::stack<u_int32_t> unused_entities_spaces;
std::vector<Entity> entities; std::vector<Entity> entities;
friend class Entity; friend class Entity;

View File

@ -0,0 +1,23 @@
#pragma once
#include "DeerCore/Serialization/WorldSettings.h"
#include "DeerCore/Components.h"
#include "DeerCore/Serialization/Core/QuatSerialization.h"
#include "DeerCore/Serialization/Core/Vec3Serialization.h"
#include "cereal/cereal.hpp"
namespace Deer {
struct TransformComponentSerialization {
WorldSerializationSettings& settings;
TransformComponent& component;
template <class Archive>
void serialize(Archive& archive) {
archive(cereal::make_nvp("Position", component.position));
archive(cereal::make_nvp("Scale", component.scale));
archive(cereal::make_nvp("Rotation", component.rotation));
}
};
} // namespace Deer

View File

@ -0,0 +1,56 @@
#pragma once
#include "DeerCore/Serialization/WorldSettings.h"
#include "DeerCore/EntityEnviroment.h"
#include "DeerCore/Serialization/Entity.h"
#include "DeerCore/Serialization/Components/TransformComponent.h"
#include "cereal/cereal.hpp"
#include <string>
namespace Deer {
struct EntitySerialization {
WorldSerializationSettings& settings;
EntityEnvironment* entityEnvironment;
uint32_t entityId;
template <class Archive, class T, class S>
void saveComponent(Archive& archive, Entity& entity) {
std::string containsComponentString = "Contains_";
containsComponentString += typeid(T).name();
bool hasComponent = entity.hasComponent<T>();
archive(cereal::make_nvp(containsComponentString.c_str(), hasComponent));
if (hasComponent) {
S serialization;
serialization.component = entity.getComponent<T>();
serialization.settings = settings;
archive(cereal::make_nvp(typeid(T).name(), serialization));
}
}
template <class Archive>
void save(Archive& archive) const {
Entity& entity = entityEnvironment->getEntity(entityId);
TagComponent& tag = entity.getComponent<TagComponent>();
RelationshipComponent& relation = entity.getComponent<RelationshipComponent>();
archive(cereal::make_nvp("Id", entityId));
archive(cereal::make_nvp("Tag", tag.tag));
archive(cereal::make_nvp("NetworkBehaviour", tag.networkBehaviour));
archive(cereal::make_nvp("Parent", relation.parent_id));
TransformComponentSerialization serialization;
serialization.settings = settings;
serialization.component = entity.getComponent<T>();
archive(cereal::make_nvp(typeid(TransformComponent).name(), serialization));
}
template <class Archive>
void load(Archive& archive) {
}
};
} // namespace Deer

View File

@ -0,0 +1,77 @@
#pragma once
#include "DeerCore/Serialization/WorldSettings.h"
#include "DeerCore/EntityEnviroment.h"
#include "DeerCore/Serialization/Entity.h"
#include "cereal/cereal.hpp"
#include "cereal/types/vector.hpp"
#include <vector>
namespace Deer {
struct EntityEnvironmentSerialization {
WorldSerializationSettings& settings;
EntityEnvironment* entityEnvironment;
template <class Archive>
void save(Archive& archive) const {
std::vector<EntitySerialization> entities;
size_t entityIndex = 0;
size_t remainingEntities = entityEnvironment->getEntityCount();
while (remainingEntities > 0) {
if (!entityEnvironment->entityExists(entityIndex)) {
entityIndex++;
continue;
}
Entity& entity = entityEnvironment->getEntity(entityIndex);
if (!entity.isValidNetworkBehaviour() && !(settings.includeClient && settings.includeServer)) {
remainingEntities--;
entityIndex++;
}
EntityNetworkBehaviour networkBehaviour = entity.getForcedNetworkBehaviour();
if (networkBehaviour == EntityNetworkBehaviour::CLIENT && !settings.includeClient) {
remainingEntities--;
entityIndex++;
}
if (networkBehaviour == EntityNetworkBehaviour::SERVER && !settings.includeServer) {
remainingEntities--;
entityIndex++;
}
entities.push_back({});
EntitySerialization& entityS = entities.push_back();
entityS.settings = settings;
entityS.entityId = entityEnvironment;
entityS.entityId = entityIndex;
remainingEntities--;
entityIndex++;
}
archive(cereal::make_size_tag(entities.size()));
for (EntitySerialization& entityS : entities)
archive(entityS);
}
template <class Archive>
void load(Archive& archive) {
size_t entitySize;
archive(cereal::make_nvp("Entities", entitySize));
for (size_t i = 0; i < entitySize; i++) {
EntitySerialization entityS;
entityS.entityEnvironment = entityEnvironment;
entityS.settings = settings;
archive(entityS);
}
}
};
} // namespace Deer

View File

@ -0,0 +1,26 @@
#pragma once
#include "DeerCore/Serialization/EntityEnvironment.h"
#include "DeerCore/Serialization/WorldSettings.h"
#include "cereal/cereal.hpp"
namespace Deer {
class World;
struct WorldSerialization {
WorldSerializationSettings settings;
EntityEnvironment* entityEnv;
uint32_t entityId;
World* world;
template <class Archive>
void serialize(Archive& archive) {
EntityEnvironmentSerialization entityEnvironment;
entityEnvironment.settings = settings;
entityEnvironment.entityEnvironment = world->entityEnvironment.get();
archive(cereal::make_nvp("SerializationSettings", settings));
archive(cereal::make_nvp("EntityEnvironment", entityEnvironment));
}
};
} // namespace Deer

View File

@ -0,0 +1,25 @@
#pragma once
#include "cereal/cereal.hpp"
namespace Deer {
struct WorldSerializationSettings {
bool includeServer;
bool includeClient;
WorldSerializationSettings() {
#ifdef DEER_RENDER
includeServer = false;
includeClient = true;
#else
includeServer = true;
includeClient = false;
#endif
};
template <class Archive>
void serialize(Archive& archive) {
archive(CEREAL_NVP(includeServer));
archive(CEREAL_NVP(includeClient));
}
};
} // namespace Deer

View File

@ -1,15 +0,0 @@
#pragma once
#include "DeerCore/Components.h"
namespace Deer {
// RELATIONSHIP COMPONENT
template <class Archive>
void serialize(Archive& archive, RelationshipComponent& relationship) {
archive(cereal::make_nvp("parentId", relationship.parent_id));
archive(cereal::make_size_tag(
static_cast<cereal::size_type>(relationship.getChildCount())));
for (int i = 0; i < relationship.getChildCount(); i++)
archive(relationship.getChildId(i));
}
} // namespace Deer

View File

@ -1,16 +0,0 @@
#pragma once
#include "DeerCore/Components.h"
namespace Deer {
// TRANSFORM COMPONENT
template <class Archive>
void serialize(Archive& archive,
TransformComponent& transform) {
archive(cereal::make_nvp("position", transform.position));
archive(cereal::make_nvp("scale", transform.scale));
archive(cereal::make_nvp("rotation", transform.rotation));
}
} // namespace Deer

View File

@ -1,72 +0,0 @@
#pragma once
#include "DeerCore/Components.h"
#include "DeerCore/EntityEnviroment.h"
#include "EntitySerializationStruct.h"
namespace Deer {
template <class Archive, typename T>
void saveComponent(Archive& archive, Entity const& m_entity) {
bool hasComponent = m_entity.hasComponent<T>();
archive(cereal::make_nvp(("contains_" + typedef(T).get_name()).c_str(), hasComponent));
if (hasComponent) {
const T& component = m_entity.getComponent<T>();
archive(cereal::make_nvp(typedef(T).get_name(), component));
}
}
template <class Archive, typename T>
void loadComponent(Archive& archive, Entity const& m_entity) {
bool hasComponent;
archive(cereal::make_nvp(("contains_" + typedef(T).get_name()).c_str(), hasComponent));
if (hasComponent) {
T& component = m_entity.addComponent<T>();
archive(cereal::make_nvp(typedef(T).get_name(), component));
}
}
// ENTITY
template <class Archive>
void save(Archive& archive, EntitySerializationStruct const& m_entity) {
const Entity& entity = m_entity.env->getEntity(m_entity.entityID);
const TagComponent& name = entity.getComponent<TagComponent>();
archive(cereal::make_nvp("id", m_entity.entityID));
archive(cereal::make_nvp("name", name.tag));
const TransformComponent& transform = entity.getComponent<TransformComponent>();
archive(cereal::make_nvp("transform", transform));
const RelationshipComponent& relation = entity.getComponent<RelationshipComponent>();
archive(cereal::make_nvp("relationship", relation));
#ifdef DEER_RENDER
if (!is_server_serialization) {
saveComponent<Archive, MeshComponent>(archive, "meshRenderComponent", entity);
saveComponent<Archive, CameraComponent>(archive, "cameraComponent", entity);
}
#endif
}
template <class Archive>
void load(Archive& archive, EntitySerializationStruct& m_entity) {
uint16_t id;
std::string name;
archive(cereal::make_nvp("id", id));
archive(cereal::make_nvp("name", name));
Entity& entity = m_entity.env->createEntityWithId(id);
archive(cereal::make_nvp("transform", entity.getComponent<TransformComponent>()));
RelationshipComponent& rc = entity.getComponent<RelationshipComponent>();
archive(cereal::make_nvp("relationship", rc));
entity.setParent(m_entity.env->getEntity(rc.parent_id));
#ifdef DEER_RENDER
if (!is_server_serialization) {
loadComponent<Archive, MeshComponent>(archive, "meshRenderComponent", entity);
loadComponent<Archive, CameraComponent>(archive, "cameraComponent", entity);
}
#endif
}
} // namespace Deer

View File

@ -1,10 +0,0 @@
#pragma once
#include <cstdint>
namespace Deer {
class EntityEnvironment;
struct EntitySerializationStruct {
uint32_t entityID;
EntityEnvironment* env;
};
} // namespace Deer

View File

@ -1,57 +0,0 @@
#pragma once
#include <cstdint>
#include <vector>
#include "DeerCore/EntityEnviroment.h"
#include "EntitySerializationStruct.h"
namespace Deer {
struct EntityEnvironmentEntity {
EntityEnvironment& environment;
EntityEnvironmentEntity(EntityEnvironment& env) : environment(env) {}
};
template <class Archive>
void save(Archive& archive, const Deer::EntityEnvironment& environment) {
EntityEnvironmentEntity envEnt(const_cast<Deer::EntityEnvironment&>(environment));
archive(cereal::make_nvp("entities", envEnt));
}
template <class Archive>
void load(Archive& archive, Deer::EntityEnvironment& environment) {
EntityEnvironmentEntity envEnt(environment);
archive(cereal::make_nvp("entities", envEnt));
}
template <class Archive>
void save(Archive& archive, EntityEnvironmentEntity const& m_entities) {
archive(cereal::make_size_tag(static_cast<cereal::size_type>(
m_entities.entityEnvironment->getEntityCount())));
for (uint16_t i = 0; i < m_entities.entityEnvironment->getEntityCount(); i++) {
while (!m_entities.entityEnvironment->entityExists(i)) {
i++;
}
EntitySerializationStruct serializationStruct;
serializationStruct.env =
const_cast<EntityEnvironment*>(&m_entities.environment);
serializationStruct.entityID = i;
archive(serializationStruct);
}
}
template <class Archive>
void load(Archive& archive, EntityEnvironmentEntity& m_entities) {
cereal::size_type size;
archive(cereal::make_size_tag(size));
for (int i = 0; i < size; i++) {
EntitySerializationStruct serializationStruct;
serializationStruct.env = &m_entities.environment;
archive(serializationStruct);
}
}
} // namespace Deer

View File

@ -1,4 +0,0 @@
namespace Deer {
bool is_server_serialization = false;
}

View File

@ -1,27 +0,0 @@
#pragma once
#include "cereal/cereal.hpp"
#include "cereal/types/string.hpp"
#include "cereal/types/vector.hpp"
// Serialization Vars
#include "DeerCore/World/Serialization/SerializationGlobalVars.h"
// GENERICS
#include "DeerCore/World/Serialization/QuatSerialization.h"
#include "DeerCore/World/Serialization/Vec3Serialization.h"
// SCENE SPECIFIC
#include "DeerCore/World/Serialization/EntityEnvironmentSerialization.h"
#include "DeerCore/World/Serialization/EntitySerialization.h"
// COMPONENTS SPECIFIC
#include "DeerCore/World/Serialization/Components/RelationshipComponentSerialization.h"
#include "DeerCore/World/Serialization/Components/TransformComponentSerialization.h"
// RENDER SPECIFIC
#ifdef DEER_RENDER
#include "DeerRender/World/Serialization/Components/CameraSerializationComponent.h"
#include "DeerRender/World/Serialization/Components/MeshRenderComponentSerialization.h"
#include "DeerRender/World/Serialization/Components/TextureBindingSerializationComponent.h"
#endif

View File

@ -1,7 +0,0 @@
#include "SerializationGlobalVars.h"
namespace Deer {
bool is_server_serialization = false;
}

View File

@ -1,5 +0,0 @@
#pragma once
namespace Deer {
extern bool is_server_serialization;
}

View File

@ -1,9 +0,0 @@
#pragma once
namespace Deer {
namespace Serialization {
}
}

View File

@ -1,12 +0,0 @@
#pragma once
#include "DeerCore/World.h"
#include "DeerCore/EntityEnviroment.h"
namespace Deer {
namespace Universe {
template <class Archive>
void save(Archive& archive, World const& world) {
World
}
}
}

View File

@ -1,12 +1,6 @@
#include "DeerCore/Universe.h" #include "DeerCore/Universe.h"
#include "DeerCore/World.h"
#include "DeerCore/Log.h"
#include "cereal/cereal.hpp"
#include "cereal/archives/json.hpp"
namespace Deer { namespace Deer {
void Universe::saveWorldInJson(World* world, const Path& path) {
}
} // namespace Deer } // namespace Deer

View File

@ -81,7 +81,7 @@ namespace Deer {
entities.push_back({}); entities.push_back({});
} else { } else {
static std::stack<uint16_t> unused_entities_spaces_cache; static std::stack<uint32_t> unused_entities_spaces_cache;
// This code its to remove a specific element from a stack // This code its to remove a specific element from a stack
// We pop the stack until we find the id or we empty it to // We pop the stack until we find the id or we empty it to

View File

@ -0,0 +1,20 @@
#pragma once
#include "DeerCore/Serialization/WorldSettings.h"
#include "DeerRender/Components.h"
#include "cereal/cereal.hpp"
namespace Deer {
struct MeshComponentSerialization {
WorldSerializationSettings& settings;
TransformComponent& component;
template <class Archive>
void serialize(Archive& archive) {
archive(cereal::make_nvp("Position", component.position));
archive(cereal::make_nvp("Scale", component.scale));
archive(cereal::make_nvp("Rotation", component.rotation));
}
};
} // namespace Deer