preparing serialization of entities
This commit is contained in:
+52
-12
@@ -7,6 +7,7 @@
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Core/Thread/ThreadContext.h>
|
||||
#include <Entity/EntityManager.h>
|
||||
#include <Graphics/MeshRenderer.h>
|
||||
|
||||
#ifdef JULIET_ENABLE_IMGUI
|
||||
@@ -30,41 +31,80 @@ void AddToWorld(NonNullPtr<World> world, NonNullPtr<Entity> entity)
|
||||
|
||||
void RemoveWorldEntity(World& world, size_t index) {}
|
||||
|
||||
void Serialize(archive& data, World& world, String filename)
|
||||
void Serialize(archive& ar, World& world, String filename)
|
||||
{
|
||||
Assert(IsValid(filename));
|
||||
|
||||
TempArena temp = scratch_begin(nullptr, 0);
|
||||
auto& entityManager = GetEntityManager();
|
||||
|
||||
if (data.loading)
|
||||
if (ar.loading)
|
||||
{
|
||||
// Load
|
||||
ByteBuffer fileBuffer = LoadFile(temp.Arena, filename);
|
||||
ByteBuffer fileBuffer = LoadFile(ar.arena, filename);
|
||||
if (fileBuffer.Size >= sizeof(WorldFileHeader))
|
||||
{
|
||||
ar.base_ptr = fileBuffer.Data;
|
||||
|
||||
WorldFileHeader header;
|
||||
serialize_elem(ar, header);
|
||||
Assert(header.Magic == kWorldMagic);
|
||||
Assert(header.Version == kWorldVersion);
|
||||
|
||||
for (typed_entity_array& type : entityManager.by_type)
|
||||
{
|
||||
serialize_elem(ar, type.count);
|
||||
|
||||
if (type.count > 0)
|
||||
{
|
||||
|
||||
// Unserialize the base entity to get informations
|
||||
Entity entity;
|
||||
serialize(ar, &entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save
|
||||
IOStream* stream = IOFromFile(temp.Arena, filename, WrapString("wb"));
|
||||
IOStream* stream = IOFromFile(ar.arena, filename, WrapString("wb"));
|
||||
|
||||
index_t beginPos = ArenaPos(temp.Arena);
|
||||
index_t beginPos = ArenaPos(ar.arena);
|
||||
|
||||
// Headers
|
||||
auto* header = ArenaPushStruct<WorldFileHeader>(temp.Arena);
|
||||
auto* header = ArenaPushStruct<WorldFileHeader>(ar.arena);
|
||||
header->Magic = kWorldMagic;
|
||||
header->Version = kWorldVersion;
|
||||
|
||||
index_t endPos = ArenaPos(temp.Arena);
|
||||
ar.base_ptr = header;
|
||||
|
||||
// TODO : Move to a one file per entity model
|
||||
for (typed_entity_array& type : entityManager.by_type)
|
||||
{
|
||||
serialize_elem(ar, type.count);
|
||||
auto* element = type.array;
|
||||
uint8* rawElement = reinterpret_cast<uint8*>(element);
|
||||
size_t stride = element->Base->Kind->size_of;
|
||||
for (index_t idx = 0; idx < type.count; ++idx)
|
||||
{
|
||||
// Todo : utils
|
||||
// Get base entity from type
|
||||
Entity* entity = reinterpret_cast<entity_template*>(rawElement + (idx * stride))->Base;
|
||||
serialize(ar, entity);
|
||||
}
|
||||
}
|
||||
|
||||
// Write
|
||||
index_t endPos = ArenaPos(ar.arena);
|
||||
ByteBuffer writeBuffer = { .Data = reinterpret_cast<Byte*>(header), .Size = endPos - beginPos };
|
||||
size_t written = IOWrite(stream, writeBuffer);
|
||||
|
||||
size_t written = IOWrite(stream, writeBuffer);
|
||||
|
||||
Assert(writeBuffer.Size == written);
|
||||
|
||||
IOClose(stream);
|
||||
}
|
||||
|
||||
scratch_end(temp);
|
||||
//
|
||||
// uint32 entityCount = static_cast<uint32>(world.Entities.Size());
|
||||
// size_t totalBytes = sizeof(WorldFileHeader) + static_cast<size_t>(entityCount) * sizeof(WorldEntityDiskRecord);
|
||||
@@ -196,13 +236,13 @@ void RenderWorldEditorUI(World& world)
|
||||
|
||||
if (ImGui::Button("Save World"))
|
||||
{
|
||||
archive data{ .loading = false };
|
||||
archive data{ .arena = temp.Arena, .loading = false };
|
||||
Serialize(data, world, path);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Load World"))
|
||||
{
|
||||
archive data{ .loading = true };
|
||||
archive data{ .arena = temp.Arena, .loading = true };
|
||||
Serialize(data, world, path);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user