Files
PuzGame/src/gen/Generated.cpp
2025-05-25 13:19:50 +02:00

2635 lines
112 KiB
C++

#include "Def.h"
#include "Generated.h"
namespace Gen
{
bool Save(const PuzzleElementType::Enum* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
auto val = (uint8_t)obj[i];
isOk = Save(&val, 1, serializer) && isOk;
}
return isOk;
}
bool Load(PuzzleElementType::Enum* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
uint8_t& val = (uint8_t&)obj[i];
isOk = Load(&val, 1, serializer) && isOk;
}
return isOk;
}
bool Save(const PlacedPuzzleCardFlags::Enum* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
auto val = (uint8_t)obj[i];
isOk = Save(&val, 1, serializer) && isOk;
}
return isOk;
}
bool Load(PlacedPuzzleCardFlags::Enum* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
uint8_t& val = (uint8_t&)obj[i];
isOk = Load(&val, 1, serializer) && isOk;
}
return isOk;
}
bool Save(const EMaterial::Enum* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
auto val = (int32_t)obj[i];
isOk = Save(&val, 1, serializer) && isOk;
}
return isOk;
}
bool Load(EMaterial::Enum* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
int32_t& val = (int32_t&)obj[i];
isOk = Load(&val, 1, serializer) && isOk;
}
return isOk;
}
bool Save(const int8_t* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(int8_t* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const int16_t* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(int16_t* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const int32_t* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(int32_t* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const int64_t* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(int64_t* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const uint8_t* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(uint8_t* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const uint16_t* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(uint16_t* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const uint32_t* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(uint32_t* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const uint64_t* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(uint64_t* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const bool* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(bool* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const float* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(float* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const double* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(double* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const char* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Load(char* obj, uint32_t count, Deserializer& serializer)
{
bool isOk = true;
for (int32_t i = 0; i < count; ++i)
{
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
}
return isOk;
}
bool Save(const Vec2* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].x, 1, serializer) && isOk;
isOk = Save(&obj[i].y, 1, serializer) && isOk;
}
return isOk;
}
bool Load(Vec2* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[Vec2::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[Vec2::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].x, 1, serializer) && isOk;
isOk = Load(&obj[i].y, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec2, x);
}
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec2, y);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "x") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "y") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const Vec3* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].x, 1, serializer) && isOk;
isOk = Save(&obj[i].y, 1, serializer) && isOk;
isOk = Save(&obj[i].z, 1, serializer) && isOk;
}
return isOk;
}
bool Load(Vec3* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[Vec3::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[Vec3::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].x, 1, serializer) && isOk;
isOk = Load(&obj[i].y, 1, serializer) && isOk;
isOk = Load(&obj[i].z, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec3, x);
}
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec3, y);
}
if (bx::strCmp(memberName, "z") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec3, z);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "x") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "y") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "z") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const Vec4* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].x, 1, serializer) && isOk;
isOk = Save(&obj[i].y, 1, serializer) && isOk;
isOk = Save(&obj[i].z, 1, serializer) && isOk;
isOk = Save(&obj[i].w, 1, serializer) && isOk;
}
return isOk;
}
bool Load(Vec4* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[Vec4::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[Vec4::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].x, 1, serializer) && isOk;
isOk = Load(&obj[i].y, 1, serializer) && isOk;
isOk = Load(&obj[i].z, 1, serializer) && isOk;
isOk = Load(&obj[i].w, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "x") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec4, x);
}
if (bx::strCmp(memberName, "y") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec4, y);
}
if (bx::strCmp(memberName, "z") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec4, z);
}
if (bx::strCmp(memberName, "w") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Vec4, w);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "x") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "y") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "z") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "w") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const Mat3* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(obj[i].M, 9, serializer) && isOk;
}
return isOk;
}
bool Load(Mat3* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[Mat3::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[Mat3::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(obj[i].M, 9, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "M") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Mat3, M);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "M") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 9, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const Mat4* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(obj[i].M, 16, serializer) && isOk;
}
return isOk;
}
bool Load(Mat4* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[Mat4::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[Mat4::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(obj[i].M, 16, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "M") == 0 && bx::strCmp(memberTypeName, "f32") == 0)
{
WriteDestinations[i] = offsetof(Mat4, M);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "M") == 0)
{
auto* fieldPtr = reinterpret_cast<float*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 16, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const Transform* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].M, 1, serializer) && isOk;
isOk = Save(&obj[i].MI, 1, serializer) && isOk;
isOk = Save(&obj[i].Position, 1, serializer) && isOk;
isOk = Save(&obj[i].Rotation, 1, serializer) && isOk;
isOk = Save(&obj[i].Scale, 1, serializer) && isOk;
}
return isOk;
}
bool Load(Transform* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[Transform::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[Transform::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].M, 1, serializer) && isOk;
isOk = Load(&obj[i].MI, 1, serializer) && isOk;
isOk = Load(&obj[i].Position, 1, serializer) && isOk;
isOk = Load(&obj[i].Rotation, 1, serializer) && isOk;
isOk = Load(&obj[i].Scale, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "M") == 0 && bx::strCmp(memberTypeName, "Mat4") == 0)
{
WriteDestinations[i] = offsetof(Transform, M);
}
if (bx::strCmp(memberName, "MI") == 0 && bx::strCmp(memberTypeName, "Mat4") == 0)
{
WriteDestinations[i] = offsetof(Transform, MI);
}
if (bx::strCmp(memberName, "Position") == 0 && bx::strCmp(memberTypeName, "Vec3") == 0)
{
WriteDestinations[i] = offsetof(Transform, Position);
}
if (bx::strCmp(memberName, "Rotation") == 0 && bx::strCmp(memberTypeName, "Mat4") == 0)
{
WriteDestinations[i] = offsetof(Transform, Rotation);
}
if (bx::strCmp(memberName, "Scale") == 0 && bx::strCmp(memberTypeName, "Vec3") == 0)
{
WriteDestinations[i] = offsetof(Transform, Scale);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "M") == 0)
{
auto* fieldPtr = reinterpret_cast<Mat4*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "MI") == 0)
{
auto* fieldPtr = reinterpret_cast<Mat4*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Position") == 0)
{
auto* fieldPtr = reinterpret_cast<Vec3*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Rotation") == 0)
{
auto* fieldPtr = reinterpret_cast<Mat4*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Scale") == 0)
{
auto* fieldPtr = reinterpret_cast<Vec3*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const AssetHandle* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].Idx, 1, serializer) && isOk;
}
return isOk;
}
bool Load(AssetHandle* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[AssetHandle::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[AssetHandle::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].Idx, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "Idx") == 0 && bx::strCmp(memberTypeName, "u32") == 0)
{
WriteDestinations[i] = offsetof(AssetHandle, Idx);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "Idx") == 0)
{
auto* fieldPtr = reinterpret_cast<uint32_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const ModelHandle* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].ModelIdx, 1, serializer) && isOk;
isOk = Save(&obj[i].Asset, 1, serializer) && isOk;
}
return isOk;
}
bool Load(ModelHandle* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[ModelHandle::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[ModelHandle::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].ModelIdx, 1, serializer) && isOk;
isOk = Load(&obj[i].Asset, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "ModelIdx") == 0 && bx::strCmp(memberTypeName, "u16") == 0)
{
WriteDestinations[i] = offsetof(ModelHandle, ModelIdx);
}
if (bx::strCmp(memberName, "Asset") == 0 && bx::strCmp(memberTypeName, "AssetHandle") == 0)
{
WriteDestinations[i] = offsetof(ModelHandle, Asset);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "ModelIdx") == 0)
{
auto* fieldPtr = reinterpret_cast<uint16_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Asset") == 0)
{
auto* fieldPtr = reinterpret_cast<AssetHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const TextureHandle* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].TextureIdx, 1, serializer) && isOk;
isOk = Save(&obj[i].Asset, 1, serializer) && isOk;
}
return isOk;
}
bool Load(TextureHandle* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[TextureHandle::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[TextureHandle::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].TextureIdx, 1, serializer) && isOk;
isOk = Load(&obj[i].Asset, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "TextureIdx") == 0 && bx::strCmp(memberTypeName, "u16") == 0)
{
WriteDestinations[i] = offsetof(TextureHandle, TextureIdx);
}
if (bx::strCmp(memberName, "Asset") == 0 && bx::strCmp(memberTypeName, "AssetHandle") == 0)
{
WriteDestinations[i] = offsetof(TextureHandle, Asset);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "TextureIdx") == 0)
{
auto* fieldPtr = reinterpret_cast<uint16_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Asset") == 0)
{
auto* fieldPtr = reinterpret_cast<AssetHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const PuzPos* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].X, 1, serializer) && isOk;
isOk = Save(&obj[i].Y, 1, serializer) && isOk;
}
return isOk;
}
bool Load(PuzPos* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[PuzPos::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[PuzPos::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].X, 1, serializer) && isOk;
isOk = Load(&obj[i].Y, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "X") == 0 && bx::strCmp(memberTypeName, "i8") == 0)
{
WriteDestinations[i] = offsetof(PuzPos, X);
}
if (bx::strCmp(memberName, "Y") == 0 && bx::strCmp(memberTypeName, "i8") == 0)
{
WriteDestinations[i] = offsetof(PuzPos, Y);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "X") == 0)
{
auto* fieldPtr = reinterpret_cast<int8_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Y") == 0)
{
auto* fieldPtr = reinterpret_cast<int8_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const CardSocket* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].Model, 1, serializer) && isOk;
isOk = Save(&obj[i].ConnectionDirection, 1, serializer) && isOk;
}
return isOk;
}
bool Load(CardSocket* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[CardSocket::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[CardSocket::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].Model, 1, serializer) && isOk;
isOk = Load(&obj[i].ConnectionDirection, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "Model") == 0 && bx::strCmp(memberTypeName, "ModelHandle") == 0)
{
WriteDestinations[i] = offsetof(CardSocket, Model);
}
if (bx::strCmp(memberName, "ConnectionDirection") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(CardSocket, ConnectionDirection);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "Model") == 0)
{
auto* fieldPtr = reinterpret_cast<ModelHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "ConnectionDirection") == 0)
{
auto* fieldPtr = reinterpret_cast<uint8_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const StaticPuzzleCard* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(obj[i].Elements, 4, serializer) && isOk;
isOk = Save(&obj[i].BaseModelHandle, 1, serializer) && isOk;
isOk = Save(&obj[i].NorthCoverHandle, 1, serializer) && isOk;
isOk = Save(&obj[i].EastCoverHandle, 1, serializer) && isOk;
isOk = Save(&obj[i].SouthCoverHandle, 1, serializer) && isOk;
isOk = Save(&obj[i].WestCoverHandle, 1, serializer) && isOk;
isOk = Save(obj[i].Sockets, 16, serializer) && isOk;
isOk = Save(&obj[i].ModelTextureHandle, 1, serializer) && isOk;
isOk = Save(&obj[i].BoardTextureHandle, 1, serializer) && isOk;
}
return isOk;
}
bool Load(StaticPuzzleCard* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[StaticPuzzleCard::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[StaticPuzzleCard::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(obj[i].Elements, 4, serializer) && isOk;
isOk = Load(&obj[i].BaseModelHandle, 1, serializer) && isOk;
isOk = Load(&obj[i].NorthCoverHandle, 1, serializer) && isOk;
isOk = Load(&obj[i].EastCoverHandle, 1, serializer) && isOk;
isOk = Load(&obj[i].SouthCoverHandle, 1, serializer) && isOk;
isOk = Load(&obj[i].WestCoverHandle, 1, serializer) && isOk;
isOk = Load(obj[i].Sockets, 16, serializer) && isOk;
isOk = Load(&obj[i].ModelTextureHandle, 1, serializer) && isOk;
isOk = Load(&obj[i].BoardTextureHandle, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "Elements") == 0 && bx::strCmp(memberTypeName, "PuzzleElementType") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, Elements);
}
if (bx::strCmp(memberName, "BaseModelHandle") == 0 && bx::strCmp(memberTypeName, "ModelHandle") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, BaseModelHandle);
}
if (bx::strCmp(memberName, "NorthCoverHandle") == 0 && bx::strCmp(memberTypeName, "ModelHandle") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, NorthCoverHandle);
}
if (bx::strCmp(memberName, "EastCoverHandle") == 0 && bx::strCmp(memberTypeName, "ModelHandle") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, EastCoverHandle);
}
if (bx::strCmp(memberName, "SouthCoverHandle") == 0 && bx::strCmp(memberTypeName, "ModelHandle") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, SouthCoverHandle);
}
if (bx::strCmp(memberName, "WestCoverHandle") == 0 && bx::strCmp(memberTypeName, "ModelHandle") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, WestCoverHandle);
}
if (bx::strCmp(memberName, "Sockets") == 0 && bx::strCmp(memberTypeName, "CardSocket") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, Sockets);
}
if (bx::strCmp(memberName, "ModelTextureHandle") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, ModelTextureHandle);
}
if (bx::strCmp(memberName, "BoardTextureHandle") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCard, BoardTextureHandle);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "Elements") == 0)
{
auto* fieldPtr = reinterpret_cast<PuzzleElementType::Enum*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 4, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "BaseModelHandle") == 0)
{
auto* fieldPtr = reinterpret_cast<ModelHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "NorthCoverHandle") == 0)
{
auto* fieldPtr = reinterpret_cast<ModelHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "EastCoverHandle") == 0)
{
auto* fieldPtr = reinterpret_cast<ModelHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "SouthCoverHandle") == 0)
{
auto* fieldPtr = reinterpret_cast<ModelHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "WestCoverHandle") == 0)
{
auto* fieldPtr = reinterpret_cast<ModelHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Sockets") == 0)
{
auto* fieldPtr = reinterpret_cast<CardSocket*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 16, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "ModelTextureHandle") == 0)
{
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "BoardTextureHandle") == 0)
{
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const StaticPuzzleCardHandle* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].Idx, 1, serializer) && isOk;
}
return isOk;
}
bool Load(StaticPuzzleCardHandle* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[StaticPuzzleCardHandle::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[StaticPuzzleCardHandle::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].Idx, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "Idx") == 0 && bx::strCmp(memberTypeName, "u16") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleCardHandle, Idx);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "Idx") == 0)
{
auto* fieldPtr = reinterpret_cast<uint16_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const PuzzleVisualSettings* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].TileBaseColor, 1, serializer) && isOk;
isOk = Save(&obj[i].TileDotColor, 1, serializer) && isOk;
isOk = Save(&obj[i].Test, 1, serializer) && isOk;
isOk = Save(&obj[i].DisabledCardTint, 1, serializer) && isOk;
}
return isOk;
}
bool Load(PuzzleVisualSettings* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[PuzzleVisualSettings::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[PuzzleVisualSettings::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].TileBaseColor, 1, serializer) && isOk;
isOk = Load(&obj[i].TileDotColor, 1, serializer) && isOk;
isOk = Load(&obj[i].Test, 1, serializer) && isOk;
isOk = Load(&obj[i].DisabledCardTint, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "TileBaseColor") == 0 && bx::strCmp(memberTypeName, "Vec4") == 0)
{
WriteDestinations[i] = offsetof(PuzzleVisualSettings, TileBaseColor);
}
if (bx::strCmp(memberName, "TileDotColor") == 0 && bx::strCmp(memberTypeName, "Vec4") == 0)
{
WriteDestinations[i] = offsetof(PuzzleVisualSettings, TileDotColor);
}
if (bx::strCmp(memberName, "Test") == 0 && bx::strCmp(memberTypeName, "Vec3") == 0)
{
WriteDestinations[i] = offsetof(PuzzleVisualSettings, Test);
}
if (bx::strCmp(memberName, "DisabledCardTint") == 0 && bx::strCmp(memberTypeName, "Vec4") == 0)
{
WriteDestinations[i] = offsetof(PuzzleVisualSettings, DisabledCardTint);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "TileBaseColor") == 0)
{
auto* fieldPtr = reinterpret_cast<Vec4*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "TileDotColor") == 0)
{
auto* fieldPtr = reinterpret_cast<Vec4*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Test") == 0)
{
auto* fieldPtr = reinterpret_cast<Vec3*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "DisabledCardTint") == 0)
{
auto* fieldPtr = reinterpret_cast<Vec4*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const StaticPuzzleData* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(obj[i].Cards, 64, serializer) && isOk;
isOk = Save(&obj[i].Visuals, 1, serializer) && isOk;
}
return isOk;
}
bool Load(StaticPuzzleData* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[StaticPuzzleData::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[StaticPuzzleData::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(obj[i].Cards, 64, serializer) && isOk;
isOk = Load(&obj[i].Visuals, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "Cards") == 0 && bx::strCmp(memberTypeName, "StaticPuzzleCard") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleData, Cards);
}
if (bx::strCmp(memberName, "Visuals") == 0 && bx::strCmp(memberTypeName, "PuzzleVisualSettings") == 0)
{
WriteDestinations[i] = offsetof(StaticPuzzleData, Visuals);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "Cards") == 0)
{
auto* fieldPtr = reinterpret_cast<StaticPuzzleCard*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 64, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Visuals") == 0)
{
auto* fieldPtr = reinterpret_cast<PuzzleVisualSettings*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const PuzzleCardStack* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].RefCard, 1, serializer) && isOk;
isOk = Save(&obj[i].MaxAvailableCount, 1, serializer) && isOk;
isOk = Save(&obj[i].UsedCount, 1, serializer) && isOk;
}
return isOk;
}
bool Load(PuzzleCardStack* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[PuzzleCardStack::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[PuzzleCardStack::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].RefCard, 1, serializer) && isOk;
isOk = Load(&obj[i].MaxAvailableCount, 1, serializer) && isOk;
isOk = Load(&obj[i].UsedCount, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "RefCard") == 0 && bx::strCmp(memberTypeName, "StaticPuzzleCardHandle") == 0)
{
WriteDestinations[i] = offsetof(PuzzleCardStack, RefCard);
}
if (bx::strCmp(memberName, "MaxAvailableCount") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PuzzleCardStack, MaxAvailableCount);
}
if (bx::strCmp(memberName, "UsedCount") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PuzzleCardStack, UsedCount);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "RefCard") == 0)
{
auto* fieldPtr = reinterpret_cast<StaticPuzzleCardHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "MaxAvailableCount") == 0)
{
auto* fieldPtr = reinterpret_cast<uint8_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "UsedCount") == 0)
{
auto* fieldPtr = reinterpret_cast<uint8_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const PlacedPuzzleCard* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].RefCard, 1, serializer) && isOk;
isOk = Save(&obj[i].Position, 1, serializer) && isOk;
isOk = Save(&obj[i].Rotation, 1, serializer) && isOk;
isOk = Save(&obj[i].Flags, 1, serializer) && isOk;
}
return isOk;
}
bool Load(PlacedPuzzleCard* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[PlacedPuzzleCard::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[PlacedPuzzleCard::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].RefCard, 1, serializer) && isOk;
isOk = Load(&obj[i].Position, 1, serializer) && isOk;
isOk = Load(&obj[i].Rotation, 1, serializer) && isOk;
isOk = Load(&obj[i].Flags, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "RefCard") == 0 && bx::strCmp(memberTypeName, "StaticPuzzleCardHandle") == 0)
{
WriteDestinations[i] = offsetof(PlacedPuzzleCard, RefCard);
}
if (bx::strCmp(memberName, "Position") == 0 && bx::strCmp(memberTypeName, "PuzPos") == 0)
{
WriteDestinations[i] = offsetof(PlacedPuzzleCard, Position);
}
if (bx::strCmp(memberName, "Rotation") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PlacedPuzzleCard, Rotation);
}
if (bx::strCmp(memberName, "Flags") == 0 && bx::strCmp(memberTypeName, "PlacedPuzzleCardFlags") == 0)
{
WriteDestinations[i] = offsetof(PlacedPuzzleCard, Flags);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "RefCard") == 0)
{
auto* fieldPtr = reinterpret_cast<StaticPuzzleCardHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Position") == 0)
{
auto* fieldPtr = reinterpret_cast<PuzPos*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Rotation") == 0)
{
auto* fieldPtr = reinterpret_cast<uint8_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Flags") == 0)
{
auto* fieldPtr = reinterpret_cast<PlacedPuzzleCardFlags::Enum*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const PuzzleData* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].ID, 1, serializer) && isOk;
isOk = Save(obj[i].PuzzleName, 64, serializer) && isOk;
isOk = Save(&obj[i].WidthTiles, 1, serializer) && isOk;
isOk = Save(&obj[i].HeightTiles, 1, serializer) && isOk;
isOk = Save(&obj[i].AvailableCardCount, 1, serializer) && isOk;
isOk = Save(obj[i].AvailableCards, 16, serializer) && isOk;
isOk = Save(obj[i].PlacedCards, 256, serializer) && isOk;
isOk = Save(obj[i].InitialPlacedCards, 256, serializer) && isOk;
isOk = Save(obj[i].BackgroundTiles, 1024, serializer) && isOk;
isOk = Save(&obj[i].GoalPositionCount, 1, serializer) && isOk;
isOk = Save(obj[i].GoalPositions, 16, serializer) && isOk;
}
return isOk;
}
bool Load(PuzzleData* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[PuzzleData::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[PuzzleData::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].ID, 1, serializer) && isOk;
isOk = Load(obj[i].PuzzleName, 64, serializer) && isOk;
isOk = Load(&obj[i].WidthTiles, 1, serializer) && isOk;
isOk = Load(&obj[i].HeightTiles, 1, serializer) && isOk;
isOk = Load(&obj[i].AvailableCardCount, 1, serializer) && isOk;
isOk = Load(obj[i].AvailableCards, 16, serializer) && isOk;
isOk = Load(obj[i].PlacedCards, 256, serializer) && isOk;
isOk = Load(obj[i].InitialPlacedCards, 256, serializer) && isOk;
isOk = Load(obj[i].BackgroundTiles, 1024, serializer) && isOk;
isOk = Load(&obj[i].GoalPositionCount, 1, serializer) && isOk;
isOk = Load(obj[i].GoalPositions, 16, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "ID") == 0 && bx::strCmp(memberTypeName, "u16") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, ID);
}
if (bx::strCmp(memberName, "PuzzleName") == 0 && bx::strCmp(memberTypeName, "str") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, PuzzleName);
}
if (bx::strCmp(memberName, "WidthTiles") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, WidthTiles);
}
if (bx::strCmp(memberName, "HeightTiles") == 0 && bx::strCmp(memberTypeName, "u8") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, HeightTiles);
}
if (bx::strCmp(memberName, "AvailableCardCount") == 0 && bx::strCmp(memberTypeName, "u32") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, AvailableCardCount);
}
if (bx::strCmp(memberName, "AvailableCards") == 0 && bx::strCmp(memberTypeName, "PuzzleCardStack") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, AvailableCards);
}
if (bx::strCmp(memberName, "PlacedCards") == 0 && bx::strCmp(memberTypeName, "PlacedPuzzleCard") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, PlacedCards);
}
if (bx::strCmp(memberName, "InitialPlacedCards") == 0 && bx::strCmp(memberTypeName, "PlacedPuzzleCard") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, InitialPlacedCards);
}
if (bx::strCmp(memberName, "BackgroundTiles") == 0 && bx::strCmp(memberTypeName, "PuzzleElementType") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, BackgroundTiles);
}
if (bx::strCmp(memberName, "GoalPositionCount") == 0 && bx::strCmp(memberTypeName, "u32") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, GoalPositionCount);
}
if (bx::strCmp(memberName, "GoalPositions") == 0 && bx::strCmp(memberTypeName, "PuzPos") == 0)
{
WriteDestinations[i] = offsetof(PuzzleData, GoalPositions);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "ID") == 0)
{
auto* fieldPtr = reinterpret_cast<uint16_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "PuzzleName") == 0)
{
auto* fieldPtr = reinterpret_cast<char*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 64, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "WidthTiles") == 0)
{
auto* fieldPtr = reinterpret_cast<uint8_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "HeightTiles") == 0)
{
auto* fieldPtr = reinterpret_cast<uint8_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "AvailableCardCount") == 0)
{
auto* fieldPtr = reinterpret_cast<uint32_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "AvailableCards") == 0)
{
auto* fieldPtr = reinterpret_cast<PuzzleCardStack*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 16, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "PlacedCards") == 0)
{
auto* fieldPtr = reinterpret_cast<PlacedPuzzleCard*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 256, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "InitialPlacedCards") == 0)
{
auto* fieldPtr = reinterpret_cast<PlacedPuzzleCard*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 256, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "BackgroundTiles") == 0)
{
auto* fieldPtr = reinterpret_cast<PuzzleElementType::Enum*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1024, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "GoalPositionCount") == 0)
{
auto* fieldPtr = reinterpret_cast<uint32_t*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "GoalPositions") == 0)
{
auto* fieldPtr = reinterpret_cast<PuzPos*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 16, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const SavedEntityRenderData* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].BaseColor, 1, serializer) && isOk;
isOk = Save(&obj[i].HighlightColor, 1, serializer) && isOk;
isOk = Save(&obj[i].TF, 1, serializer) && isOk;
isOk = Save(&obj[i].Material, 1, serializer) && isOk;
isOk = Save(&obj[i].Texture, 1, serializer) && isOk;
isOk = Save(&obj[i].Model, 1, serializer) && isOk;
isOk = Save(&obj[i].Visible, 1, serializer) && isOk;
}
return isOk;
}
bool Load(SavedEntityRenderData* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[SavedEntityRenderData::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[SavedEntityRenderData::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].BaseColor, 1, serializer) && isOk;
isOk = Load(&obj[i].HighlightColor, 1, serializer) && isOk;
isOk = Load(&obj[i].TF, 1, serializer) && isOk;
isOk = Load(&obj[i].Material, 1, serializer) && isOk;
isOk = Load(&obj[i].Texture, 1, serializer) && isOk;
isOk = Load(&obj[i].Model, 1, serializer) && isOk;
isOk = Load(&obj[i].Visible, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "BaseColor") == 0 && bx::strCmp(memberTypeName, "Vec4") == 0)
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, BaseColor);
}
if (bx::strCmp(memberName, "HighlightColor") == 0 && bx::strCmp(memberTypeName, "Vec4") == 0)
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, HighlightColor);
}
if (bx::strCmp(memberName, "TF") == 0 && bx::strCmp(memberTypeName, "Transform") == 0)
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, TF);
}
if (bx::strCmp(memberName, "Material") == 0 && bx::strCmp(memberTypeName, "EMaterial") == 0)
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, Material);
}
if (bx::strCmp(memberName, "Texture") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, Texture);
}
if (bx::strCmp(memberName, "Model") == 0 && bx::strCmp(memberTypeName, "ModelHandle") == 0)
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, Model);
}
if (bx::strCmp(memberName, "Visible") == 0 && bx::strCmp(memberTypeName, "b") == 0)
{
WriteDestinations[i] = offsetof(SavedEntityRenderData, Visible);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "BaseColor") == 0)
{
auto* fieldPtr = reinterpret_cast<Vec4*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "HighlightColor") == 0)
{
auto* fieldPtr = reinterpret_cast<Vec4*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "TF") == 0)
{
auto* fieldPtr = reinterpret_cast<Transform*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Material") == 0)
{
auto* fieldPtr = reinterpret_cast<EMaterial::Enum*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Texture") == 0)
{
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Model") == 0)
{
auto* fieldPtr = reinterpret_cast<ModelHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "Visible") == 0)
{
auto* fieldPtr = reinterpret_cast<bool*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
bool Save(const SavedPlayerConfig* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].TabletBackgroundRenderData, 1, serializer) && isOk;
isOk = Save(&obj[i].TabletStatusRenderData, 1, serializer) && isOk;
isOk = Save(&obj[i].TabletStatusNotSolvedTexture, 1, serializer) && isOk;
isOk = Save(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk;
isOk = Save(&obj[i].TabletResetRenderData, 1, serializer) && isOk;
}
return isOk;
}
bool Load(SavedPlayerConfig* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[SavedPlayerConfig::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[SavedPlayerConfig::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].TabletBackgroundRenderData, 1, serializer) && isOk;
isOk = Load(&obj[i].TabletStatusRenderData, 1, serializer) && isOk;
isOk = Load(&obj[i].TabletStatusNotSolvedTexture, 1, serializer) && isOk;
isOk = Load(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk;
isOk = Load(&obj[i].TabletResetRenderData, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
*obj = {};
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "TabletBackgroundRenderData") == 0 && bx::strCmp(memberTypeName, "SavedEntityRenderData") == 0)
{
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletBackgroundRenderData);
}
if (bx::strCmp(memberName, "TabletStatusRenderData") == 0 && bx::strCmp(memberTypeName, "SavedEntityRenderData") == 0)
{
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusRenderData);
}
if (bx::strCmp(memberName, "TabletStatusNotSolvedTexture") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
{
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusNotSolvedTexture);
}
if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
{
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusSolvedTexture);
}
if (bx::strCmp(memberName, "TabletResetRenderData") == 0 && bx::strCmp(memberTypeName, "SavedEntityRenderData") == 0)
{
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletResetRenderData);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "TabletBackgroundRenderData") == 0)
{
auto* fieldPtr = reinterpret_cast<SavedEntityRenderData*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "TabletStatusRenderData") == 0)
{
auto* fieldPtr = reinterpret_cast<SavedEntityRenderData*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "TabletStatusNotSolvedTexture") == 0)
{
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0)
{
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "TabletResetRenderData") == 0)
{
auto* fieldPtr = reinterpret_cast<SavedEntityRenderData*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
}