Compare commits

..

2 Commits

Author SHA1 Message Date
Asuro
1067a72012 fixing stuff 2025-03-24 18:30:46 +01:00
Asuro
fa93abe1ec serialization stuff 2025-03-24 16:35:49 +01:00
18 changed files with 213 additions and 196 deletions

48
src/game/Gen.cpp Normal file
View File

@@ -0,0 +1,48 @@
#include "Gen.h"
namespace Generated
{
bool IsValid(const ModelHandle& h)
{
return h.ModelIdx != UINT16_MAX && IsValid(h.Asset);
}
bool IsValid(const AssetHandle& h)
{
return h.Idx != UINT32_MAX;
}
bool operator==(const AssetHandle& lhs, const AssetHandle& rhs)
{
return lhs.Idx == rhs.Idx;
}
bool operator==(const ModelHandle& lhs, const ModelHandle& rhs)
{
if (!IsValid(lhs) || !IsValid(rhs)) return IsValid(lhs) == IsValid(rhs);
return lhs.ModelIdx == rhs.ModelIdx && lhs.Asset == rhs.Asset;
}
PuzPos operator+=(PuzPos lhs, const PuzPos& rhs)
{
lhs.X += rhs.X;
lhs.Y += rhs.Y;
return lhs;
}
PuzPos operator+(PuzPos lhs, const PuzPos& rhs)
{
PuzPos res = lhs;
res.X += rhs.X;
res.Y += rhs.Y;
return res;
}
PuzPos operator-=(PuzPos lhs, const PuzPos& rhs)
{
lhs.X -= rhs.X;
lhs.Y -= rhs.Y;
return lhs;
}
PuzPos operator-(PuzPos lhs, const PuzPos& rhs)
{
PuzPos res = lhs;
res.X += rhs.X;
res.Y += rhs.Y;
return res;
}
} // namespace Generated

14
src/game/Gen.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include "../gen/Generated.h"
namespace Generated
{
bool IsValid(const AssetHandle& h);
bool IsValid(const ModelHandle& h);
bool operator==(const AssetHandle& lhs, const AssetHandle& rhs);
bool operator==(const ModelHandle& lhs, const ModelHandle& rhs);
PuzPos operator+=(PuzPos lhs, const PuzPos& rhs);
PuzPos operator+(PuzPos lhs, const PuzPos& rhs);
} // namespace Generated

View File

@@ -45,7 +45,7 @@ namespace Game
char ImguiIni[4096]{0}; char ImguiIni[4096]{0};
static constexpr uint32_t MaxAssets = 128; static constexpr uint32_t MaxAssets = 128;
uint32_t AssetCount = 0; uint32_t AssetCount = 0;
uint32_t AssetHandles[MaxAssets]{0}; Generated::AssetHandle AssetHandles[MaxAssets]{0};
char AssetHandlePaths[MaxAssets][128]; char AssetHandlePaths[MaxAssets][128];
bool ShowImguiDemo = false; bool ShowImguiDemo = false;
uint8_t DebugCardRotation = 0; uint8_t DebugCardRotation = 0;

View File

@@ -1,4 +1,5 @@
#include "../gen/Def.h" #include "../gen/Def.h"
#include "Gen.h"
#include "Global.h" #include "Global.h"
#include "Input.h" #include "Input.h"
#include "Instance.h" #include "Instance.h"
@@ -23,14 +24,14 @@ namespace Game
{ {
void EntityRenderData::Render(const Model* models, const Material* materials) void EntityRenderData::Render(const Model* models, const Material* materials)
{ {
if (ModelHandle == UINT16_MAX || MaterialHandle == UINT16_MAX) return; if (!Generated::IsValid(ModelH) || MaterialHandle == UINT16_MAX) return;
if (!Visible) return; if (!Visible) return;
auto& rendering = GameRendering::Get(); auto& rendering = GameRendering::Get();
Transform.UpdateMatrix(); Transform.UpdateMatrix();
bgfx::setTransform(Transform.M.M); bgfx::setTransform(Transform.M.M);
const Model& currentModel = models[ModelHandle]; const Model& currentModel = models[ModelH.ModelIdx];
const Material& currentMaterial = materials[MaterialHandle]; const Material& currentMaterial = materials[MaterialHandle];
bgfx::setVertexBuffer(0, currentModel.VertexBuffer); bgfx::setVertexBuffer(0, currentModel.VertexBuffer);
bgfx::setIndexBuffer(currentModel.IndexBuffer); bgfx::setIndexBuffer(currentModel.IndexBuffer);
@@ -105,9 +106,8 @@ namespace Game
LOG("Loading %s", fullPath.getCPtr()); LOG("Loading %s", fullPath.getCPtr());
Generated::Deserializer ser; Generated::Deserializer ser;
ser.Init(fullPath);
Generated::PuzzleData dataBuf; Generated::PuzzleData dataBuf;
if (ser.ReadT("PZZL", dataBuf)) if (ser.Init(fullPath, "PZZL") && ser.ReadT(dataBuf))
{ {
if (dataBuf.ID >= BX_COUNTOF(Puzzles)) if (dataBuf.ID >= BX_COUNTOF(Puzzles))
{ {
@@ -278,7 +278,7 @@ namespace Game
void Cube::Setup() void Cube::Setup()
{ {
EData.MaterialHandle = 0; EData.MaterialHandle = 0;
EData.ModelHandle = GameRendering::Get().GetModelHandleFromPath("models/cube.gltf"); EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/cube.gltf");
} }
void Cube::Update() void Cube::Update()
@@ -301,7 +301,7 @@ namespace Game
void TestEntity::Setup() void TestEntity::Setup()
{ {
EData.MaterialHandle = 0; EData.MaterialHandle = 0;
EData.ModelHandle = GameRendering::Get().GetModelHandleFromPath("models/zurg.gltf"); EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/zurg.gltf");
EData.Transform.Position = {0.0f, 0.0f, 0.0f}; EData.Transform.Position = {0.0f, 0.0f, 0.0f};
} }
@@ -327,7 +327,7 @@ namespace Game
Level& level = GetInstance().GameLevel; Level& level = GetInstance().GameLevel;
auto& staticCards = Puzzle::GetStaticPuzzleData().Cards; auto& staticCards = Puzzle::GetStaticPuzzleData().Cards;
for (int8_t y = 0; y < Data.WidthTiles / Puzzle::Config::CardSize; ++y) for (int8_t y = 0; y < Data.HeightTiles / Puzzle::Config::CardSize; ++y)
{ {
for (int8_t x = 0; x < Data.WidthTiles / Puzzle::Config::CardSize; ++x) for (int8_t x = 0; x < Data.WidthTiles / Puzzle::Config::CardSize; ++x)
{ {
@@ -337,21 +337,24 @@ namespace Game
bool IsValid = Puzzle::IsValid(card.RefCard); bool IsValid = Puzzle::IsValid(card.RefCard);
tile.EData.Visible = true; tile.EData.Visible = true;
quad.EData.Visible = IsValid; quad.EData.Visible = true;
// const Generated::StaticPuzzleCard& cData = Puzzle::GetCard(card.RefCard); tile.EData.ModelH = IsValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle;
tile.EData.ModelHandle = Vec3 cardPos = {
IsValid ? staticCards[card.RefCard.Idx].ModelHandle : staticCards[0].ModelHandle;
tile.EData.Transform.SetPosition({
(float)card.Position.X * Puzzle::Config::CardScaleWorld, (float)card.Position.X * Puzzle::Config::CardScaleWorld,
-5.0f, -5.0f,
(float)card.Position.Y * Puzzle::Config::CardScaleWorld, (float)card.Position.Y * Puzzle::Config::CardScaleWorld,
}); };
if (!IsValid)
{
cardPos = {x * Puzzle::Config::CardScaleWorld, -5.0f, y * Puzzle::Config::CardScaleWorld};
}
tile.EData.Transform.SetPosition(cardPos);
bx::mtxRotateY(tile.EData.Transform.Rotation.M, card.Rotation * bx::kPi * 0.5f); bx::mtxRotateY(tile.EData.Transform.Rotation.M, card.Rotation * bx::kPi * 0.5f);
Vec3 fw = {0, -1, 0}; Vec3 fw = {0, -1, 0};
quad.EData.Transform.SetPosition({}); quad.EData.Transform.SetPosition(fw);
quad.EData.Transform.Rotation = camTransform.Rotation; quad.EData.Transform.Rotation = {};
} }
} }
} }

View File

@@ -21,7 +21,7 @@ namespace Game
Vec4 BaseColor{0.0f, 0.0f, 0.0f, 1.0f}; Vec4 BaseColor{0.0f, 0.0f, 0.0f, 1.0f};
Transform Transform; Transform Transform;
uint16_t MaterialHandle = UINT16_MAX; uint16_t MaterialHandle = UINT16_MAX;
uint16_t ModelHandle = UINT16_MAX; Generated::ModelHandle ModelH;
bool Visible = true; bool Visible = true;
void Render(const Model* models, const Material* materials); void Render(const Model* models, const Material* materials);

View File

@@ -133,6 +133,7 @@ namespace Game
} }
LOG("Found %u models!", modelFilePathCount); LOG("Found %u models!", modelFilePathCount);
auto& inst = GetInstance();
int32_t writeI = 0; int32_t writeI = 0;
for (int32_t i = 0; i < modelFilePathCount; ++i) for (int32_t i = 0; i < modelFilePathCount; ++i)
{ {
@@ -141,11 +142,11 @@ namespace Game
Model& mod = models[writeI]; Model& mod = models[writeI];
if (LoadMesh(mod, fullPath.getCPtr(), modelFileIsBinary[i])) if (LoadMesh(mod, fullPath.getCPtr(), modelFileIsBinary[i]))
{ {
mod.AssetHandle = CrcPath(fullPath.getCPtr()); mod.Handle.Asset.Idx = CrcPath(fullPath.getCPtr());
auto& inst = GetInstance(); mod.Handle.ModelIdx = inst.DebugData.AssetCount;
if (inst.DebugData.AssetCount < inst.DebugData.MaxAssets) if (inst.DebugData.AssetCount < inst.DebugData.MaxAssets)
{ {
inst.DebugData.AssetHandles[inst.DebugData.AssetCount] = mod.AssetHandle; inst.DebugData.AssetHandles[inst.DebugData.AssetCount] = mod.Handle.Asset;
bx::strCopy(inst.DebugData.AssetHandlePaths[inst.DebugData.AssetCount], bx::strCopy(inst.DebugData.AssetHandlePaths[inst.DebugData.AssetCount],
sizeof(inst.DebugData.AssetHandlePaths[inst.DebugData.AssetCount]), sizeof(inst.DebugData.AssetHandlePaths[inst.DebugData.AssetCount]),
fullPath.getCPtr()); fullPath.getCPtr());

View File

@@ -42,8 +42,7 @@ namespace Puzzle
void LoadStaticPuzzleData() void LoadStaticPuzzleData()
{ {
Deserializer ser; Deserializer ser;
ser.Init("game/data/static/puzzle.dat"); if (ser.Init("game/data/static/puzzle.dat", "SPUZ") && ser.ReadT(StaticData))
if (ser.ReadT("SPUZ", StaticData))
{ {
LOG("Successfully loaded static puzzle data!"); LOG("Successfully loaded static puzzle data!");
} }
@@ -54,8 +53,7 @@ namespace Puzzle
{ {
auto& data = GetStaticPuzzleData(); auto& data = GetStaticPuzzleData();
Serializer ser; Serializer ser;
ser.Init("game/data/static/puzzle.dat"); if (ser.Init("game/data/static/puzzle.dat", "SPUZ") && ser.WriteT(GetStaticPuzzleData()))
if (ser.WriteT("SPUZ", GetStaticPuzzleData()))
{ {
LOG("Successfully saved static puzzle data!"); LOG("Successfully saved static puzzle data!");
} }
@@ -576,8 +574,7 @@ namespace Puzzle
char path[128]{0}; char path[128]{0};
WritePuzzleFilePath(path, sizeof(path), obj.ID); WritePuzzleFilePath(path, sizeof(path), obj.ID);
Serializer ser; Serializer ser;
ser.Init(path); if (ser.Init(path, "PZZL") && ser.WriteT(obj))
if (ser.WriteT("PZZL", obj))
{ {
LOG("Saved to %s", path); LOG("Saved to %s", path);
} }
@@ -591,33 +588,3 @@ namespace Puzzle
return isVisible; return isVisible;
} }
} // namespace Puzzle } // namespace Puzzle
namespace Generated
{
PuzPos operator+=(PuzPos lhs, const PuzPos& rhs)
{
lhs.X += rhs.X;
lhs.Y += rhs.Y;
return lhs;
}
PuzPos operator+(PuzPos lhs, const PuzPos& rhs)
{
PuzPos res = lhs;
res.X += rhs.X;
res.Y += rhs.Y;
return res;
}
PuzPos operator-=(PuzPos lhs, const PuzPos& rhs)
{
lhs.X -= rhs.X;
lhs.Y -= rhs.Y;
return lhs;
}
PuzPos operator-(PuzPos lhs, const PuzPos& rhs)
{
PuzPos res = lhs;
res.X += rhs.X;
res.Y += rhs.Y;
return res;
}
} // namespace Generated

View File

@@ -1,9 +1,8 @@
#pragma once #pragma once
#include "Serial.h"
#include <cstdint> #include <cstdint>
#include <imgui.h> #include <imgui.h>
#include "../../gen/Generated.h" #include "Gen.h"
namespace Puzzle namespace Puzzle
{ {
@@ -51,9 +50,3 @@ namespace Puzzle
}; };
bool RenderDebugUI(PuzzleData& obj); bool RenderDebugUI(PuzzleData& obj);
} // namespace Puzzle } // namespace Puzzle
namespace Generated
{
PuzPos operator+=(PuzPos lhs, const PuzPos& rhs);
PuzPos operator+(PuzPos lhs, const PuzPos& rhs);
} // namespace Generated

View File

@@ -1,32 +0,0 @@
#include "Global.h"
#include "Log.h"
#include "Serial.h"
#include "bx/bx.h"
#include "bx/file.h"
#include "bx/filepath.h"
void SerializeStruct(void* data, uint64_t size, const char* path)
{
bx::Error err;
bx::FilePath filePath{path};
bx::FileWriter writer;
if (writer.open(filePath, false, &err))
{
if (!writer.write(data, size, &err))
{
LOG_ERROR("Failed to write to file %s: %s", path, err.getMessage().getCPtr());
writer.close();
return;
}
}
else
{
LOG_ERROR("Failed to open file %s: %s", path, err.getMessage().getCPtr());
return;
}
LOG("Successful serialization");
}
void DeserializeStruct(void* data, SerializationHeader& expectedHeader, const char* path)
{
}

View File

@@ -1,32 +0,0 @@
#include <cstdint>
struct SerializationHeader
{
uint8_t _ID0 = 0;
uint8_t _ID1 = 0;
uint8_t _ID2 = 0;
uint8_t _ID3 = 0;
uint8_t HeaderVersion = 0;
uint8_t VersionNum = 0;
uint8_t Reserved0 = 0;
uint8_t Reserved1 = 0;
};
#define SER_HEADER(Version, FCC) \
SerializationHeader __Header{ \
FCC[0], \
FCC[1], \
FCC[2], \
FCC[3], \
1, \
Version, \
0, \
0, \
}; \
bool VersionMatches(uint8_t headerVersion, uint8_t versionNum) \
{ \
return headerVersion == 1 && versionNum == Version; \
}
void SerializeStruct(void* data, uint64_t size, const char* path);
void DeserializeStruct(void* data, SerializationHeader& expectedHeader, const char* path);

View File

@@ -1,14 +1,13 @@
#include "Global.h" #include "Global.h"
#include "Instance.h" #include "Instance.h"
#include "Tools.h" #include "Tools.h"
#include "bx/string.h"
#include "rendering/Rendering.h" #include "rendering/Rendering.h"
#include <imgui.h> #include <imgui.h>
namespace Tools namespace Tools
{ {
const char* GetAssetPath(uint32_t assetHandle) const char* GetAssetPath(Generated::AssetHandle assetHandle)
{ {
const auto& inst = Game::GetInstance(); const auto& inst = Game::GetInstance();
for (int32_t j = 0; j < inst.DebugData.AssetCount; ++j) for (int32_t j = 0; j < inst.DebugData.AssetCount; ++j)
@@ -21,26 +20,17 @@ namespace Tools
return "---"; return "---";
} }
void ModelDropdown(uint32_t& modelHandle) void ModelDropdown(Generated::ModelHandle& modelHandle)
{ {
auto& R = Game::GameRendering::Get(); auto& R = Game::GameRendering::Get();
const char* name = GetAssetPath(modelHandle); const char* name = GetAssetPath(modelHandle.Asset);
int32_t idx = -1;
for (int32_t i = 0; i < R.ModelCount; ++i)
{
if (R.Models[i].AssetHandle == modelHandle)
{
idx = i;
break;
}
}
if (ImGui::BeginCombo("Models", name)) if (ImGui::BeginCombo("Models", name))
{ {
for (int32_t i = 0; i < R.ModelCount; ++i) for (int32_t i = 0; i < R.ModelCount; ++i)
{ {
if (ImGui::Selectable(GetAssetPath(R.Models[i].AssetHandle), i == idx)) if (ImGui::Selectable(GetAssetPath(R.Models[i].Handle.Asset), i == modelHandle.ModelIdx))
{ {
modelHandle = i; modelHandle = R.Models[i].Handle;
} }
} }
ImGui::EndCombo(); ImGui::EndCombo();

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <cstdint> #include "Gen.h"
namespace Tools namespace Tools
{ {
void ModelDropdown(uint32_t& modelHandle); void ModelDropdown(Generated::ModelHandle& modelHandle);
} // namespace Tools } // namespace Tools

Binary file not shown.

Binary file not shown.

View File

@@ -38,6 +38,17 @@ type Mat4
}") }")
} }
type AssetHandle
{
u32 Idx Default("UINT32_MAX")
}
type ModelHandle
{
u16 ModelIdx Default("UINT16_MAX")
AssetHandle Asset
}
type PuzPos type PuzPos
{ {
i8 X i8 X
@@ -59,7 +70,8 @@ enum PuzzleElementType(u8)
type StaticPuzzleCard type StaticPuzzleCard
{ {
PuzzleElementType Elements Arr(4) PuzzleElementType Elements Arr(4)
u32 ModelHandle ModelHandle ModelHandle
} }
type StaticPuzzleCardHandle type StaticPuzzleCardHandle

View File

@@ -731,17 +731,17 @@ namespace Game
return mat; return mat;
} }
uint16_t GameRendering::GetModelHandleFromPath(const char* path) Generated::ModelHandle GameRendering::GetModelHandleFromPath(const char* path)
{ {
uint32_t AssetHandle = CrcPath(path); uint32_t AssetHandle = CrcPath(path);
for (int32_t i = 0; i < ModelCount; ++i) for (int32_t i = 0; i < ModelCount; ++i)
{ {
if (Models[i].AssetHandle == AssetHandle) if (Models[i].Handle.Asset.Idx == AssetHandle)
{ {
return i; return Models[i].Handle;
} }
} }
return 0; return {};
} }
} // namespace Game } // namespace Game

View File

@@ -1,11 +1,12 @@
#pragma once #pragma once
#include "bgfx/defines.h" #include "bgfx/defines.h"
#include "imgui.h"
#include <bgfx/bgfx.h> #include <bgfx/bgfx.h>
#include <bx/string.h> #include <bx/string.h>
#include <cstdint> #include <cstdint>
#include "../Gen.h"
#include "../Global.h" #include "../Global.h"
#include "imgui.h"
union SDL_Event; union SDL_Event;
@@ -36,7 +37,7 @@ namespace Game
bgfx::VertexBufferHandle VertexBuffer; bgfx::VertexBufferHandle VertexBuffer;
bgfx::IndexBufferHandle IndexBuffer; bgfx::IndexBufferHandle IndexBuffer;
bgfx::VertexLayout VertLayout; bgfx::VertexLayout VertLayout;
uint32_t AssetHandle = UINT16_MAX; Generated::ModelHandle Handle;
}; };
struct Material struct Material
@@ -118,6 +119,6 @@ namespace Game
void HandleEvents(); void HandleEvents();
void RenderDebugUI(); void RenderDebugUI();
void Shutdown(); void Shutdown();
uint16_t GetModelHandleFromPath(const char* path); Generated::ModelHandle GetModelHandleFromPath(const char* path);
}; };
} // namespace Game } // namespace Game

View File

@@ -8,32 +8,49 @@
namespace Generated namespace Generated
{ {
struct EmbeddedTypeDef
{
uint32_t Size = sizeof(Def::DefinitionFile);
Def::DefinitionFile Data;
};
struct Serializer struct Serializer
{ {
bx::Error Err; bx::Error Err;
bx::FilePath Path; bx::FilePath Path;
bx::FileWriter Writer; bx::FileWriter Writer;
bool Init(const bx::FilePath& path) bool Init(const bx::FilePath& path, const char* _4cc)
{ {
if (_4cc == nullptr)
{
LOG_ERROR("Provided invalid 4cc!");
return false;
}
if (path.isEmpty())
{
LOG_ERROR("Provided empty path!");
return false;
}
Path = path; Path = path;
Writer.open(path, false, &Err); if (!Writer.open(path, false, &Err))
{
LOG_ERROR("Failed to open file %s: %s", path.getCPtr(), Err.getMessage().getCPtr());
return false;
}
Writer.write(_4cc, 4, &Err);
if (!Err.isOk())
{
LOG_ERROR("Failed to write to file %s: %s", path.getCPtr(), Err.getMessage().getCPtr());
}
return Err.isOk(); return Err.isOk();
} }
template <typename T> bool WriteT(const char* _4cc, const T& data) template <typename T> bool WriteT(const T& data)
{ {
if (!Write(_4cc, 4)) return false;
uint32_t hash = data.Hash; uint32_t hash = data.Hash;
if (!Write(&hash, sizeof(hash))) return false; if (!Write(&hash, sizeof(hash))) return false;
uint32_t defSize = 0;
if (!Write(&defSize, sizeof(defSize))) return false;
// auto& definitions = GetDefinitions();
// if (!Write(&definitions, sizeof(definitions))) return false;
uint32_t size = sizeof(T); uint32_t size = sizeof(T);
if (!Write(&size, sizeof(size))) return false; if (!Write(&size, sizeof(size))) return false;
@@ -51,6 +68,11 @@ namespace Generated
{ {
Writer.close(); Writer.close();
} }
~Serializer()
{
Writer.close();
}
}; };
struct Deserializer struct Deserializer
@@ -59,11 +81,32 @@ namespace Generated
bx::FilePath Path; bx::FilePath Path;
bx::FileReader Reader; bx::FileReader Reader;
bool Init(const bx::FilePath& path) bool Init(const bx::FilePath& path, const char* _4cc)
{ {
Path = path; Path = path;
Reader.open(path, &Err); if (!Reader.open(path, &Err))
return Err.isOk(); {
LOG_ERROR("Failed to open file %s: %s", path.getCPtr(), Err.getMessage().getCPtr());
return false;
}
char read4cc[4]{0};
int32_t readAmount = Reader.read(read4cc, 4, &Err);
if (!Err.isOk())
{
LOG_ERROR("Failed to read from file %s: %s", path.getCPtr(), Err.getMessage().getCPtr());
return false;
}
if (readAmount < 4)
{
LOG_ERROR("Failed to read enough bytes from file %s", path.getCPtr());
return false;
}
if (read4cc[0] != _4cc[0] || read4cc[1] != _4cc[1] || read4cc[2] != _4cc[2] || read4cc[3] != _4cc[3])
{
LOG_ERROR("4CC mismatch! %.4s != %.4s", read4cc, _4cc);
return false;
}
return true;
} }
bool Read(void* data, uint32_t size) bool Read(void* data, uint32_t size)
@@ -73,40 +116,44 @@ namespace Generated
return Err.isOk(); return Err.isOk();
} }
template <typename T> bool ReadT(const char* _4cc, T& data) template <typename T> bool ReadT(T& data)
{ {
char magic[5]{0};
if (!Read(magic, 4)) return false;
bx::StringView given{_4cc, 4};
bx::StringView loaded{magic, 4};
if (bx::strCmp(given, loaded) != 0)
{
LOG_ERROR("Magic mismatch! %s != %s", _4cc, magic);
return false;
}
uint32_t hash = 0; uint32_t hash = 0;
if (!Read(&hash, sizeof(hash))) return false; if (!Read(&hash, sizeof(hash))) return false;
uint32_t defSize = 0;
if (!Read(&defSize, sizeof(defSize))) return false;
if (data.Hash != hash) if (data.Hash != hash)
{ {
LOG_ERROR("Hash mismatch! %u != %u", data.Hash, hash); LOG_WARN("Hash mismatch! %u != %u", data.Hash, hash);
return false;
// TODO: figure out upgrade data
data = {};
return true;
}
else
{
LOG("Hash match!");
// Skip definitions, we know they match
Reader.seek(defSize);
uint32_t size = 0;
if (!Read(&size, sizeof(size))) return false;
if (sizeof(T) != size)
{
LOG_ERROR("Size mismatch! %u != %u", sizeof(T), size);
return false;
}
if (!Load(&data, 1, *this))
{
LOG_ERROR("Failed to load: %s", Err.getMessage().getCPtr());
return false;
}
} }
uint32_t size = 0;
if (!Read(&size, sizeof(size))) return false;
if (sizeof(T) != size)
{
LOG_ERROR("Size mismatch! %u != %u", sizeof(T), size);
return false;
}
if (!Load(&data, 1, *this))
{
LOG_ERROR("Failed to load: %s", Err.getMessage().getCPtr());
return false;
}
return true; return true;
} }
@@ -114,6 +161,11 @@ namespace Generated
{ {
Reader.close(); Reader.close();
} }
~Deserializer()
{
Reader.close();
}
}; };
template <typename T> bool Save(const T* obj, uint32_t count, Serializer& serializer); template <typename T> bool Save(const T* obj, uint32_t count, Serializer& serializer);