save works!

This commit is contained in:
Asuro
2025-03-10 22:45:15 +01:00
parent ff00119e5b
commit c7377c3452
11 changed files with 538 additions and 217 deletions

View File

@@ -1,8 +1,10 @@
#include "CppGen.h"
#include "Logging.h"
#include "TypeDef.h"
#include "bx/string.h"
#include <bx/file.h>
#include <cstdarg>
#include <memoryapi.h>
#include <winnt.h>
@@ -11,10 +13,15 @@
namespace WriteTemplates
{
constexpr char FileHeader[] =
constexpr char FileHeaderStart[] =
R"END(#pragma once
#include "Def.h"
namespace Generated
{
)END";
constexpr char FileCppStart[] = R"END(#include "Generated.h"
namespace Generated
{
)END";
@@ -36,7 +43,7 @@ namespace Generated
R"END( struct %s
{
static constexpr int32_t EntryCount = %u;
enum class Enum : %s
enum Enum : %s
{
)END";
@@ -62,8 +69,77 @@ namespace Generated
constexpr char FileEnd[] =
R"END(}
)END";
constexpr char SaveFuncHeader1[] =
R"END( bool Save(const %s* obj, uint32_t count, Serializer& serializer);
)END";
constexpr char SaveFuncBodyStart1[] = R"END( bool Save(const %s* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
)END";
constexpr char SaveFuncBodyType3[] = R"END( isOk = Save(%sobj[i].%s, %u, serializer) && isOk;
)END";
constexpr char SaveFuncBodyEnum1[] = R"END( auto val = (%s)obj[i];
isOk = Save(&val, 1, serializer) && isOk;
)END";
constexpr char SaveFuncBodyEnd[] = R"END( }
return isOk;
}
)END";
} // namespace WriteTemplates
void CppFileWriter::InitBuffer(WriteBuffer& buf)
{
if (buf.Data != nullptr)
{
LOG_ERROR(0, "Multiple writes not supported yet!");
return;
}
buf.Data =
reinterpret_cast<char*>(VirtualAlloc(nullptr, BufferRequestSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
if (buf.Data == nullptr)
{
LOG_ERROR(0, "Failed to allocate write memory!");
return;
}
buf.WrittenBytes = 0;
}
bool CppFileWriter::WriteBufferToDisk(const bx::FilePath& path, const WriteBuffer& buf)
{
bx::Error error;
bx::FileWriter writer;
LOG(0, "Writing to %s", path.getCPtr());
if (!writer.open(path, false, &error))
{
LOG_ERROR(0, "Failed to open output file: %s", error.getMessage().getCPtr());
return false;
}
writer.write(buf.Data, buf.WrittenBytes, &error);
if (!error.isOk())
{
LOG_ERROR(0, "Failed to write to output file: %s", error.getMessage().getCPtr());
}
writer.close();
LOG(0, "Finished writing!");
return true;
}
void CppFileWriter::WriteInternal(WriteBuffer& buf, const char* templateStr, va_list args)
{
if (buf.Data == nullptr)
{
LOG_ERROR(0, "Wrote too early!");
return;
}
buf.WrittenBytes += bx::vsnprintf(&buf.Data[buf.WrittenBytes], BufferRequestSize, templateStr, args);
}
void CppFileWriter::PrintTypeName(char* buf,
int32_t bufSize,
const Def::FieldType& type,
@@ -87,6 +163,7 @@ void CppFileWriter::PrintTypeName(char* buf,
else if (type.FieldKind == Def::EFieldType::DefinedEnum)
{
bx::strCopy(buf, bufSize, definitions.Enums[type.TypeIdx].Name);
bx::strCat(buf, bufSize, "::Enum");
}
}
@@ -143,64 +220,75 @@ void CppFileWriter::WriteTypes(const Def::DefinitionFile& definitions)
Write(WriteTemplates::StructEnd);
}
}
void CppFileWriter::WriteSaveMethods(const Def::DefinitionFile& definitions)
{
char buf[64]{0};
for (int32_t enumIdx = 0; enumIdx < definitions.EnumCount; ++enumIdx)
{
const Def::Enum& e = definitions.Enums[enumIdx];
bx::snprintf(buf, sizeof(buf), "%s::Enum", e.Name);
Write(WriteTemplates::SaveFuncHeader1, buf);
WriteCpp(WriteTemplates::SaveFuncBodyStart1, buf);
PrintTypeName(buf, sizeof(buf), e.EnumType, definitions);
WriteCpp(WriteTemplates::SaveFuncBodyEnum1, buf);
WriteCpp(WriteTemplates::SaveFuncBodyEnd);
}
for (int32_t typeIdx = 0; typeIdx < definitions.TypeCount; ++typeIdx)
{
const Def::Type& t = definitions.Types[typeIdx];
Write(WriteTemplates::SaveFuncHeader1, t.Name);
WriteCpp(WriteTemplates::SaveFuncBodyStart1, t.Name);
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
{
WriteCpp(WriteTemplates::SaveFuncBodyType3,
t.FieldArraySizes[fieldIdx] > 0 ? "" : "&",
t.FieldNames[fieldIdx],
bx::max(1, t.FieldArraySizes[fieldIdx]));
}
WriteCpp(WriteTemplates::SaveFuncBodyEnd);
}
}
void CppFileWriter::WriteLoadMethods(const Def::DefinitionFile& definitions)
{
}
void CppFileWriter::GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions)
{
LOG(0, "Generating...");
LOG(0, "Generating output files...");
// Allocate write buffer
if (FileWriteBuffer != nullptr)
{
LOG_ERROR(0, "Multiple writes not supported yet!");
return;
}
FileWriteBuffer =
reinterpret_cast<char*>(VirtualAlloc(nullptr, BufferRequestSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
if (FileWriteBuffer == nullptr)
{
LOG_ERROR(0, "Failed to allocate write memory!");
return;
}
FileWriterWritten = 0;
InitBuffer(HeaderWrite);
InitBuffer(CppWrite);
// Write text to buffer
Write(WriteTemplates::FileHeader);
Write(WriteTemplates::FileHeaderStart);
WriteCpp(WriteTemplates::FileCppStart);
WriteEnums(definitions);
WriteTypes(definitions);
WriteSaveMethods(definitions);
Write(WriteTemplates::FileEnd);
WriteCpp(WriteTemplates::FileEnd);
// Write buffer to disk
bx::Error error;
bx::FileWriter writer;
bx::FilePath writePath = outDir;
// std::filesystem::create_directory(outDir.getCPtr());
writePath.join("Generated.h");
LOG(0, "Writing to %s", writePath.getCPtr());
if (!writer.open(writePath, false, &error))
{
LOG_ERROR(0, "Failed to open output file: %s", error.getMessage().getCPtr());
return;
}
writer.write(FileWriteBuffer, FileWriterWritten, &error);
if (!error.isOk())
{
LOG_ERROR(0, "Failed to write to output file: %s", error.getMessage().getCPtr());
}
writer.close();
LOG(0, "Finished writing!");
bx::FilePath writePathHeader = outDir;
bx::FilePath writePathCpp = outDir;
writePathHeader.join("Generated.h");
writePathCpp.join("Generated.cpp");
WriteBufferToDisk(writePathHeader, HeaderWrite);
WriteBufferToDisk(writePathCpp, CppWrite);
}
void CppFileWriter::Write(const char* Template, ...)
void CppFileWriter::Write(const char* templateStr, ...)
{
if (FileWriteBuffer == nullptr)
{
LOG_ERROR(0, "Wrote too early!");
return;
}
va_list ArgList;
va_start(ArgList, Template);
FileWriterWritten += bx::vsnprintf(&FileWriteBuffer[FileWriterWritten], BufferRequestSize, Template, ArgList);
va_end(ArgList);
va_list args;
va_start(args, templateStr);
WriteInternal(HeaderWrite, templateStr, args);
va_end(args);
}
void CppFileWriter::WriteCpp(const char* templateStr, ...)
{
va_list args;
va_start(args, templateStr);
WriteInternal(CppWrite, templateStr, args);
va_end(args);
}

View File

@@ -4,17 +4,30 @@
#include "bx/filepath.h"
struct WriteBuffer
{
char* Data = nullptr;
uint64_t WrittenBytes = 0;
};
struct CppFileWriter
{
private:
static constexpr size_t BufferRequestSize = 1024 * 1024 * 1024;
char* FileWriteBuffer = nullptr;
uint64_t FileWriterWritten = 0;
WriteBuffer HeaderWrite;
WriteBuffer CppWrite;
void InitBuffer(WriteBuffer& buf);
bool WriteBufferToDisk(const bx::FilePath& path, const WriteBuffer& buf);
void WriteInternal(WriteBuffer& buf, const char* templateStr, va_list args);
public:
void PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type, const Def::DefinitionFile& definitions);
void WriteEnums(const Def::DefinitionFile& definitions);
void WriteTypes(const Def::DefinitionFile& definitions);
void WriteSaveMethods(const Def::DefinitionFile& definitions);
void WriteLoadMethods(const Def::DefinitionFile& definitions);
void GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions);
void Write(const char* Template, ...);
void Write(const char* templateStr, ...);
void WriteCpp(const char* templateStr, ...);
};