conversion to c by gemini 4 argon
This commit is contained in:
1 parent
b70e2d21d2
commit
f9356f9ba7
369 files changed
+18074
-107634
No files matched your search
@@ -0,0 +1,140 @@
|
||||
#include <Data/World.h>
|
||||
|
||||
#include <Core/Common/CoreUtils.h>
|
||||
#include <Core/Common/serialization.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/HAL/IO/IOStream.h>
|
||||
#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
|
||||
#include <dcimgui.h>
|
||||
#endif
|
||||
|
||||
void InitWorld(World* world, Arena* arena)
|
||||
{
|
||||
Assert(world != NULL);
|
||||
Assert(arena != NULL);
|
||||
world->WorldArena = arena;
|
||||
}
|
||||
|
||||
void ShutdownWorld(World* world)
|
||||
{
|
||||
Assert(world != NULL);
|
||||
world->WorldArena = NULL;
|
||||
}
|
||||
|
||||
void AddToWorld(World* world, Entity* entity)
|
||||
{
|
||||
(void)world;
|
||||
(void)entity;
|
||||
}
|
||||
|
||||
void RemoveWorldEntity(World* world, size_t index)
|
||||
{
|
||||
(void)world;
|
||||
(void)index;
|
||||
}
|
||||
|
||||
void SerializeWorld(Archive* ar, World* world, String filename)
|
||||
{
|
||||
(void)world;
|
||||
Assert(ar != NULL);
|
||||
Assert(IsValidString(filename));
|
||||
|
||||
EntityManager* entityManager = GetEntityManager();
|
||||
|
||||
if (ar->loading)
|
||||
{
|
||||
// Load
|
||||
ByteBuffer fileBuffer = LoadFile(ar->arena, filename);
|
||||
|
||||
// TEST SERIALIZATION
|
||||
ParsedArchive archive = tokenize_archive(ar->arena, fileBuffer);
|
||||
#if JULIET_DEBUG
|
||||
audit_unconsumed_properties(&archive, ConstString("World"));
|
||||
#else
|
||||
(void)archive;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save
|
||||
IOStream* stream = IOFromFile(ar->arena, filename, WrapString("wb"));
|
||||
|
||||
index_t beginPos = ArenaPos(ar->arena);
|
||||
|
||||
// Headers
|
||||
WorldFileHeader* header = ArenaPushStruct(ar->arena, WorldFileHeader);
|
||||
header->Magic = kWorldMagic;
|
||||
|
||||
// TODO : Move to a one file per entity model
|
||||
for (uint8 i = 0; i < ENTITY(Count); ++i)
|
||||
{
|
||||
typed_entity_array* type = &entityManager->by_type[i];
|
||||
serialize_elem(ar, type->count);
|
||||
if (type->count > 0 && type->array != NULL)
|
||||
{
|
||||
EntityTemplate* element = type->array;
|
||||
uint8* rawElement = (uint8*)element;
|
||||
size_t stride = element->base->derived_kind->size_of;
|
||||
for (index_t idx = 0; idx < type->count; ++idx)
|
||||
{
|
||||
Entity* entity = ((EntityTemplate*)(rawElement + (idx * stride)))->base;
|
||||
serialize_entity(ar, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write
|
||||
index_t endPos = ArenaPos(ar->arena);
|
||||
ByteBuffer writeBuffer = { .Data = (Byte*)header, .Size = endPos - beginPos };
|
||||
|
||||
size_t written = IOWrite(stream, writeBuffer);
|
||||
|
||||
Assert(writeBuffer.Size == written);
|
||||
|
||||
IOClose(stream);
|
||||
}
|
||||
}
|
||||
|
||||
bool8 LoadWorld(World* world, String filename)
|
||||
{
|
||||
(void)world;
|
||||
Assert(IsValidString(filename));
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef JULIET_EDITOR
|
||||
void RenderWorldEditorUI(World* world)
|
||||
{
|
||||
Assert(world != NULL);
|
||||
|
||||
if (ImGui_Begin("World Editor", NULL, ImGuiWindowFlags_None))
|
||||
{
|
||||
TempArena temp = scratch_begin(NULL, 0);
|
||||
static char worldFilePath[256] = "/world.bin";
|
||||
ImGui_InputText("World File", worldFilePath, sizeof(worldFilePath));
|
||||
|
||||
Path path = GetAssetPath(temp.Arena, AssetType_JAsset, WrapString(worldFilePath));
|
||||
|
||||
if (ImGui_Button("Save World"))
|
||||
{
|
||||
Archive data = { .arena = temp.Arena, .loading = false };
|
||||
SerializeWorld(&data, world, path.FullPath);
|
||||
}
|
||||
ImGui_SameLine(0.0f, -1.0f);
|
||||
if (ImGui_Button("Load World"))
|
||||
{
|
||||
Archive data = { .arena = temp.Arena, .loading = true };
|
||||
SerializeWorld(&data, world, path.FullPath);
|
||||
}
|
||||
|
||||
scratch_end(temp);
|
||||
}
|
||||
ImGui_End();
|
||||
}
|
||||
#endif
|
||||
@@ -1,322 +0,0 @@
|
||||
#include <Data/World.h>
|
||||
|
||||
#include <Core/Common/CoreUtils.h>
|
||||
#include <Core/Common/serialization.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/HAL/IO/IOStream.h>
|
||||
#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
|
||||
#include <imgui.h>
|
||||
#endif
|
||||
|
||||
void InitWorld(NonNullPtr<World> world, NonNullPtr<Arena> arena)
|
||||
{
|
||||
world->WorldArena = arena.Get();
|
||||
}
|
||||
|
||||
void ShutdownWorld(NonNullPtr<World> world)
|
||||
{
|
||||
world->WorldArena = nullptr;
|
||||
}
|
||||
|
||||
void AddToWorld(NonNullPtr<World> /*world*/, NonNullPtr<Entity> /*entity*/)
|
||||
{
|
||||
// RegisterEntity(*world->EntityManager, entity.Get());
|
||||
}
|
||||
|
||||
void RemoveWorldEntity(World& /*world*/, size_t /*index*/) {}
|
||||
|
||||
void Serialize(Archive& ar, World& /*world*/, String filename)
|
||||
{
|
||||
Assert(IsValid(filename));
|
||||
|
||||
auto& entityManager = GetEntityManager();
|
||||
|
||||
if (ar.loading)
|
||||
{
|
||||
// Load
|
||||
ByteBuffer fileBuffer = LoadFile(ar.arena, filename);
|
||||
|
||||
// TEST SERIALIZATION
|
||||
ParsedArchive archive = tokenize_archive(ar.arena, fileBuffer);
|
||||
// ArchivePropertyNode* property = find_property(&archive, "Position"_crc32);
|
||||
audit_unconsumed_properties(&archive, ConstString("World"));
|
||||
|
||||
// if (fileBuffer.Size >= sizeof(WorldFileHeader))
|
||||
// {
|
||||
// ar.base_ptr = fileBuffer.Data;
|
||||
//
|
||||
// WorldFileHeader header;
|
||||
// serialize_elem(ar, header);
|
||||
// Assert(header.Magic == kWorldMagic);
|
||||
//
|
||||
// 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(ar.arena, filename, WrapString("wb"));
|
||||
|
||||
index_t beginPos = ArenaPos(ar.arena);
|
||||
|
||||
// Headers
|
||||
auto* header = ArenaPushStruct<WorldFileHeader>(ar.arena);
|
||||
header->Magic = kWorldMagic;
|
||||
|
||||
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->derived_kind->size_of;
|
||||
for (index_t idx = 0; idx < type.count; ++idx)
|
||||
{
|
||||
// Todo : utils
|
||||
// Get base entity from type
|
||||
Entity* entity = reinterpret_cast<EntityTemplate*>(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);
|
||||
|
||||
Assert(writeBuffer.Size == written);
|
||||
|
||||
IOClose(stream);
|
||||
}
|
||||
|
||||
//
|
||||
// uint32 entityCount = static_cast<uint32>(world.Entities.Size());
|
||||
// size_t totalBytes = sizeof(WorldFileHeader) + static_cast<size_t>(entityCount) * sizeof(WorldEntityDiskRecord);
|
||||
//
|
||||
// ArenaParams tempParams = { .ReserveSize = Megabytes(1), .Name = "WorldSaveArena" };
|
||||
// Arena* tempArena = ArenaAllocate(tempParams);
|
||||
// if (!tempArena)
|
||||
// {
|
||||
// LogError(LogCategory::Game, "SaveWorld: Failed to allocate memory for saving world.");
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// auto deferRelease = Defer([&]() { ArenaRelease(tempArena); });
|
||||
//
|
||||
// uint8* bufferData = ArenaPushArray<uint8, false>(tempArena, totalBytes);
|
||||
// if (!bufferData)
|
||||
// {
|
||||
// LogError(LogCategory::Game, "SaveWorld: Failed to allocate buffer in arena.");
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// auto* header = reinterpret_cast<WorldFileHeader*>(bufferData);
|
||||
// header->Magic = kWorldMagic;
|
||||
// header->Version = kWorldVersion;
|
||||
// header->EntityCount = entityCount;
|
||||
// header->Reserved = 0;
|
||||
//
|
||||
// auto* records = reinterpret_cast<WorldEntityDiskRecord*>(bufferData + sizeof(WorldFileHeader));
|
||||
// for (size_t i = 0; i < entityCount; ++i)
|
||||
// {
|
||||
// const Entity& ent = world.Entities[i];
|
||||
// records[i].X = ent.X;
|
||||
// records[i].Y = ent.Y;
|
||||
// records[i].Z = ent.Z;
|
||||
// }
|
||||
//
|
||||
// IOStream* stream = IOFromFile(tempArena, filename, WrapString("wb"));
|
||||
// if (!stream)
|
||||
// {
|
||||
// LogError(LogCategory::Game, "SaveWorld: Failed to open file for writing: %s", CStr(filename));
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// ByteBuffer writeBuffer = { .Data = reinterpret_cast<Byte*>(bufferData), .Size = totalBytes };
|
||||
//
|
||||
// size_t written = IOWrite(stream, writeBuffer);
|
||||
// IOClose(stream);
|
||||
//
|
||||
// if (written != totalBytes)
|
||||
// {
|
||||
// LogError(LogCategory::Game, "SaveWorld: Failed to write complete world data to %s (wrote %zu / %zu bytes)",
|
||||
// CStr(filename), written, totalBytes);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// LogMessage(LogCategory::Game, "World successfully saved to %s (%u entities)", CStr(filename), entityCount);
|
||||
// return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool LoadWorld(World& /*world*/, String filename)
|
||||
{
|
||||
Assert(IsValid(filename));
|
||||
// Assert(world.WorldArena != nullptr);
|
||||
//
|
||||
// TempArena loadArena = scratch_begin(nullptr, 0);
|
||||
//
|
||||
// ByteBuffer fileBuffer = LoadFile(loadArena.Arena, filename);
|
||||
// if (fileBuffer.Data && fileBuffer.Size < sizeof(WorldFileHeader))
|
||||
// {
|
||||
// const WorldFileHeader* header = reinterpret_cast<const WorldFileHeader*>(fileBuffer.Data);
|
||||
// const bool invalidMagicNum = header->Magic != kWorldMagic;
|
||||
// const bool invalidVersion = header->Version != kWorldVersion;
|
||||
// if (invalidMagicNum)
|
||||
// {
|
||||
// LogError(LogCategory::Game, "LoadWorld: Invalid magic in world file: %s (expected 0x%08X, got 0x%08X)",
|
||||
// CStr(filename), kWorldMagic, header->Magic);
|
||||
// }
|
||||
//
|
||||
// if (invalidVersion)
|
||||
// {
|
||||
// LogError(LogCategory::Game, "LoadWorld: Unsupported world file version: %u in %s", header->Version, CStr(filename));
|
||||
// }
|
||||
//
|
||||
// size_t expectedSize = sizeof(WorldFileHeader) + static_cast<size_t>(header->EntityCount) * sizeof(WorldEntityDiskRecord);
|
||||
// const bool invalidSize = fileBuffer.Size < expectedSize;
|
||||
// if (invalidSize)
|
||||
// {
|
||||
// LogError(LogCategory::Game, "LoadWorld: Corrupted file %s: size %zu < expected %zu for %u entities",
|
||||
// CStr(filename), fileBuffer.Size, expectedSize, header->EntityCount);
|
||||
// }
|
||||
//
|
||||
// if (!invalidMagicNum && !invalidVersion && !invalidSize)
|
||||
// {
|
||||
//
|
||||
// // world.Entities.Clear();
|
||||
// //
|
||||
// // const auto* records = reinterpret_cast<const WorldEntityDiskRecord*>(
|
||||
// // reinterpret_cast<const uint8*>(fileBuffer.Data) + sizeof(WorldFileHeader));
|
||||
// //
|
||||
// // for (uint32 i = 0; i < header->EntityCount; ++i)
|
||||
// // {
|
||||
// // Entity ent;
|
||||
// // (void)AddWorldEntity(world, records[i].X, records[i].Y, records[i].Z);
|
||||
// // }
|
||||
//
|
||||
// LogMessage(LogCategory::Game, "World successfully loaded from %s (%u entities)", CStr(filename), header->EntityCount);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// LogError(LogCategory::Game, "LoadWorld: Failed to read world file or file is too small: %s", CStr(filename));
|
||||
// }
|
||||
//
|
||||
// scratch_end(loadArena);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef JULIET_EDITOR
|
||||
void RenderWorldEditorUI(World& world)
|
||||
{
|
||||
if (ImGui::Begin("World Editor"))
|
||||
{
|
||||
TempArena temp = scratch_begin(nullptr, 0);
|
||||
static char worldFilePath[256] = "/world.bin";
|
||||
ImGui::InputText("World File", worldFilePath, sizeof(worldFilePath));
|
||||
|
||||
Path path = GetAssetPath(temp.Arena, AssetType::JAsset, ConstString(worldFilePath));
|
||||
|
||||
if (ImGui::Button("Save World"))
|
||||
{
|
||||
Archive data = { .arena = temp.Arena, .loading = false };
|
||||
Serialize(data, world, path.FullPath);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Load World"))
|
||||
{
|
||||
Archive data{ .arena = temp.Arena, .loading = true };
|
||||
Serialize(data, world, path.FullPath);
|
||||
}
|
||||
|
||||
scratch_end(temp);
|
||||
|
||||
// ImGui::SameLine();
|
||||
// if (ImGui::Button("Clear All"))
|
||||
// {
|
||||
// ClearWorld(world);
|
||||
// }
|
||||
//
|
||||
// ImGui::Separator();
|
||||
//
|
||||
// if (ImGui::Button("Add Entity"))
|
||||
// {
|
||||
// (void)AddWorldEntity(world, 0.0f, 0.0f, 0.0f);
|
||||
// }
|
||||
//
|
||||
// ImGui::Text("Entity Count: %zu", world.Entities.Size());
|
||||
// ImGui::Separator();
|
||||
//
|
||||
// static int selectedEntity = -1;
|
||||
// if (selectedEntity >= static_cast<int>(world.Entities.Size()))
|
||||
// {
|
||||
// selectedEntity = -1;
|
||||
// }
|
||||
//
|
||||
// ImGui::BeginChild("EntityList", ImVec2(180, 200), true);
|
||||
// for (size_t i = 0; i < world.Entities.Size(); ++i)
|
||||
// {
|
||||
// char label[64];
|
||||
// snprintf(label, sizeof(label), "Entity #%zu (ID: %llu)", i, world.Entities[i].ID);
|
||||
// if (ImGui::Selectable(label, selectedEntity == static_cast<int>(i)))
|
||||
// {
|
||||
// selectedEntity = static_cast<int>(i);
|
||||
// }
|
||||
// }
|
||||
// ImGui::EndChild();
|
||||
//
|
||||
// ImGui::SameLine();
|
||||
//
|
||||
// ImGui::BeginChild("EntityInspector", ImVec2(0, 200), true);
|
||||
// if (selectedEntity >= 0 && selectedEntity < static_cast<int>(world.Entities.Size()))
|
||||
// {
|
||||
// Entity& ent = world.Entities[static_cast<size_t>(selectedEntity)];
|
||||
// ImGui::Text("Selected: Entity #%d", selectedEntity);
|
||||
// ImGui::Text("ID: %llu", ent.ID);
|
||||
//
|
||||
// float pos[3] = { ent.X, ent.Y, ent.Z };
|
||||
// if (ImGui::DragFloat3("Position", pos, 0.1f))
|
||||
// {
|
||||
// ent.X = pos[0];
|
||||
// ent.Y = pos[1];
|
||||
// ent.Z = pos[2];
|
||||
// UpdateWorld(world);
|
||||
// }
|
||||
//
|
||||
// if (ImGui::Button("Delete Entity"))
|
||||
// {
|
||||
// RemoveWorldEntity(world, static_cast<size_t>(selectedEntity));
|
||||
// selectedEntity = -1;
|
||||
// UpdateWorld(world);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ImGui::Text("Select an entity to edit its properties.");
|
||||
// }
|
||||
// ImGui::EndChild();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
#endif
|
||||
+15
-14
@@ -1,38 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Core/Common/String.h>
|
||||
#include <Core/Container/Vector.h>
|
||||
#include <Core/Memory/MemoryArena.h>
|
||||
#include <Entity/Entity.h>
|
||||
|
||||
struct Archive;
|
||||
struct EntityManager;
|
||||
typedef struct Archive Archive;
|
||||
typedef struct EntityManager EntityManager;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct WorldFileHeader WorldFileHeader;
|
||||
struct WorldFileHeader
|
||||
{
|
||||
uint32 Magic = 0x444C574A; // 'JWLD' in little-endian
|
||||
uint32 Magic; // 0x444C574A ('JWLD' in little-endian)
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
constexpr uint32 kWorldMagic = 0x444C574A; // 'JWLD'
|
||||
constexpr uint32 kWorldVersion = 1;
|
||||
#define kWorldMagic ((uint32)0x444C574A) // 'JWLD'
|
||||
#define kWorldVersion ((uint32)1)
|
||||
|
||||
typedef struct World World;
|
||||
struct World
|
||||
{
|
||||
Arena* WorldArena = nullptr;
|
||||
EntityManager* EntityManager = nullptr;
|
||||
Arena* WorldArena;
|
||||
EntityManager* EntityManager;
|
||||
};
|
||||
|
||||
void InitWorld(NonNullPtr<World> world, NonNullPtr<Arena> arena);
|
||||
void ShutdownWorld(NonNullPtr<World> world);
|
||||
void InitWorld(World* world, Arena* arena);
|
||||
void ShutdownWorld(World* world);
|
||||
|
||||
void AddToWorld(NonNullPtr<World> world, NonNullPtr<Entity> entity);
|
||||
void RemoveWorldEntity(World& world, size_t index);
|
||||
void AddToWorld(World* world, Entity* entity);
|
||||
void RemoveWorldEntity(World* world, size_t index);
|
||||
|
||||
void Serialize(Archive& data, World& world, String filename);
|
||||
void SerializeWorld(Archive* data, World* world, String filename);
|
||||
|
||||
#if JULIET_EDITOR
|
||||
void RenderWorldEditorUI(World& world);
|
||||
void RenderWorldEditorUI(World* world);
|
||||
#endif
|
||||
Reference in new issue
Block a user