generate metadata in code
This commit is contained in:
@@ -32,7 +32,7 @@ namespace Gen
|
|||||||
constexpr char StructHeader2[] =
|
constexpr char StructHeader2[] =
|
||||||
R"END( struct %s
|
R"END( struct %s
|
||||||
{
|
{
|
||||||
static constexpr uint32_t Hash = %u;
|
static constexpr uint16_t TypeIdx = %u;
|
||||||
)END";
|
)END";
|
||||||
|
|
||||||
constexpr char StructField4[] =
|
constexpr char StructField4[] =
|
||||||
@@ -46,8 +46,8 @@ namespace Gen
|
|||||||
constexpr char EnumHeader4[] =
|
constexpr char EnumHeader4[] =
|
||||||
R"END( struct %s
|
R"END( struct %s
|
||||||
{
|
{
|
||||||
|
static constexpr uint16_t EnumIdx = %u;
|
||||||
static constexpr int32_t EntryCount = %u;
|
static constexpr int32_t EntryCount = %u;
|
||||||
static constexpr uint32_t Hash = %u;
|
|
||||||
enum Enum : %s
|
enum Enum : %s
|
||||||
{
|
{
|
||||||
)END";
|
)END";
|
||||||
@@ -112,6 +112,44 @@ namespace Gen
|
|||||||
return isOk;
|
return isOk;
|
||||||
}
|
}
|
||||||
)END";
|
)END";
|
||||||
|
|
||||||
|
constexpr char MetadataStart1[] = R"END(
|
||||||
|
namespace Meta {
|
||||||
|
struct TypeDef
|
||||||
|
{
|
||||||
|
uint32_t Size = 0;
|
||||||
|
uint32_t Hash = 0;
|
||||||
|
const char Name[64]{"Dummy"};
|
||||||
|
uint16_t ChildCount = 0;
|
||||||
|
uint16_t ChildIndices[64]{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EnumDef
|
||||||
|
{
|
||||||
|
uint32_t Size = 0;
|
||||||
|
uint32_t Hash = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MetadataTable
|
||||||
|
{
|
||||||
|
TypeDef TypeDefinitions[%u]
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char MetadataTypeEntry5[] = R"END( TypeDef{sizeof(%s), %u, "%s", %u, {%s}},
|
||||||
|
)END";
|
||||||
|
constexpr char MetadataEnumStart1[] = R"END( };
|
||||||
|
EnumDef EnumDefinitions[%u]
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
constexpr char MetadataEnumEntry2[] = R"END( EnumDef{sizeof(%s::Enum), %u},
|
||||||
|
)END";
|
||||||
|
constexpr char MetadataEnd[] = R"END( };
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr MetadataTable Metadata;
|
||||||
|
}
|
||||||
|
)END";
|
||||||
} // namespace WriteTemplates
|
} // namespace WriteTemplates
|
||||||
|
|
||||||
void CppFileWriter::InitBuffer(WriteBuffer& buf)
|
void CppFileWriter::InitBuffer(WriteBuffer& buf)
|
||||||
@@ -164,26 +202,25 @@ void CppFileWriter::WriteInternal(WriteBuffer& buf, const char* templateStr, va_
|
|||||||
buf.WrittenBytes += bx::vsnprintf(&buf.Data[buf.WrittenBytes], BufferRequestSize, templateStr, args);
|
buf.WrittenBytes += bx::vsnprintf(&buf.Data[buf.WrittenBytes], BufferRequestSize, templateStr, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppFileWriter::PrintTypeName(char* buf,
|
void CppFileWriter::PrintTypeName(char* buf, int32_t bufSize, Def::TypeRef type, const Def::DefinitionFile& definitions)
|
||||||
int32_t bufSize,
|
|
||||||
const Def::FieldType& type,
|
|
||||||
const Def::DefinitionFile& definitions)
|
|
||||||
{
|
{
|
||||||
if (type.FieldKind == Def::EFieldType::Native)
|
if (buf == nullptr || bufSize == 0 || !IsValid(type))
|
||||||
{
|
{
|
||||||
if (int32_t(type.Native) < Gen::KnownType::EntryCount)
|
LOG_ERROR(0, "Invalid PrintTypeName call!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type.FieldKind == Def::EFieldType::DefinedClass)
|
||||||
|
{
|
||||||
|
auto& t = definitions.Types[type.TypeIdx];
|
||||||
|
if ((uint32_t)t.TypeFlags & (uint32_t)Def::ETypeFlags::IsNative)
|
||||||
{
|
{
|
||||||
bx::strCopy(buf, bufSize, Gen::KnownType::CName[size_t(type.Native)]);
|
bx::strCopy(buf, bufSize, t.NativeCName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR(0, "Unknown native type index: %u", type.Native);
|
bx::strCopy(buf, bufSize, t.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type.FieldKind == Def::EFieldType::DefinedClass)
|
|
||||||
{
|
|
||||||
bx::strCopy(buf, bufSize, definitions.Types[type.TypeIdx].Name);
|
|
||||||
}
|
|
||||||
else if (type.FieldKind == Def::EFieldType::DefinedEnum)
|
else if (type.FieldKind == Def::EFieldType::DefinedEnum)
|
||||||
{
|
{
|
||||||
bx::strCopy(buf, bufSize, definitions.Enums[type.TypeIdx].Name);
|
bx::strCopy(buf, bufSize, definitions.Enums[type.TypeIdx].Name);
|
||||||
@@ -197,11 +234,15 @@ void CppFileWriter::WriteEnums(const Def::DefinitionFile& definitions)
|
|||||||
{
|
{
|
||||||
const Def::Enum& e = definitions.Enums[enumIdx];
|
const Def::Enum& e = definitions.Enums[enumIdx];
|
||||||
|
|
||||||
Write(WriteTemplates::EnumHeader4,
|
if (!IsValid(e.EnumType))
|
||||||
e.Name,
|
{
|
||||||
e.EntryCount,
|
LOG_ERROR(0, "Invalid enum type (enum %i)", enumIdx);
|
||||||
e.Hash,
|
continue;
|
||||||
Gen::KnownType::CName[(int32_t)e.EnumType.Native]);
|
}
|
||||||
|
|
||||||
|
char Buf[Def::MaxNameLength]{0};
|
||||||
|
PrintTypeName(Buf, sizeof(Buf), e.EnumType, definitions);
|
||||||
|
Write(WriteTemplates::EnumHeader4, e.Name, enumIdx, e.EntryCount, Buf);
|
||||||
for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx)
|
for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx)
|
||||||
{
|
{
|
||||||
Write(WriteTemplates::EnumField1, e.EntryNames[entryIdx]);
|
Write(WriteTemplates::EnumField1, e.EntryNames[entryIdx]);
|
||||||
@@ -230,15 +271,16 @@ void CppFileWriter::WriteTypes(const Def::DefinitionFile& definitions)
|
|||||||
for (int32_t typeIdx = 0; typeIdx < definitions.TypeCount; ++typeIdx)
|
for (int32_t typeIdx = 0; typeIdx < definitions.TypeCount; ++typeIdx)
|
||||||
{
|
{
|
||||||
const Def::Type& t = definitions.Types[typeIdx];
|
const Def::Type& t = definitions.Types[typeIdx];
|
||||||
|
if ((uint32_t)t.TypeFlags & (uint32_t)Def::ETypeFlags::IsNative) continue;
|
||||||
|
|
||||||
Write(WriteTemplates::StructHeader2, t.Name, t.Hash);
|
Write(WriteTemplates::StructHeader2, t.Name, typeIdx);
|
||||||
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
||||||
{
|
{
|
||||||
char Type[64]{0};
|
char Type[64]{0};
|
||||||
PrintTypeName(Type, sizeof(Type), t.FieldTypes[fieldIdx], definitions);
|
PrintTypeName(Type, sizeof(Type), t.FieldTypes[fieldIdx], definitions);
|
||||||
char Array[32]{0};
|
char Array[32]{0};
|
||||||
uint32_t ArraySize = t.FieldArraySizes[fieldIdx];
|
uint32_t ArraySize = t.FieldArraySizes[fieldIdx];
|
||||||
if (ArraySize > 0)
|
if (ArraySize > 0 && ArraySize != UINT32_MAX)
|
||||||
{
|
{
|
||||||
bx::snprintf(Array, sizeof(Array), "[%u]", ArraySize);
|
bx::snprintf(Array, sizeof(Array), "[%u]", ArraySize);
|
||||||
}
|
}
|
||||||
@@ -254,6 +296,11 @@ void CppFileWriter::WriteSaveLoadMethods(const Def::DefinitionFile& definitions)
|
|||||||
for (int32_t enumIdx = 0; enumIdx < definitions.EnumCount; ++enumIdx)
|
for (int32_t enumIdx = 0; enumIdx < definitions.EnumCount; ++enumIdx)
|
||||||
{
|
{
|
||||||
const Def::Enum& e = definitions.Enums[enumIdx];
|
const Def::Enum& e = definitions.Enums[enumIdx];
|
||||||
|
if (!IsValid(e.EnumType))
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Invalid enum!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
bx::snprintf(nameBuf, sizeof(nameBuf), "%s::Enum", e.Name);
|
bx::snprintf(nameBuf, sizeof(nameBuf), "%s::Enum", e.Name);
|
||||||
PrintTypeName(fieldBuf, sizeof(fieldBuf), e.EnumType, definitions);
|
PrintTypeName(fieldBuf, sizeof(fieldBuf), e.EnumType, definitions);
|
||||||
|
|
||||||
@@ -268,13 +315,16 @@ void CppFileWriter::WriteSaveLoadMethods(const Def::DefinitionFile& definitions)
|
|||||||
WriteCpp(WriteTemplates::LoadFuncBodyEnum2, fieldBuf, fieldBuf);
|
WriteCpp(WriteTemplates::LoadFuncBodyEnum2, fieldBuf, fieldBuf);
|
||||||
WriteCpp(WriteTemplates::LoadFuncBodyEnd);
|
WriteCpp(WriteTemplates::LoadFuncBodyEnd);
|
||||||
}
|
}
|
||||||
for (int32_t typeIdx = 0; typeIdx < definitions.TypeCount; ++typeIdx)
|
for (uint16_t typeIdx = 0; typeIdx < definitions.TypeCount; ++typeIdx)
|
||||||
{
|
{
|
||||||
const Def::Type& t = definitions.Types[typeIdx];
|
const Def::Type& t = definitions.Types[typeIdx];
|
||||||
Write(WriteTemplates::SaveFuncHeader1, t.Name);
|
char typeName[Def::MaxNameLength]{0};
|
||||||
Write(WriteTemplates::LoadFuncHeader1, t.Name);
|
PrintTypeName(typeName, sizeof(typeName), {typeIdx, Def::EFieldType::DefinedClass}, definitions);
|
||||||
|
|
||||||
WriteCpp(WriteTemplates::SaveFuncBodyStart1, t.Name);
|
Write(WriteTemplates::SaveFuncHeader1, typeName);
|
||||||
|
Write(WriteTemplates::LoadFuncHeader1, typeName);
|
||||||
|
|
||||||
|
WriteCpp(WriteTemplates::SaveFuncBodyStart1, typeName);
|
||||||
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
||||||
{
|
{
|
||||||
WriteCpp(WriteTemplates::SaveFuncBodyType3,
|
WriteCpp(WriteTemplates::SaveFuncBodyType3,
|
||||||
@@ -284,7 +334,7 @@ void CppFileWriter::WriteSaveLoadMethods(const Def::DefinitionFile& definitions)
|
|||||||
}
|
}
|
||||||
WriteCpp(WriteTemplates::SaveFuncBodyEnd);
|
WriteCpp(WriteTemplates::SaveFuncBodyEnd);
|
||||||
|
|
||||||
WriteCpp(WriteTemplates::LoadFuncBodyStart1, t.Name);
|
WriteCpp(WriteTemplates::LoadFuncBodyStart1, typeName);
|
||||||
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
||||||
{
|
{
|
||||||
WriteCpp(WriteTemplates::LoadFuncBodyType3,
|
WriteCpp(WriteTemplates::LoadFuncBodyType3,
|
||||||
@@ -295,6 +345,33 @@ void CppFileWriter::WriteSaveLoadMethods(const Def::DefinitionFile& definitions)
|
|||||||
WriteCpp(WriteTemplates::LoadFuncBodyEnd);
|
WriteCpp(WriteTemplates::LoadFuncBodyEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppFileWriter::WriteMetadata(const Def::DefinitionFile& definitions)
|
||||||
|
{
|
||||||
|
Write(WriteTemplates::MetadataStart1, definitions.TypeCount);
|
||||||
|
for (uint16_t i = 0; i < definitions.TypeCount; ++i)
|
||||||
|
{
|
||||||
|
auto& type = definitions.Types[i];
|
||||||
|
char fieldStr[256]{0};
|
||||||
|
for (int32_t j = 0; j < type.FieldCount; ++j)
|
||||||
|
{
|
||||||
|
if (j != 0) bx::strCat(fieldStr, sizeof(fieldStr), ", ");
|
||||||
|
char numBuf[8]{0};
|
||||||
|
bx::snprintf(numBuf, sizeof(numBuf), "%u", type.FieldTypes[j].TypeIdx);
|
||||||
|
bx::strCat(fieldStr, sizeof(fieldStr), numBuf);
|
||||||
|
}
|
||||||
|
char typeStr[Def::MaxNameLength]{0};
|
||||||
|
PrintTypeName(typeStr, sizeof(typeStr), {i, Def::EFieldType::DefinedClass}, definitions);
|
||||||
|
Write(WriteTemplates::MetadataTypeEntry5, typeStr, type.Hash, type.Name, type.FieldCount, fieldStr);
|
||||||
|
}
|
||||||
|
Write(WriteTemplates::MetadataEnumStart1, definitions.EnumCount);
|
||||||
|
for (int32_t i = 0; i < definitions.EnumCount; ++i)
|
||||||
|
{
|
||||||
|
Write(WriteTemplates::MetadataEnumEntry2, definitions.Enums[i].Name, definitions.Enums[i].Hash);
|
||||||
|
}
|
||||||
|
Write(WriteTemplates::MetadataEnd);
|
||||||
|
}
|
||||||
|
|
||||||
void CppFileWriter::GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions)
|
void CppFileWriter::GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions)
|
||||||
{
|
{
|
||||||
LOG(0, "Generating output files...");
|
LOG(0, "Generating output files...");
|
||||||
@@ -307,6 +384,7 @@ void CppFileWriter::GenerateCpp(const bx::FilePath& outDir, const Def::Definitio
|
|||||||
WriteEnums(definitions);
|
WriteEnums(definitions);
|
||||||
WriteTypes(definitions);
|
WriteTypes(definitions);
|
||||||
WriteSaveLoadMethods(definitions);
|
WriteSaveLoadMethods(definitions);
|
||||||
|
WriteMetadata(definitions);
|
||||||
Write(WriteTemplates::FileEnd);
|
Write(WriteTemplates::FileEnd);
|
||||||
WriteCpp(WriteTemplates::FileEnd);
|
WriteCpp(WriteTemplates::FileEnd);
|
||||||
|
|
||||||
@@ -334,36 +412,3 @@ void CppFileWriter::WriteCpp(const char* templateStr, ...)
|
|||||||
WriteInternal(CppWrite, templateStr, args);
|
WriteInternal(CppWrite, templateStr, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppFileWriter::WriteTypeDataFile(const bx::FilePath& outDir, const Def::DefinitionFile& definitions)
|
|
||||||
{
|
|
||||||
constexpr const char _4cc[] = "TDAT";
|
|
||||||
constexpr uint32_t version = 1;
|
|
||||||
bx::FilePath typeDataFilePath = outDir;
|
|
||||||
typeDataFilePath.join("TypeData.bin");
|
|
||||||
|
|
||||||
bx::Error err;
|
|
||||||
bx::FileWriter writer;
|
|
||||||
if (!writer.open(typeDataFilePath, false, &err))
|
|
||||||
{
|
|
||||||
LOG_ERROR(0, "Failed to open type data file to write: %s", err.getMessage().getCPtr());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uint32_t size = sizeof(definitions);
|
|
||||||
writer.write(_4cc, 4, &err);
|
|
||||||
if (!err.isOk())
|
|
||||||
{
|
|
||||||
LOG_ERROR(0, "Failed to write type data: %s", err.getMessage().getCPtr());
|
|
||||||
writer.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
writer.write(&version, sizeof(version), &err);
|
|
||||||
writer.write(&size, sizeof(size), &err);
|
|
||||||
writer.write(&definitions, sizeof(definitions), &err);
|
|
||||||
if (!err.isOk())
|
|
||||||
{
|
|
||||||
LOG_ERROR(0, "Failed to write type data: %s", err.getMessage().getCPtr());
|
|
||||||
}
|
|
||||||
writer.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ struct CppFileWriter
|
|||||||
void WriteInternal(WriteBuffer& buf, const char* templateStr, va_list args);
|
void WriteInternal(WriteBuffer& buf, const char* templateStr, va_list args);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type, const Def::DefinitionFile& definitions);
|
void PrintTypeName(char* buf, int32_t bufSize, Def::TypeRef type, const Def::DefinitionFile& definitions);
|
||||||
void WriteEnums(const Def::DefinitionFile& definitions);
|
void WriteEnums(const Def::DefinitionFile& definitions);
|
||||||
void WriteTypes(const Def::DefinitionFile& definitions);
|
void WriteTypes(const Def::DefinitionFile& definitions);
|
||||||
void WriteSaveLoadMethods(const Def::DefinitionFile& definitions);
|
void WriteSaveLoadMethods(const Def::DefinitionFile& definitions);
|
||||||
|
void WriteMetadata(const Def::DefinitionFile& definitions);
|
||||||
|
|
||||||
void GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions);
|
void GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions);
|
||||||
void Write(const char* templateStr, ...);
|
void Write(const char* templateStr, ...);
|
||||||
void WriteCpp(const char* templateStr, ...);
|
void WriteCpp(const char* templateStr, ...);
|
||||||
void WriteTypeDataFile(const bx::FilePath& outDir, const Def::DefinitionFile& definitions);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
#include "Def.h"
|
|
||||||
|
|
||||||
#define INST(T) \
|
|
||||||
template bool Save<T>(const T* obj, uint32_t count, Serializer& serializer); \
|
|
||||||
template bool Load<T>(T * obj, uint32_t count, Deserializer & serializer);
|
|
||||||
|
|
||||||
namespace Gen
|
|
||||||
{
|
|
||||||
template <typename T> bool Save(const 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> bool Load(T* obj, uint32_t count, Deserializer& serializer)
|
|
||||||
{
|
|
||||||
bool isOk = true;
|
|
||||||
for (uint32_t i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
|
|
||||||
}
|
|
||||||
return isOk;
|
|
||||||
}
|
|
||||||
|
|
||||||
INST(uint8_t)
|
|
||||||
INST(uint16_t)
|
|
||||||
INST(uint32_t)
|
|
||||||
INST(uint64_t)
|
|
||||||
INST(int8_t)
|
|
||||||
INST(int16_t)
|
|
||||||
INST(int32_t)
|
|
||||||
INST(int64_t)
|
|
||||||
INST(float)
|
|
||||||
INST(double)
|
|
||||||
INST(bool)
|
|
||||||
INST(char)
|
|
||||||
} // namespace Gen
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "../TypeDef.h"
|
|
||||||
// #include "../game/Log.h"
|
|
||||||
|
|
||||||
#include "bx/string.h"
|
|
||||||
#include <bx/file.h>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#ifndef LOG_ERROR
|
|
||||||
#define LOG_ERROR(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Gen
|
|
||||||
{
|
|
||||||
struct EmbeddedTypeDef
|
|
||||||
{
|
|
||||||
uint32_t Size = sizeof(Def::DefinitionFile);
|
|
||||||
Def::DefinitionFile Data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Serializer
|
|
||||||
{
|
|
||||||
bx::Error Err;
|
|
||||||
bx::FilePath Path;
|
|
||||||
bx::FileWriter Writer;
|
|
||||||
|
|
||||||
bool Init(const bx::FilePath& path)
|
|
||||||
{
|
|
||||||
Path = path;
|
|
||||||
Writer.open(path, false, &Err);
|
|
||||||
return Err.isOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> bool WriteT(const char* _4cc, const T& data)
|
|
||||||
{
|
|
||||||
if (!Write(_4cc, 4)) return false;
|
|
||||||
|
|
||||||
uint32_t hash = data.Hash;
|
|
||||||
if (!Write(&hash, sizeof(hash))) return false;
|
|
||||||
|
|
||||||
uint32_t size = sizeof(T);
|
|
||||||
if (!Write(&size, sizeof(size))) return false;
|
|
||||||
|
|
||||||
return Save(&data, 1, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Write(const void* data, uint32_t size)
|
|
||||||
{
|
|
||||||
Writer.write(data, size, &Err);
|
|
||||||
if (!Err.isOk()) LOG_ERROR("Write error: %s", Err.getMessage().getCPtr());
|
|
||||||
return Err.isOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Finish()
|
|
||||||
{
|
|
||||||
Writer.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Deserializer
|
|
||||||
{
|
|
||||||
bx::Error Err;
|
|
||||||
bx::FilePath Path;
|
|
||||||
bx::FileReader Reader;
|
|
||||||
|
|
||||||
bool Init(const bx::FilePath& path)
|
|
||||||
{
|
|
||||||
Path = path;
|
|
||||||
Reader.open(path, &Err);
|
|
||||||
return Err.isOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Read(void* data, uint32_t size)
|
|
||||||
{
|
|
||||||
Reader.read(data, size, &Err);
|
|
||||||
if (!Err.isOk()) LOG_ERROR("Read error: %s", Err.getMessage().getCPtr());
|
|
||||||
return Err.isOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> bool ReadT(const char* _4cc, 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;
|
|
||||||
if (!Read(&hash, sizeof(hash))) return false;
|
|
||||||
if (data.Hash != hash)
|
|
||||||
{
|
|
||||||
LOG_ERROR("Hash mismatch! %u != %u", data.Hash, hash);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Finish()
|
|
||||||
{
|
|
||||||
Reader.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> bool Save(const T* obj, uint32_t count, Serializer& serializer);
|
|
||||||
template <typename T> bool Load(T* obj, uint32_t count, Deserializer& serializer);
|
|
||||||
} // namespace Gen
|
|
||||||
@@ -8,7 +8,7 @@ namespace Gen
|
|||||||
bool isOk = true;
|
bool isOk = true;
|
||||||
for (uint32_t i = 0; i < count; ++i)
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
auto val = (int32_t)obj[i];
|
auto val = (uint8_t)obj[i];
|
||||||
isOk = Save(&val, 1, serializer) && isOk;
|
isOk = Save(&val, 1, serializer) && isOk;
|
||||||
}
|
}
|
||||||
return isOk;
|
return isOk;
|
||||||
@@ -18,11 +18,203 @@ namespace Gen
|
|||||||
bool isOk = true;
|
bool isOk = true;
|
||||||
for (uint32_t i = 0; i < count; ++i)
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
int32_t& val = (int32_t&)obj[i];
|
uint8_t& val = (uint8_t&)obj[i];
|
||||||
isOk = Load(&val, 1, serializer) && isOk;
|
isOk = Load(&val, 1, serializer) && isOk;
|
||||||
}
|
}
|
||||||
return 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(int8_t* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const int16_t* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(int16_t* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const int32_t* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(int32_t* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const int64_t* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(int64_t* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const uint8_t* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(uint8_t* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const uint16_t* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(uint16_t* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const uint32_t* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(uint32_t* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const uint64_t* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(uint64_t* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const bool* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(bool* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const float* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(float* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const double* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(double* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const char* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(char* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
bool Save(const Test* obj, uint32_t count, Serializer& serializer)
|
bool Save(const Test* obj, uint32_t count, Serializer& serializer)
|
||||||
{
|
{
|
||||||
bool isOk = true;
|
bool isOk = true;
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ namespace Gen
|
|||||||
struct Deserializer;
|
struct Deserializer;
|
||||||
struct KnownType
|
struct KnownType
|
||||||
{
|
{
|
||||||
|
static constexpr uint16_t EnumIdx = 0;
|
||||||
static constexpr int32_t EntryCount = 12;
|
static constexpr int32_t EntryCount = 12;
|
||||||
static constexpr uint32_t Hash = 2024002654;
|
enum Enum : uint8_t
|
||||||
enum Enum : int32_t
|
|
||||||
{
|
{
|
||||||
i8,
|
i8,
|
||||||
i16,
|
i16,
|
||||||
@@ -57,12 +57,12 @@ namespace Gen
|
|||||||
};
|
};
|
||||||
struct Test
|
struct Test
|
||||||
{
|
{
|
||||||
static constexpr uint32_t Hash = 273256278;
|
static constexpr uint16_t TypeIdx = 12;
|
||||||
uint32_t Number = {};
|
uint32_t Number = {};
|
||||||
};
|
};
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
static constexpr uint32_t Hash = 992460010;
|
static constexpr uint16_t TypeIdx = 13;
|
||||||
uint32_t Width = {};
|
uint32_t Width = {};
|
||||||
uint32_t Height = {};
|
uint32_t Height = {};
|
||||||
char StrTest[3] = {};
|
char StrTest[3] = {};
|
||||||
@@ -70,8 +70,76 @@ namespace Gen
|
|||||||
};
|
};
|
||||||
bool Save(const KnownType::Enum* obj, uint32_t count, Serializer& serializer);
|
bool Save(const KnownType::Enum* obj, uint32_t count, Serializer& serializer);
|
||||||
bool Load(KnownType::Enum* obj, uint32_t count, Deserializer& serializer);
|
bool Load(KnownType::Enum* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const int8_t* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(int8_t* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const int16_t* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(int16_t* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const int32_t* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(int32_t* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const int64_t* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(int64_t* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const uint8_t* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(uint8_t* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const uint16_t* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(uint16_t* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const uint32_t* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(uint32_t* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const uint64_t* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(uint64_t* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const bool* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(bool* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const float* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(float* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const double* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(double* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const char* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(char* obj, uint32_t count, Deserializer& serializer);
|
||||||
bool Save(const Test* obj, uint32_t count, Serializer& serializer);
|
bool Save(const Test* obj, uint32_t count, Serializer& serializer);
|
||||||
bool Load(Test* obj, uint32_t count, Deserializer& serializer);
|
bool Load(Test* obj, uint32_t count, Deserializer& serializer);
|
||||||
bool Save(const Texture* obj, uint32_t count, Serializer& serializer);
|
bool Save(const Texture* obj, uint32_t count, Serializer& serializer);
|
||||||
bool Load(Texture* obj, uint32_t count, Deserializer& serializer);
|
bool Load(Texture* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
|
||||||
|
namespace Meta {
|
||||||
|
struct TypeDef
|
||||||
|
{
|
||||||
|
uint32_t Size = 0;
|
||||||
|
uint32_t Hash = 0;
|
||||||
|
const char Name[64]{"Dummy"};
|
||||||
|
uint16_t ChildCount = 0;
|
||||||
|
uint16_t ChildIndices[64]{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EnumDef
|
||||||
|
{
|
||||||
|
uint32_t Size = 0;
|
||||||
|
uint32_t Hash = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MetadataTable
|
||||||
|
{
|
||||||
|
TypeDef TypeDefinitions[14]
|
||||||
|
{
|
||||||
|
TypeDef{sizeof(int8_t), 0, "i8", 0, {}},
|
||||||
|
TypeDef{sizeof(int16_t), 1, "i16", 0, {}},
|
||||||
|
TypeDef{sizeof(int32_t), 2, "i32", 0, {}},
|
||||||
|
TypeDef{sizeof(int64_t), 3, "i64", 0, {}},
|
||||||
|
TypeDef{sizeof(uint8_t), 4, "u8", 0, {}},
|
||||||
|
TypeDef{sizeof(uint16_t), 5, "u16", 0, {}},
|
||||||
|
TypeDef{sizeof(uint32_t), 6, "u32", 0, {}},
|
||||||
|
TypeDef{sizeof(uint64_t), 7, "u64", 0, {}},
|
||||||
|
TypeDef{sizeof(bool), 8, "b", 0, {}},
|
||||||
|
TypeDef{sizeof(float), 9, "f32", 0, {}},
|
||||||
|
TypeDef{sizeof(double), 10, "f64", 0, {}},
|
||||||
|
TypeDef{sizeof(char), 11, "str", 0, {}},
|
||||||
|
TypeDef{sizeof(Test), 273256278, "Test", 1, {6}},
|
||||||
|
TypeDef{sizeof(Texture), 992460010, "Texture", 4, {6, 6, 11, 12}},
|
||||||
|
};
|
||||||
|
EnumDef EnumDefinitions[1]
|
||||||
|
{
|
||||||
|
EnumDef{sizeof(KnownType::Enum), 2983807453},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr MetadataTable Metadata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -2,8 +2,8 @@
|
|||||||
#include "Gen/Generated.h"
|
#include "Gen/Generated.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
#include "MiniDef.h"
|
#include "MiniDef.h"
|
||||||
|
|
||||||
#include "TypeDef.h"
|
#include "TypeDef.h"
|
||||||
|
|
||||||
#include "bx/hash.h"
|
#include "bx/hash.h"
|
||||||
#include "bx/string.h"
|
#include "bx/string.h"
|
||||||
#include <bx/filepath.h>
|
#include <bx/filepath.h>
|
||||||
@@ -114,6 +114,8 @@ Parser::Result Parser::Parse()
|
|||||||
{
|
{
|
||||||
ReadPtr = &Buffer[0];
|
ReadPtr = &Buffer[0];
|
||||||
Parser::Result Res = Parser::OK;
|
Parser::Result Res = Parser::OK;
|
||||||
|
CHECK(LoadNativeTypes());
|
||||||
|
|
||||||
while (Res == Parser::OK)
|
while (Res == Parser::OK)
|
||||||
{
|
{
|
||||||
Res = SkipWhitespace();
|
Res = SkipWhitespace();
|
||||||
@@ -136,6 +138,7 @@ Parser::Result Parser::Parse()
|
|||||||
Parser::Result Parser::HandleFileStart()
|
Parser::Result Parser::HandleFileStart()
|
||||||
{
|
{
|
||||||
Result Res = OK;
|
Result Res = OK;
|
||||||
|
|
||||||
if (CmpAdvance("type", Res, true) && Res == OK)
|
if (CmpAdvance("type", Res, true) && Res == OK)
|
||||||
{
|
{
|
||||||
return HandleType();
|
return HandleType();
|
||||||
@@ -152,6 +155,20 @@ Parser::Result Parser::HandleFileStart()
|
|||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::LoadNativeTypes()
|
||||||
|
{
|
||||||
|
for (int32_t i = 0; i < Gen::KnownType::EntryCount; ++i)
|
||||||
|
{
|
||||||
|
auto& t = Definitions.Types[i];
|
||||||
|
t.Hash = i; // TODO!
|
||||||
|
bx::strCopy(t.Name, sizeof(t.Name), Gen::KnownType::EntryNames[i]);
|
||||||
|
bx::strCopy(t.NativeCName, sizeof(t.NativeCName), Gen::KnownType::CName[i]);
|
||||||
|
t.TypeFlags = Def::ETypeFlags::IsNative;
|
||||||
|
++Definitions.TypeCount;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
Parser::Result Parser::HandleType()
|
Parser::Result Parser::HandleType()
|
||||||
{
|
{
|
||||||
Result Res = OK;
|
Result Res = OK;
|
||||||
@@ -200,6 +217,13 @@ Parser::Result Parser::HandleType()
|
|||||||
CHECK(ReadUint(t.FieldArraySizes[t.FieldCount]));
|
CHECK(ReadUint(t.FieldArraySizes[t.FieldCount]));
|
||||||
CHECK(ExpectChar(")"));
|
CHECK(ExpectChar(")"));
|
||||||
}
|
}
|
||||||
|
else if (CmpAdvance("ArrDynamic", Res, true) && Res == Result::OK)
|
||||||
|
{
|
||||||
|
CHECK(ExpectChar("("));
|
||||||
|
CHECK(ReadUint(t.FieldArraySizes[t.FieldCount]));
|
||||||
|
t.FieldFlags[t.FieldCount] = Def::ETypeFieldFlags::DynamicArray;
|
||||||
|
CHECK(ExpectChar(")"));
|
||||||
|
}
|
||||||
else if (CmpAdvance("Default", Res, true) && Res == OK)
|
else if (CmpAdvance("Default", Res, true) && Res == OK)
|
||||||
{
|
{
|
||||||
CHECK(ExpectChar("("));
|
CHECK(ExpectChar("("));
|
||||||
@@ -249,12 +273,15 @@ Parser::Result Parser::HandleEnum()
|
|||||||
if (CmpAdvance("(", Res) && Res == OK)
|
if (CmpAdvance("(", Res) && Res == OK)
|
||||||
{
|
{
|
||||||
CHECK(SkipWhitespace());
|
CHECK(SkipWhitespace());
|
||||||
Def::FieldType field;
|
CHECK(ReadDefinedFieldType(e.EnumType));
|
||||||
CHECK(ReadNativeFieldType(field));
|
|
||||||
CHECK(SkipWhitespace());
|
CHECK(SkipWhitespace());
|
||||||
CHECK(ExpectChar(")"));
|
CHECK(ExpectChar(")"));
|
||||||
CHECK(SkipWhitespace());
|
CHECK(SkipWhitespace());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e.EnumType = {(uint16_t)Gen::KnownType::i32, Def::EFieldType::DefinedClass};
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(ExpectChar("{"));
|
CHECK(ExpectChar("{"));
|
||||||
CHECK(SkipWhitespace());
|
CHECK(SkipWhitespace());
|
||||||
@@ -338,29 +365,13 @@ Parser::Result Parser::ReadTypeToken()
|
|||||||
{
|
{
|
||||||
Result Res = OK;
|
Result Res = OK;
|
||||||
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
||||||
if (ReadNativeFieldType(t.FieldTypes[t.FieldCount]) == OK) return OK;
|
|
||||||
if (ReadDefinedFieldType(t.FieldTypes[t.FieldCount]) == OK) return OK;
|
if (ReadDefinedFieldType(t.FieldTypes[t.FieldCount]) == OK) return OK;
|
||||||
LOG_ERROR(Line, "Unknown type token!");
|
LOG_ERROR(Line, "Unknown type token!");
|
||||||
ErrorLine();
|
ErrorLine();
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Result Parser::ReadNativeFieldType(Def::FieldType& FieldT)
|
Parser::Result Parser::ReadDefinedFieldType(Def::TypeRef& FieldT)
|
||||||
{
|
|
||||||
Result Res = OK;
|
|
||||||
for (int32_t i = 0; i < Gen::KnownType::EntryCount; ++i)
|
|
||||||
{
|
|
||||||
if (CmpAdvance(Gen::KnownType::EntryNames[i], Res, true) && Res == OK)
|
|
||||||
{
|
|
||||||
FieldT.FieldKind = Def::EFieldType::Native;
|
|
||||||
FieldT.Native = Gen::KnownType::Enum(i);
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
Parser::Result Parser::ReadDefinedFieldType(Def::FieldType& FieldT)
|
|
||||||
{
|
{
|
||||||
Result Res = OK;
|
Result Res = OK;
|
||||||
for (uint16_t i = 0; i < Definitions.TypeCount; ++i)
|
for (uint16_t i = 0; i < Definitions.TypeCount; ++i)
|
||||||
@@ -437,11 +448,7 @@ uint32_t Parser::CalculateTypeHash(const Def::Type& t)
|
|||||||
hash.add(t.FieldArraySizes[i]);
|
hash.add(t.FieldArraySizes[i]);
|
||||||
|
|
||||||
Def::EFieldType fieldType = t.FieldTypes[i].FieldKind;
|
Def::EFieldType fieldType = t.FieldTypes[i].FieldKind;
|
||||||
if (fieldType == Def::EFieldType::Native)
|
if (fieldType == Def::EFieldType::DefinedClass)
|
||||||
{
|
|
||||||
hash.add(t.FieldTypes[i].Native);
|
|
||||||
}
|
|
||||||
else if (fieldType == Def::EFieldType::DefinedClass)
|
|
||||||
{
|
{
|
||||||
Def::Type& dependType = Definitions.Types[t.FieldTypes[i].TypeIdx];
|
Def::Type& dependType = Definitions.Types[t.FieldTypes[i].TypeIdx];
|
||||||
if (dependType.Hash == 0)
|
if (dependType.Hash == 0)
|
||||||
@@ -456,7 +463,7 @@ uint32_t Parser::CalculateTypeHash(const Def::Type& t)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR(0, "TODO!");
|
LOG_ERROR(Line, "TODO!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hash.end();
|
return hash.end();
|
||||||
@@ -466,9 +473,14 @@ void Parser::CalculateHashes()
|
|||||||
for (int32_t i = 0; i < Definitions.EnumCount; ++i)
|
for (int32_t i = 0; i < Definitions.EnumCount; ++i)
|
||||||
{
|
{
|
||||||
Def::Enum& e = Definitions.Enums[i];
|
Def::Enum& e = Definitions.Enums[i];
|
||||||
|
if (!IsValid(e.EnumType))
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Invalid enum type at idx %i", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
bx::HashMurmur2A hash;
|
bx::HashMurmur2A hash;
|
||||||
hash.begin();
|
hash.begin();
|
||||||
hash.add(e.EnumType.Native);
|
hash.add(Definitions.Types[e.EnumType.TypeIdx].Hash); // TODO: add enum entries?
|
||||||
e.Hash = hash.end();
|
e.Hash = hash.end();
|
||||||
}
|
}
|
||||||
for (int32_t i = 0; i < Definitions.TypeCount; ++i)
|
for (int32_t i = 0; i < Definitions.TypeCount; ++i)
|
||||||
@@ -519,9 +531,5 @@ int main(int argc, const char** argv)
|
|||||||
FileParser.CalculateHashes();
|
FileParser.CalculateHashes();
|
||||||
Writer.GenerateCpp(outPath, FileParser.Definitions);
|
Writer.GenerateCpp(outPath, FileParser.Definitions);
|
||||||
|
|
||||||
LOG(0, "Writing type data file");
|
|
||||||
Writer.WriteTypeDataFile(outPath, FileParser.Definitions);
|
|
||||||
LOG(0, "Finished writing type data file!");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,12 +86,12 @@ class Parser
|
|||||||
Result ExpectChar(bx::StringView expect);
|
Result ExpectChar(bx::StringView expect);
|
||||||
Result Advance(int32_t Amount);
|
Result Advance(int32_t Amount);
|
||||||
Result HandleFileStart();
|
Result HandleFileStart();
|
||||||
|
Result LoadNativeTypes();
|
||||||
Result HandleType();
|
Result HandleType();
|
||||||
Result HandleEnum();
|
Result HandleEnum();
|
||||||
Result ReadName(char* Target);
|
Result ReadName(char* Target);
|
||||||
Result ReadUint(uint32_t& Out);
|
Result ReadUint(uint32_t& Out);
|
||||||
Result ReadNativeFieldType(Def::FieldType& FieldT);
|
Result ReadDefinedFieldType(Def::TypeRef& FieldT);
|
||||||
Result ReadDefinedFieldType(Def::FieldType& FieldT);
|
|
||||||
Result ReadTypeToken();
|
Result ReadTypeToken();
|
||||||
Result ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx);
|
Result ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Gen/Generated.h"
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace Def
|
namespace Def
|
||||||
@@ -7,33 +6,52 @@ namespace Def
|
|||||||
constexpr int32_t MaxNameLength = 64;
|
constexpr int32_t MaxNameLength = 64;
|
||||||
constexpr int32_t MaxFields = 64;
|
constexpr int32_t MaxFields = 64;
|
||||||
constexpr int32_t MaxExtraEnumFields = 2;
|
constexpr int32_t MaxExtraEnumFields = 2;
|
||||||
enum class EFieldType
|
|
||||||
|
enum class EFieldType : uint8_t
|
||||||
{
|
{
|
||||||
Native,
|
|
||||||
DefinedClass,
|
DefinedClass,
|
||||||
DefinedEnum
|
DefinedEnum
|
||||||
};
|
};
|
||||||
struct FieldType
|
|
||||||
|
enum class ETypeFlags : uint32_t
|
||||||
{
|
{
|
||||||
EFieldType FieldKind = EFieldType::Native;
|
None = 0,
|
||||||
Gen::KnownType::Enum Native = Gen::KnownType::Enum::i32;
|
IsNative = 1 << 0,
|
||||||
uint16_t TypeIdx = UINT16_MAX;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ETypeFieldFlags : uint32_t
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
DynamicArray = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TypeRef
|
||||||
|
{
|
||||||
|
uint16_t TypeIdx = UINT16_MAX;
|
||||||
|
EFieldType FieldKind = EFieldType::DefinedClass;
|
||||||
|
};
|
||||||
|
inline bool IsValid(TypeRef ref)
|
||||||
|
{
|
||||||
|
return ref.TypeIdx != UINT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
struct Type
|
struct Type
|
||||||
{
|
{
|
||||||
int32_t FieldCount = 0;
|
int32_t FieldCount = 0;
|
||||||
FieldType FieldTypes[MaxFields];
|
TypeRef FieldTypes[MaxFields];
|
||||||
char FieldNames[MaxFields][MaxNameLength];
|
char FieldNames[MaxFields][MaxNameLength];
|
||||||
uint32_t FieldArraySizes[MaxFields]{0};
|
uint32_t FieldArraySizes[MaxFields]{0};
|
||||||
char FieldValues[MaxFields][128]{0};
|
char FieldValues[MaxFields][128]{0};
|
||||||
|
ETypeFlags TypeFlags = ETypeFlags::None;
|
||||||
|
ETypeFieldFlags FieldFlags[MaxFields]{ETypeFieldFlags::None};
|
||||||
char Name[MaxNameLength]{0};
|
char Name[MaxNameLength]{0};
|
||||||
|
char NativeCName[MaxNameLength]{0};
|
||||||
uint32_t Hash = 0;
|
uint32_t Hash = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Enum
|
struct Enum
|
||||||
{
|
{
|
||||||
FieldType EnumType;
|
TypeRef EnumType;
|
||||||
int32_t EntryCount = 0;
|
int32_t EntryCount = 0;
|
||||||
char EntryNames[MaxFields][MaxNameLength];
|
char EntryNames[MaxFields][MaxNameLength];
|
||||||
int32_t ExtraStringFieldCount = 0;
|
int32_t ExtraStringFieldCount = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user