From fe121853e2c130b03122f8f2b819bba648150295 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 20 Feb 2021 12:28:38 +0100 Subject: [PATCH] render zoneload header --- .../Templates/AssetStructTestsTemplate.cpp | 66 +++---- .../Templates/Internal/BaseTemplate.cpp | 153 +++++++++++++++ .../Templates/Internal/BaseTemplate.h | 42 +++++ .../Generating/Templates/ZoneLoadTemplate.cpp | 174 ++++++++++++++++++ .../Generating/Templates/ZoneLoadTemplate.h | 2 + 5 files changed, 395 insertions(+), 42 deletions(-) create mode 100644 src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp create mode 100644 src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp index 7ef35e41..19929764 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp @@ -4,60 +4,42 @@ #include #include "Domain/Computations/StructureComputations.h" +#include "Internal/BaseTemplate.h" -#define LINE(x) DoIntendation(); m_out << x << "\n" - -class AssetStructTestsTemplate::Internal +class AssetStructTestsTemplate::Internal final : BaseTemplate { - static constexpr const char* INTENDATION = " "; - - std::ostream& m_out; - RenderingContext& m_env; - unsigned m_intendation; - - void DoIntendation() const - { - for (auto i = 0u; i < m_intendation; i++) - m_out << INTENDATION; - } - void TestMethod(StructureInformation* structure) { - /*if (structure->m_non_embedded_reference_exists) - {*/ - LINE("TEST_CASE(\""<m_definition->GetFullName()<<": Tests for "<m_definition->GetFullName()<<"\", \"[assetstruct]\")"); - LINE("{"); - m_intendation++; - LINE("REQUIRE("<m_definition->GetSize()<<"u == sizeof("<m_definition->GetFullName()<<"));"); - LINE("REQUIRE("<m_definition->GetAlignment()<<"u == alignof("<m_definition->GetFullName()<<"));"); - m_intendation--; - LINE("}"); - /*}*/ + LINE("TEST_CASE(\""<m_definition->GetFullName()<<": Tests for "<m_definition->GetFullName()<<"\", \"[assetstruct]\")") + LINE("{") + m_intendation++; + LINE("REQUIRE("<m_definition->GetSize()<<"u == sizeof("<m_definition->GetFullName()<<"));") + LINE("REQUIRE("<m_definition->GetAlignment()<<"u == alignof("<m_definition->GetFullName()<<"));") + m_intendation--; + LINE("}") } public: Internal(std::ostream& stream, RenderingContext* context) - : m_out(stream), - m_env(*context), - m_intendation(0u) + : BaseTemplate(stream, context) { } 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(""); - LINE("#include "); - LINE("#include \"Game/" << m_env.m_game << "/" << m_env.m_game << ".h\""); - LINE(""); - LINE("using namespace " << m_env.m_game << ";"); - LINE(""); - LINE("namespace game::"<m_definition->m_name); - LINE("{"); + LINE("// ====================================================================") + LINE("// This file has been generated by ZoneCodeGenerator.") + LINE("// Do not modify.") + LINE("// Any changes will be discarded when regenerating.") + LINE("// ====================================================================") + LINE("") + LINE("#include ") + LINE("#include \"Game/" << m_env.m_game << "/" << m_env.m_game << ".h\"") + LINE("") + LINE("using namespace " << m_env.m_game << ";") + LINE("") + LINE("namespace game::"<m_definition->m_name)) + LINE("{") m_intendation++; TestMethod(m_env.m_asset); @@ -69,7 +51,7 @@ public: } m_intendation--; - LINE("}"); + LINE("}") } }; diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp new file mode 100644 index 00000000..09e3c0f8 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp @@ -0,0 +1,153 @@ +#include "BaseTemplate.h" + +#include + +#include "Domain/Definition/ArrayDeclarationModifier.h" + +BaseTemplate::BaseTemplate(std::ostream& stream, RenderingContext* context) + : m_out(stream), + m_env(*context), + m_intendation(0u) +{ +} + +void BaseTemplate::DoIntendation() const +{ + for (auto i = 0u; i < m_intendation; i++) + m_out << INTENDATION; +} + +std::string BaseTemplate::Upper(std::string str) +{ + for (auto& c : str) + c = static_cast(toupper(c)); + + return str; +} + +std::string BaseTemplate::Lower(std::string str) +{ + for (auto& c : str) + c = static_cast(tolower(c)); + + return str; +} + +std::string BaseTemplate::TypeVarName(const DataDefinition* def) +{ + std::ostringstream str; + str << "var" << SafeTypeName(def); + return str.str(); +} + +std::string BaseTemplate::TypePtrVarName(const DataDefinition* def) +{ + std::ostringstream str; + str << "var" << SafeTypeName(def) << "Ptr"; + return str.str(); +} + +std::string BaseTemplate::SafeTypeName(const DataDefinition* def) +{ + auto safeName(def->m_name); + + for(auto& c : safeName) + { + if (isspace(c)) + c = '_'; + } + + return safeName; +} + +void BaseTemplate::TypeDecl(const TypeDeclaration* decl) const +{ + if (decl->m_is_const) + m_out << "const "; + m_out << decl->m_type->GetFullName(); +} + +void BaseTemplate::PrintFollowingReferences(const std::vector>& modifiers) const +{ + for(const auto& modifier : modifiers) + { + if(modifier->GetType() == DeclarationModifierType::ARRAY) + { + const auto* array = dynamic_cast(modifier.get()); + m_out << "[" << array->m_size << "]"; + } + else + m_out << '*'; + } +} + +void BaseTemplate::PrintArrayIndices(const DeclarationModifierComputations& modifierComputations) const +{ + for(auto index : modifierComputations.GetArrayIndices()) + m_out << "[" << index << "]"; +} + +void BaseTemplate::PrintOperandStatic(const OperandStatic* op) const +{ + if (op->m_enum_member != nullptr) + m_out << op->m_enum_member->m_name; + else + m_out << op->m_value; +} + +void BaseTemplate::PrintOperandDynamic(const OperandDynamic* op) const +{ + m_out << TypeVarName(op->m_structure->m_definition); + + auto first = true; + for (const auto* chainMember : op->m_referenced_member_chain) + { + if (first) + { + first = false; + m_out << "->" << chainMember->m_member->m_name; + } + else + m_out << '.' << chainMember->m_member->m_name; + } + + for(const auto& arrayIndex : op->m_array_indices) + { + m_out << "["; + PrintEvaluation(arrayIndex.get()); + m_out << "]"; + } +} + +void BaseTemplate::PrintOperation(const Operation* operation) const +{ + if (operation->Operand1NeedsParenthesis()) + { + m_out << "("; + PrintEvaluation(operation->m_operand1.get()); + m_out << ")"; + } + else + PrintEvaluation(operation->m_operand1.get()); + + m_out << " " << operation->m_operation_type->m_syntax << " "; + + if (operation->Operand2NeedsParenthesis()) + { + m_out << "("; + PrintEvaluation(operation->m_operand2.get()); + m_out << ")"; + } + else + PrintEvaluation(operation->m_operand2.get()); +} + +void BaseTemplate::PrintEvaluation(const IEvaluation* evaluation) const +{ + if (evaluation->GetType() == EvaluationType::OPERATION) + PrintOperation(dynamic_cast(evaluation)); + else if (evaluation->GetType() == EvaluationType::OPERAND_STATIC) + PrintOperandStatic(dynamic_cast(evaluation)); + else if (evaluation->GetType() == EvaluationType::OPERAND_DYNAMIC) + PrintOperandDynamic(dynamic_cast(evaluation)); +} diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h new file mode 100644 index 00000000..f3776b13 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include "Domain/Computations/MemberDeclarationModifierComputations.h" +#include "Domain/Evaluation/OperandDynamic.h" +#include "Domain/Evaluation/OperandStatic.h" +#include "Domain/Evaluation/Operation.h" +#include "Generating/RenderingContext.h" + +class BaseTemplate +{ +protected: + static constexpr const char* INTENDATION = " "; + + std::ostream& m_out; + RenderingContext& m_env; + unsigned m_intendation; + + BaseTemplate(std::ostream& stream, RenderingContext* context); + + void DoIntendation() const; + + static std::string Upper(std::string str); + static std::string Lower(std::string str); + static std::string TypeVarName(const DataDefinition* def); + static std::string TypePtrVarName(const DataDefinition* def); + static std::string SafeTypeName(const DataDefinition* def); + void TypeDecl(const TypeDeclaration* decl) const; + void PrintFollowingReferences(const std::vector>& modifiers) const; + void PrintArrayIndices(const DeclarationModifierComputations& modifierComputations) const; + + void PrintOperandStatic(const OperandStatic* op) const; + void PrintOperandDynamic(const OperandDynamic* op) const; + void PrintOperation(const Operation* operation) const; + void PrintEvaluation(const IEvaluation* evaluation) const; +}; + +#define LINE(x) {DoIntendation(); m_out << x << "\n";} +#define LINE_START(x) {DoIntendation(); m_out << x;} +#define LINE_MIDDLE(x) {m_out << x;} +#define LINE_END(x) {m_out << x << "\n";} \ No newline at end of file diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp index acbe9bdc..bae89f81 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp @@ -1,7 +1,176 @@ #include "ZoneLoadTemplate.h" +#include #include + +#include "Domain/Computations/StructureComputations.h" +#include "Internal/BaseTemplate.h" + +class ZoneLoadTemplate::Internal final : BaseTemplate +{ + static std::string LoaderClassName(StructureInformation* asset) + { + std::ostringstream str; + str << "Loader_" << asset->m_definition->m_name; + return str.str(); + } + + static std::string VariableDecl(const DataDefinition* def) + { + std::ostringstream str; + str << def->GetFullName() << "* var" << SafeTypeName(def) << ";"; + return str.str(); + } + + static std::string PointerVariableDecl(const DataDefinition* def) + { + std::ostringstream str; + str << def->GetFullName() << "** var" << SafeTypeName(def) << "Ptr;"; + return str.str(); + } + + void PrintHeaderPtrArrayLoadMethodDeclaration(const DataDefinition* def) const + { + LINE("void LoadPtrArray_"<m_definition)<<"(bool atStreamStart);") + } + + void PrintHeaderTempPtrLoadMethodDeclaration(const StructureInformation* info) const + { + LINE("void LoadPtr_"<m_definition)<<"(bool atStreamStart);") + } + + void PrintHeaderAssetLoadMethodDeclaration(const StructureInformation* info) const + { + LINE("void LoadAsset_"<m_definition)<<"("<m_definition->GetFullName()<<"** pAsset);") + } + + void PrintHeaderGetNameMethodDeclaration(const StructureInformation* info) const + { + LINE("static std::string GetAssetName("<m_definition->GetFullName()<<"* pAsset);") + } + + void PrintHeaderMainLoadMethodDeclaration(const StructureInformation* info) const + { + LINE("XAssetInfo<"<m_definition->GetFullName()<<">* Load("<m_definition->GetFullName()<<"** pAsset);") + } + + void PrintHeaderConstructor() const + { + LINE(LoaderClassName(m_env.m_asset)<<"(Zone* zone, IZoneInputStream* stream);") + } + +public: + Internal(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/AssetLoader.h\"") + LINE("#include \"Game/" << m_env.m_game << "/" << m_env.m_game << ".h\"") + if (m_env.m_has_actions) + { + LINE("#include \"Game/" << m_env.m_game << "/XAssets/" << Lower(m_env.m_asset->m_definition->m_name) << "/" << Lower(m_env.m_asset->m_definition->m_name) << "_actions.h\"") + } + LINE("#include ") + LINE("") + LINE("namespace " << m_env.m_game) + LINE("{") + m_intendation++; + LINE("class " << LoaderClassName(m_env.m_asset) << " final : public AssetLoader") + LINE("{") + m_intendation++; + + LINE("XAssetInfo<"<m_definition->GetFullName()<<">* m_asset_info;") + if (m_env.m_has_actions) + { + LINE("Actions_"<m_definition->m_name<<" m_actions;") + } + LINE(VariableDecl(m_env.m_asset->m_definition)) + LINE(PointerVariableDecl(m_env.m_asset->m_definition)) + + // Variable Declarations: type varType; + for (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 (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 (auto* type : m_env.m_used_types) + { + if (type->m_pointer_array_reference_exists) + { + PrintHeaderPtrArrayLoadMethodDeclaration(type->m_type); + } + } + for (auto* type : m_env.m_used_types) + { + if (type->m_array_reference_exists && type->m_info && !type->m_info->m_is_leaf && type->m_non_runtime_reference_exists) + { + PrintHeaderArrayLoadMethodDeclaration(type->m_type); + } + } + for (auto* type : m_env.m_used_structures) + { + if (type->m_non_runtime_reference_exists && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset()) + { + PrintHeaderLoadMethodDeclaration(type->m_info); + } + } + PrintHeaderLoadMethodDeclaration(m_env.m_asset); + PrintHeaderTempPtrLoadMethodDeclaration(m_env.m_asset); + PrintHeaderAssetLoadMethodDeclaration(m_env.m_asset); + LINE("") + m_intendation--; + LINE("public:") + m_intendation++; + PrintHeaderConstructor(); + PrintHeaderMainLoadMethodDeclaration(m_env.m_asset); + PrintHeaderGetNameMethodDeclaration(m_env.m_asset); + + m_intendation--; + LINE("};") + m_intendation--; + LINE("}") + } + + void Source() + { + } +}; + std::vector ZoneLoadTemplate::GetFilesToRender(RenderingContext* context) { std::vector files; @@ -27,13 +196,18 @@ std::vector ZoneLoadTemplate::GetFilesToRender(RenderingContex void ZoneLoadTemplate::RenderFile(std::ostream& stream, const int fileTag, RenderingContext* context) { + Internal internal(stream, context); + if (fileTag == TAG_HEADER) { + internal.Header(); } else if (fileTag == TAG_SOURCE) { + internal.Source(); } else { + std::cout << "Unknown tag for ZoneLoadTemplate: " << fileTag << "\n"; } } diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.h b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.h index 5e9cafa9..b4c743a7 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.h +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.h @@ -6,6 +6,8 @@ class ZoneLoadTemplate final : public ICodeTemplate static constexpr int TAG_HEADER = 1; static constexpr int TAG_SOURCE = 2; + class Internal; + public: std::vector GetFilesToRender(RenderingContext* context) override; void RenderFile(std::ostream& stream, int fileTag, RenderingContext* context) override;