mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-28 08:34:56 +00:00
849 lines
31 KiB
C++
849 lines
31 KiB
C++
#include "ZoneMarkTemplate.h"
|
|
|
|
#include "Domain/Computations/MemberComputations.h"
|
|
#include "Domain/Computations/StructureComputations.h"
|
|
#include "Internal/BaseTemplate.h"
|
|
#include "Utils/StringUtils.h"
|
|
|
|
#include <cassert>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
|
|
namespace
|
|
{
|
|
constexpr int TAG_HEADER = 1;
|
|
constexpr int TAG_SOURCE = 2;
|
|
|
|
class Template final : BaseTemplate
|
|
{
|
|
public:
|
|
Template(std::ostream& stream, RenderingContext* context)
|
|
: BaseTemplate(stream, context)
|
|
{
|
|
}
|
|
|
|
void Header()
|
|
{
|
|
LINE("// ====================================================================")
|
|
LINE("// This file has been generated by ZoneCodeGenerator.")
|
|
LINE("// Do not modify.")
|
|
LINE("// Any changes will be discarded when regenerating.")
|
|
LINE("// ====================================================================")
|
|
LINE("")
|
|
LINE("#pragma once")
|
|
LINE("")
|
|
LINE("#include \"Loading/AssetMarker.h\"")
|
|
LINEF("#include \"Game/{0}/{0}.h\"", m_env.m_game)
|
|
LINE("")
|
|
LINE("#include <string>")
|
|
LINE("")
|
|
LINEF("namespace {0}", m_env.m_game)
|
|
LINE("{")
|
|
m_intendation++;
|
|
LINEF("class {0} final : public AssetMarker", MarkerClassName(m_env.m_asset))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
LINE(VariableDecl(m_env.m_asset->m_definition))
|
|
LINE(PointerVariableDecl(m_env.m_asset->m_definition))
|
|
LINE("")
|
|
|
|
m_intendation--;
|
|
LINE("public:")
|
|
m_intendation++;
|
|
|
|
// Variable Declarations: type varType;
|
|
for (const auto* type : m_env.m_used_types)
|
|
{
|
|
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
|
|
{
|
|
LINE(VariableDecl(type->m_type))
|
|
}
|
|
}
|
|
for (const auto* type : m_env.m_used_types)
|
|
{
|
|
if (type->m_pointer_array_reference_exists && !type->m_is_context_asset)
|
|
{
|
|
LINE(PointerVariableDecl(type->m_type))
|
|
}
|
|
}
|
|
|
|
LINE("")
|
|
|
|
// Method Declarations
|
|
for (const auto* type : m_env.m_used_types)
|
|
{
|
|
if (type->m_pointer_array_reference_exists && type->m_info->m_requires_marking)
|
|
{
|
|
PrintHeaderPtrArrayMarkMethodDeclaration(type->m_type);
|
|
}
|
|
}
|
|
for (const auto* type : m_env.m_used_types)
|
|
{
|
|
if (type->m_array_reference_exists && type->m_info && !type->m_info->m_is_leaf && type->m_info->m_requires_marking
|
|
&& type->m_non_runtime_reference_exists)
|
|
{
|
|
PrintHeaderArrayMarkMethodDeclaration(type->m_type);
|
|
}
|
|
}
|
|
for (const auto* type : m_env.m_used_structures)
|
|
{
|
|
if (type->m_non_runtime_reference_exists && !type->m_info->m_is_leaf && type->m_info->m_requires_marking
|
|
&& !StructureComputations(type->m_info).IsAsset())
|
|
{
|
|
PrintHeaderMarkMethodDeclaration(type->m_info);
|
|
}
|
|
}
|
|
PrintHeaderMarkMethodDeclaration(m_env.m_asset);
|
|
LINE("")
|
|
PrintHeaderGetNameMethodDeclaration(m_env.m_asset);
|
|
PrintHeaderGetAssetInfoMethodDeclaration(m_env.m_asset);
|
|
LINE("")
|
|
PrintHeaderConstructor();
|
|
PrintHeaderMainMarkMethodDeclaration(m_env.m_asset);
|
|
|
|
m_intendation--;
|
|
LINE("};")
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
|
|
void Source()
|
|
{
|
|
LINE("// ====================================================================")
|
|
LINE("// This file has been generated by ZoneCodeGenerator.")
|
|
LINE("// Do not modify.")
|
|
LINE("// Any changes will be discarded when regenerating.")
|
|
LINE("// ====================================================================")
|
|
LINE("")
|
|
LINEF("#include \"{0}_mark_db.h\"", Lower(m_env.m_asset->m_definition->m_name))
|
|
LINE("")
|
|
LINE("#include <cassert>")
|
|
LINE("")
|
|
|
|
if (!m_env.m_referenced_assets.empty())
|
|
{
|
|
LINE("// Referenced Assets:")
|
|
for (const auto* type : m_env.m_referenced_assets)
|
|
{
|
|
LINEF("#include \"../{0}/{0}_mark_db.h\"", Lower(type->m_type->m_name))
|
|
}
|
|
LINE("")
|
|
}
|
|
LINEF("using namespace {0};", m_env.m_game)
|
|
LINE("")
|
|
PrintConstructorMethod();
|
|
|
|
for (const auto* type : m_env.m_used_types)
|
|
{
|
|
if (type->m_pointer_array_reference_exists && type->m_info->m_requires_marking)
|
|
{
|
|
LINE("")
|
|
PrintMarkPtrArrayMethod(type->m_type, type->m_info, type->m_pointer_array_reference_is_reusable);
|
|
}
|
|
}
|
|
for (const auto* type : m_env.m_used_types)
|
|
{
|
|
if (type->m_array_reference_exists && type->m_info && !type->m_info->m_is_leaf && type->m_info->m_requires_marking
|
|
&& type->m_non_runtime_reference_exists)
|
|
{
|
|
LINE("")
|
|
PrintMarkArrayMethod(type->m_type, type->m_info);
|
|
}
|
|
}
|
|
for (const auto* type : m_env.m_used_structures)
|
|
{
|
|
if (type->m_non_runtime_reference_exists && !type->m_info->m_is_leaf && type->m_info->m_requires_marking
|
|
&& !StructureComputations(type->m_info).IsAsset())
|
|
{
|
|
LINE("")
|
|
PrintMarkMethod(type->m_info);
|
|
}
|
|
}
|
|
LINE("")
|
|
PrintMarkMethod(m_env.m_asset);
|
|
LINE("")
|
|
PrintMainMarkMethod();
|
|
LINE("")
|
|
PrintGetNameMethod();
|
|
PrintGetAssetInfoMethod();
|
|
}
|
|
|
|
private:
|
|
enum class MemberLoadType : std::uint8_t
|
|
{
|
|
ARRAY_POINTER,
|
|
DYNAMIC_ARRAY,
|
|
EMBEDDED,
|
|
EMBEDDED_ARRAY,
|
|
POINTER_ARRAY,
|
|
SINGLE_POINTER
|
|
};
|
|
|
|
static std::string MarkerClassName(const StructureInformation* asset)
|
|
{
|
|
return std::format("Marker_{0}", asset->m_definition->m_name);
|
|
}
|
|
|
|
static std::string VariableDecl(const DataDefinition* def)
|
|
{
|
|
return std::format("{0}* var{1};", def->GetFullName(), MakeSafeTypeName(def));
|
|
}
|
|
|
|
static std::string PointerVariableDecl(const DataDefinition* def)
|
|
{
|
|
return std::format("{0}** var{1}Ptr;", def->GetFullName(), MakeSafeTypeName(def));
|
|
}
|
|
|
|
void PrintHeaderPtrArrayMarkMethodDeclaration(const DataDefinition* def) const
|
|
{
|
|
LINEF("void MarkPtrArray_{0}(size_t count);", MakeSafeTypeName(def))
|
|
}
|
|
|
|
void PrintHeaderArrayMarkMethodDeclaration(const DataDefinition* def) const
|
|
{
|
|
LINEF("void MarkArray_{0}(size_t count);", MakeSafeTypeName(def))
|
|
}
|
|
|
|
void PrintHeaderMarkMethodDeclaration(const StructureInformation* info) const
|
|
{
|
|
LINEF("void Mark_{0}();", MakeSafeTypeName(info->m_definition))
|
|
}
|
|
|
|
void PrintHeaderGetAssetInfoMethodDeclaration(const StructureInformation* info) const
|
|
{
|
|
LINEF("XAssetInfo<{0}>* GetAssetInfo({0}* pAsset) const;", info->m_definition->GetFullName())
|
|
}
|
|
|
|
void PrintHeaderGetNameMethodDeclaration(const StructureInformation* info) const
|
|
{
|
|
LINEF("static std::string GetAssetName({0}* pAsset);", info->m_definition->GetFullName())
|
|
}
|
|
|
|
void PrintHeaderConstructor() const
|
|
{
|
|
LINEF("{0}(Zone* zone);", MarkerClassName(m_env.m_asset))
|
|
}
|
|
|
|
void PrintHeaderMainMarkMethodDeclaration(const StructureInformation* info) const
|
|
{
|
|
LINEF("void Mark({0}* pAsset);", info->m_definition->GetFullName())
|
|
}
|
|
|
|
void PrintVariableInitialization(const DataDefinition* def) const
|
|
{
|
|
LINEF("var{0} = nullptr;", def->m_name)
|
|
}
|
|
|
|
void PrintPointerVariableInitialization(const DataDefinition* def) const
|
|
{
|
|
LINEF("var{0}Ptr = nullptr;", def->m_name)
|
|
}
|
|
|
|
void PrintConstructorMethod()
|
|
{
|
|
LINEF("{0}::{0}(Zone* zone)", MarkerClassName(m_env.m_asset))
|
|
|
|
m_intendation++;
|
|
LINEF(": AssetMarker({0}, zone)", m_env.m_asset->m_asset_enum_entry->m_name)
|
|
m_intendation--;
|
|
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
PrintVariableInitialization(m_env.m_asset->m_definition);
|
|
PrintPointerVariableInitialization(m_env.m_asset->m_definition);
|
|
LINE("")
|
|
|
|
for (const auto* type : m_env.m_used_types)
|
|
{
|
|
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
|
|
{
|
|
PrintVariableInitialization(type->m_type);
|
|
}
|
|
}
|
|
for (const auto* type : m_env.m_used_types)
|
|
{
|
|
if (type->m_info && type->m_pointer_array_reference_exists && !type->m_is_context_asset)
|
|
{
|
|
PrintPointerVariableInitialization(type->m_type);
|
|
}
|
|
}
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
|
|
void PrintMarkPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const
|
|
{
|
|
if (info && !info->m_is_leaf)
|
|
{
|
|
LINEF("{0} = *{1};", MakeTypeVarName(info->m_definition), MakeTypePtrVarName(def))
|
|
LINEF("Mark_{0}();", MakeSafeTypeName(def))
|
|
}
|
|
}
|
|
|
|
void PrintMarkPtrArrayMethod_PointerCheck(const DataDefinition* def, StructureInformation* info, const bool reusable)
|
|
{
|
|
LINEF("if (*{0})", MakeTypePtrVarName(def))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
if (info && StructureComputations(info).IsAsset())
|
|
{
|
|
LINEF("AddDependency({0}(m_zone).GetAssetInfo(*{1}));", MarkerClassName(info), MakeTypePtrVarName(def))
|
|
}
|
|
else
|
|
{
|
|
PrintMarkPtrArrayMethod_Loading(def, info);
|
|
}
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
|
|
void PrintMarkPtrArrayMethod(const DataDefinition* def, StructureInformation* info, const bool reusable)
|
|
{
|
|
LINEF("void {0}::MarkPtrArray_{1}(const size_t count)", MarkerClassName(m_env.m_asset), MakeSafeTypeName(def))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
LINEF("assert({0} != nullptr);", MakeTypePtrVarName(def))
|
|
LINE("")
|
|
|
|
LINEF("{0}** var = {1};", def->GetFullName(), MakeTypePtrVarName(def))
|
|
LINE("for (size_t index = 0; index < count; index++)")
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
LINEF("{0} = var;", MakeTypePtrVarName(def))
|
|
PrintMarkPtrArrayMethod_PointerCheck(def, info, reusable);
|
|
LINE("")
|
|
LINE("var++;")
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
|
|
void PrintMarkArrayMethod(const DataDefinition* def, const StructureInformation* info)
|
|
{
|
|
LINEF("void {0}::MarkArray_{1}(const size_t count)", MarkerClassName(m_env.m_asset), MakeSafeTypeName(def))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
LINEF("assert({0} != nullptr);", MakeTypeVarName(def))
|
|
LINE("")
|
|
|
|
LINEF("{0}* var = {1};", def->GetFullName(), MakeTypeVarName(def))
|
|
LINE("for (size_t index = 0; index < count; index++)")
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
LINEF("{0} = var;", MakeTypeVarName(info->m_definition))
|
|
LINEF("Mark_{0}();", info->m_definition->m_name)
|
|
LINE("var++;")
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
|
|
void MarkMember_ScriptString(const StructureInformation* info,
|
|
const MemberInformation* member,
|
|
const DeclarationModifierComputations& modifier,
|
|
const MemberLoadType loadType) const
|
|
{
|
|
if (loadType == MemberLoadType::ARRAY_POINTER)
|
|
{
|
|
LINEF("MarkArray_ScriptString({0}, {1});", MakeMemberAccess(info, member, modifier), MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
|
|
}
|
|
else if (loadType == MemberLoadType::EMBEDDED_ARRAY)
|
|
{
|
|
LINEF("MarkArray_ScriptString({0}, {1});",
|
|
MakeMemberAccess(info, member, modifier),
|
|
MakeArrayCount(dynamic_cast<ArrayDeclarationModifier*>(modifier.GetDeclarationModifier())))
|
|
}
|
|
else if (loadType == MemberLoadType::EMBEDDED)
|
|
{
|
|
LINEF("Mark_ScriptString({0});", MakeMemberAccess(info, member, modifier))
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
LINEF("#error unsupported loadType {0} for script string", static_cast<int>(loadType))
|
|
}
|
|
}
|
|
|
|
void MarkMember_AssetRef(const StructureInformation* info,
|
|
const MemberInformation* member,
|
|
const DeclarationModifierComputations& modifier,
|
|
const MemberLoadType loadType) const
|
|
{
|
|
if (loadType == MemberLoadType::POINTER_ARRAY)
|
|
{
|
|
if (modifier.IsArray())
|
|
{
|
|
LINEF("MarkArray_IndirectAssetRef({0}, {1}, {2});",
|
|
member->m_asset_ref->m_name,
|
|
MakeMemberAccess(info, member, modifier),
|
|
modifier.GetArraySize())
|
|
}
|
|
else
|
|
{
|
|
LINEF("MarkArray_IndirectAssetRef({0}, {1}, {2});",
|
|
member->m_asset_ref->m_name,
|
|
MakeMemberAccess(info, member, modifier),
|
|
MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
|
|
}
|
|
}
|
|
else if (loadType == MemberLoadType::SINGLE_POINTER)
|
|
{
|
|
LINEF("Mark_IndirectAssetRef({0}, {1});", member->m_asset_ref->m_name, MakeMemberAccess(info, member, modifier))
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
LINEF("#error unsupported loadType {0} for script string", static_cast<int>(loadType))
|
|
}
|
|
}
|
|
|
|
void MarkMember_Asset(const StructureInformation* info,
|
|
const MemberInformation* member,
|
|
const DeclarationModifierComputations& modifier,
|
|
const MemberLoadType loadType) const
|
|
{
|
|
if (loadType == MemberLoadType::SINGLE_POINTER)
|
|
{
|
|
LINEF("AddDependency({0}(m_zone).GetAssetInfo({1}));", MarkerClassName(member->m_type), MakeMemberAccess(info, member, modifier))
|
|
}
|
|
else if (loadType == MemberLoadType::POINTER_ARRAY)
|
|
{
|
|
MarkMember_PointerArray(info, member, modifier);
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
LINEF("#error unsupported loadType {0} for asset", static_cast<int>(loadType))
|
|
}
|
|
}
|
|
|
|
void MarkMember_ArrayPointer(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
|
{
|
|
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
|
LINEF("MarkArray_{0}({1});",
|
|
MakeSafeTypeName(member->m_member->m_type_declaration->m_type),
|
|
MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
|
|
}
|
|
|
|
void MarkMember_PointerArray(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
|
{
|
|
LINEF("{0} = {1};", MakeTypePtrVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
|
if (modifier.IsArray())
|
|
{
|
|
LINEF("MarkPtrArray_{0}({1});", MakeSafeTypeName(member->m_member->m_type_declaration->m_type), modifier.GetArraySize())
|
|
}
|
|
else
|
|
{
|
|
LINEF("MarkPtrArray_{0}({1});",
|
|
MakeSafeTypeName(member->m_member->m_type_declaration->m_type),
|
|
MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
|
|
}
|
|
}
|
|
|
|
void MarkMember_EmbeddedArray(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
|
{
|
|
std::string arraySizeStr;
|
|
|
|
if (modifier.HasDynamicArrayCount())
|
|
arraySizeStr = MakeEvaluation(modifier.GetDynamicArrayCountEvaluation());
|
|
else
|
|
arraySizeStr = std::to_string(modifier.GetArraySize());
|
|
|
|
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
|
LINEF("MarkArray_{0}({1});", MakeSafeTypeName(member->m_member->m_type_declaration->m_type), arraySizeStr)
|
|
}
|
|
|
|
void MarkMember_DynamicArray(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
|
{
|
|
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
|
LINEF(
|
|
"MarkArray_{0}({1});", MakeSafeTypeName(member->m_member->m_type_declaration->m_type), MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()))
|
|
}
|
|
|
|
void MarkMember_Embedded(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
|
{
|
|
LINEF("{0} = &{1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
|
LINEF("Mark_{0}();", MakeSafeTypeName(member->m_member->m_type_declaration->m_type))
|
|
}
|
|
|
|
void MarkMember_SinglePointer(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
|
{
|
|
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
|
LINEF("Mark_{0}();", MakeSafeTypeName(member->m_type->m_definition))
|
|
}
|
|
|
|
void MarkMember_TypeCheck(const StructureInformation* info,
|
|
const MemberInformation* member,
|
|
const DeclarationModifierComputations& modifier,
|
|
const MemberLoadType loadType) const
|
|
{
|
|
if (member->m_is_script_string)
|
|
{
|
|
MarkMember_ScriptString(info, member, modifier, loadType);
|
|
}
|
|
else if (member->m_asset_ref)
|
|
{
|
|
MarkMember_AssetRef(info, member, modifier, loadType);
|
|
}
|
|
else if (member->m_type && StructureComputations(member->m_type).IsAsset())
|
|
{
|
|
MarkMember_Asset(info, member, modifier, loadType);
|
|
}
|
|
else
|
|
{
|
|
switch (loadType)
|
|
{
|
|
case MemberLoadType::ARRAY_POINTER:
|
|
MarkMember_ArrayPointer(info, member, modifier);
|
|
break;
|
|
|
|
case MemberLoadType::SINGLE_POINTER:
|
|
MarkMember_SinglePointer(info, member, modifier);
|
|
break;
|
|
|
|
case MemberLoadType::EMBEDDED:
|
|
MarkMember_Embedded(info, member, modifier);
|
|
break;
|
|
|
|
case MemberLoadType::POINTER_ARRAY:
|
|
MarkMember_PointerArray(info, member, modifier);
|
|
break;
|
|
|
|
case MemberLoadType::DYNAMIC_ARRAY:
|
|
MarkMember_DynamicArray(info, member, modifier);
|
|
break;
|
|
|
|
case MemberLoadType::EMBEDDED_ARRAY:
|
|
MarkMember_EmbeddedArray(info, member, modifier);
|
|
break;
|
|
|
|
default:
|
|
LINEF("// t={0}", static_cast<int>(loadType))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool MarkMember_ShouldMakePointerCheck(const MemberInformation* member, const DeclarationModifierComputations& modifier, MemberLoadType loadType)
|
|
{
|
|
if (loadType != MemberLoadType::ARRAY_POINTER && loadType != MemberLoadType::POINTER_ARRAY && loadType != MemberLoadType::SINGLE_POINTER)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (loadType == MemberLoadType::POINTER_ARRAY)
|
|
{
|
|
return !modifier.IsArray();
|
|
}
|
|
|
|
if (member->m_is_string)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void MarkMember_PointerCheck(const StructureInformation* info,
|
|
const MemberInformation* member,
|
|
const DeclarationModifierComputations& modifier,
|
|
const MemberLoadType loadType)
|
|
{
|
|
if (MarkMember_ShouldMakePointerCheck(member, modifier, loadType))
|
|
{
|
|
LINEF("if ({0})", MakeMemberAccess(info, member, modifier))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
MarkMember_TypeCheck(info, member, modifier, loadType);
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
else
|
|
{
|
|
MarkMember_TypeCheck(info, member, modifier, loadType);
|
|
}
|
|
}
|
|
|
|
void MarkMember_ReferenceArray(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier)
|
|
{
|
|
auto first = true;
|
|
for (const auto& entry : modifier.GetArrayEntries())
|
|
{
|
|
if (first)
|
|
{
|
|
first = false;
|
|
}
|
|
else
|
|
{
|
|
LINE("")
|
|
}
|
|
|
|
MarkMember_Reference(info, member, entry);
|
|
}
|
|
}
|
|
|
|
void MarkMember_Reference(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier)
|
|
{
|
|
if (modifier.IsDynamicArray())
|
|
{
|
|
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::DYNAMIC_ARRAY);
|
|
}
|
|
else if (modifier.IsSinglePointer())
|
|
{
|
|
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::SINGLE_POINTER);
|
|
}
|
|
else if (modifier.IsArrayPointer())
|
|
{
|
|
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::ARRAY_POINTER);
|
|
}
|
|
else if (modifier.IsPointerArray())
|
|
{
|
|
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::POINTER_ARRAY);
|
|
}
|
|
else if (modifier.IsArray() && modifier.GetNextDeclarationModifier() == nullptr)
|
|
{
|
|
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::EMBEDDED_ARRAY);
|
|
}
|
|
else if (modifier.GetDeclarationModifier() == nullptr)
|
|
{
|
|
MarkMember_PointerCheck(info, member, modifier, MemberLoadType::EMBEDDED);
|
|
}
|
|
else if (modifier.IsArray())
|
|
{
|
|
MarkMember_ReferenceArray(info, member, modifier);
|
|
}
|
|
else
|
|
{
|
|
assert(false);
|
|
LINEF("#error MarkMemberReference failed @ {0}", member->m_member->m_name)
|
|
}
|
|
}
|
|
|
|
void MarkMember_Condition_Struct(const StructureInformation* info, const MemberInformation* member)
|
|
{
|
|
LINE("")
|
|
if (member->m_condition)
|
|
{
|
|
LINEF("if ({0})", MakeEvaluation(member->m_condition.get()))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
else
|
|
{
|
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
|
}
|
|
}
|
|
|
|
void MarkMember_Condition_Union(const StructureInformation* info, const MemberInformation* member)
|
|
{
|
|
const MemberComputations computations(member);
|
|
|
|
if (computations.IsFirstMember())
|
|
{
|
|
LINE("")
|
|
if (member->m_condition)
|
|
{
|
|
LINEF("if ({0})", MakeEvaluation(member->m_condition.get()))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
else
|
|
{
|
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
|
}
|
|
}
|
|
else if (computations.IsLastMember())
|
|
{
|
|
if (member->m_condition)
|
|
{
|
|
LINEF("else if ({0})", MakeEvaluation(member->m_condition.get()))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
else
|
|
{
|
|
LINE("else")
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (member->m_condition)
|
|
{
|
|
LINEF("else if ({0})", MakeEvaluation(member->m_condition.get()))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
else
|
|
{
|
|
LINEF("#error Middle member of union must have condition ({0})", member->m_member->m_name)
|
|
}
|
|
}
|
|
}
|
|
|
|
void PrintMarkMemberIfNeedsTreatment(const StructureInformation* info, const MemberInformation* member)
|
|
{
|
|
const MemberComputations computations(member);
|
|
if (computations.ShouldIgnore() || computations.IsInRuntimeBlock())
|
|
return;
|
|
|
|
if (member->m_is_script_string || member->m_asset_ref
|
|
|| member->m_type && (member->m_type->m_requires_marking || StructureComputations(member->m_type).IsAsset()))
|
|
{
|
|
if (info->m_definition->GetType() == DataDefinitionType::UNION)
|
|
MarkMember_Condition_Union(info, member);
|
|
else
|
|
MarkMember_Condition_Struct(info, member);
|
|
}
|
|
}
|
|
|
|
void PrintMarkMethod(const StructureInformation* info)
|
|
{
|
|
LINEF("void {0}::Mark_{1}()", MarkerClassName(m_env.m_asset), info->m_definition->m_name)
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
LINEF("assert({0} != nullptr);", MakeTypeVarName(info->m_definition))
|
|
|
|
for (const auto& member : info->m_ordered_members)
|
|
{
|
|
PrintMarkMemberIfNeedsTreatment(info, member.get());
|
|
}
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
|
|
void PrintGetNameMethod()
|
|
{
|
|
LINEF("std::string {0}::GetAssetName({1}* pAsset)", MarkerClassName(m_env.m_asset), m_env.m_asset->m_definition->GetFullName())
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
if (!m_env.m_asset->m_name_chain.empty())
|
|
{
|
|
LINE_START("return pAsset")
|
|
|
|
auto first = true;
|
|
for (auto* member : m_env.m_asset->m_name_chain)
|
|
{
|
|
if (first)
|
|
{
|
|
first = false;
|
|
LINE_MIDDLEF("->{0}", member->m_member->m_name)
|
|
}
|
|
else
|
|
{
|
|
LINE_MIDDLEF(".{0}", member->m_member->m_name)
|
|
}
|
|
}
|
|
LINE_END(";")
|
|
}
|
|
else
|
|
{
|
|
LINEF("return \"{0}\";", m_env.m_asset->m_definition->m_name)
|
|
}
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
|
|
void PrintGetAssetInfoMethod()
|
|
{
|
|
LINEF("XAssetInfo<{0}>* {1}::GetAssetInfo({0}* pAsset) const", m_env.m_asset->m_definition->GetFullName(), MarkerClassName(m_env.m_asset))
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
LINEF("return reinterpret_cast<XAssetInfo<{0}>*>(GetAssetInfoByName(GetAssetName(pAsset)));", m_env.m_asset->m_definition->GetFullName())
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
|
|
void PrintMainMarkMethod()
|
|
{
|
|
LINEF("void {0}::Mark({1}* pAsset)", MarkerClassName(m_env.m_asset), m_env.m_asset->m_definition->GetFullName())
|
|
LINE("{")
|
|
m_intendation++;
|
|
|
|
LINE("assert(pAsset != nullptr);")
|
|
LINE("")
|
|
LINEF("{0} = pAsset;", MakeTypeVarName(m_env.m_asset->m_definition))
|
|
LINEF("Mark_{0}();", MakeSafeTypeName(m_env.m_asset->m_definition))
|
|
|
|
m_intendation--;
|
|
LINE("}")
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
std::vector<CodeTemplateFile> ZoneMarkTemplate::GetFilesToRender(RenderingContext* context)
|
|
{
|
|
std::vector<CodeTemplateFile> files;
|
|
|
|
auto assetName = context->m_asset->m_definition->m_name;
|
|
utils::MakeStringLowerCase(assetName);
|
|
|
|
files.emplace_back(std::format("{0}/{0}_mark_db.h", assetName), TAG_HEADER);
|
|
files.emplace_back(std::format("{0}/{0}_mark_db.cpp", assetName), TAG_SOURCE);
|
|
|
|
return files;
|
|
}
|
|
|
|
void ZoneMarkTemplate::RenderFile(std::ostream& stream, const int fileTag, RenderingContext* context)
|
|
{
|
|
Template t(stream, context);
|
|
|
|
if (fileTag == TAG_HEADER)
|
|
{
|
|
t.Header();
|
|
}
|
|
else
|
|
{
|
|
assert(fileTag == TAG_SOURCE);
|
|
t.Source();
|
|
}
|
|
}
|