From d4a98b7c528e7777539f828eab67ebe162277810 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 20 Feb 2021 02:33:40 +0100 Subject: [PATCH] add basis for code rendering --- .../Generating/CodeGenerator.cpp | 126 +++++++++++++ .../Generating/CodeGenerator.h | 23 +++ .../Generating/ICodeTemplate.h | 34 ++++ .../Generating/RenderingContext.cpp | 166 ++++++++++++++++++ .../Generating/RenderingContext.h | 52 ++++++ .../Templates/AssetStructTestsTemplate.cpp | 24 +++ .../Templates/AssetStructTestsTemplate.h | 11 ++ .../Generating/Templates/ZoneLoadTemplate.cpp | 42 +++++ .../Generating/Templates/ZoneLoadTemplate.h | 12 ++ .../Templates/ZoneWriteTemplate.cpp | 30 ++++ .../Generating/Templates/ZoneWriteTemplate.h | 12 ++ .../Persistence/IDataRepository.h | 4 +- .../InMemory/InMemoryRepository.cpp | 6 +- .../Persistence/InMemory/InMemoryRepository.h | 8 +- .../ZoneCodeGenerator.cpp | 12 +- .../ZoneCodeGeneratorArguments.cpp | 27 ++- .../ZoneCodeGeneratorArguments.h | 6 +- 17 files changed, 571 insertions(+), 24 deletions(-) create mode 100644 src/ZoneCodeGeneratorLib/Generating/ICodeTemplate.h create mode 100644 src/ZoneCodeGeneratorLib/Generating/RenderingContext.cpp create mode 100644 src/ZoneCodeGeneratorLib/Generating/RenderingContext.h create mode 100644 src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp create mode 100644 src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.h create mode 100644 src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp create mode 100644 src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.h create mode 100644 src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp create mode 100644 src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.h diff --git a/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.cpp b/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.cpp index e69de29b..4dfbedb5 100644 --- a/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.cpp @@ -0,0 +1,126 @@ +#include "CodeGenerator.h" + +#include +#include +#include + +#include "Domain/Computations/StructureComputations.h" +#include "Templates/AssetStructTestsTemplate.h" +#include "Templates/ZoneLoadTemplate.h" +#include "Templates/ZoneWriteTemplate.h" + +namespace fs = std::filesystem; + +CodeGenerator::CodeGenerator(const ZoneCodeGeneratorArguments* args) + : m_args(args) +{ + SetupTemplates(); +} + +void CodeGenerator::SetupTemplates() +{ + m_template_mapping["zoneload"] = std::make_unique(); + m_template_mapping["zonewrite"] = std::make_unique(); + m_template_mapping["assetstructtests"] = std::make_unique(); +} + +bool CodeGenerator::GenerateCodeForTemplate(RenderingContext* context, ICodeTemplate* codeTemplate) const +{ + for (const auto& codeFile : codeTemplate->GetFilesToRender(context)) + { + fs::path p(m_args->m_output_directory); + p.append(codeFile.m_file_name); + + auto parentFolder(p); + parentFolder.remove_filename(); + create_directories(parentFolder); + + std::ofstream stream(p, std::fstream::out | std::fstream::binary); + + if (!stream.is_open()) + { + std::cout << "Failed to open file '" << p.string() << "'" << std::endl; + return false; + } + + codeTemplate->RenderFile(stream, codeFile.m_tag); + + stream.close(); + } + + return true; +} + +bool CodeGenerator::GetAssetWithName(IDataRepository* repository, const std::string& name, StructureInformation*& asset) +{ + auto* def = repository->GetDataDefinitionByName(name); + if (def == nullptr) + { + std::cout << "Could not find type with name '" << name << "'" << std::endl; + return false; + } + + auto* defWithMembers = dynamic_cast(def); + auto* info = defWithMembers != nullptr ? repository->GetInformationFor(defWithMembers) : nullptr; + if (info == nullptr) + { + std::cout << "Could not find type with name '" << name << "'" << std::endl; + return false; + } + + if(!StructureComputations(info).IsAsset()) + { + std::cout << "Type is not an asset '" << name << "'" << std::endl; + return false; + } + + return true; +} + +bool CodeGenerator::GenerateCode(IDataRepository* repository) +{ + std::vector assets; + + for (auto* info : repository->GetAllStructureInformation()) + { + StructureComputations computations(info); + if (computations.IsAsset()) + assets.push_back(info); + } + + for (const auto& generationTask : m_args->m_generation_tasks) + { + auto templateName = generationTask.m_template_name; + for (auto& c : templateName) + c = static_cast(tolower(c)); + + const auto foundTemplate = m_template_mapping.find(templateName); + if (foundTemplate == m_template_mapping.end()) + { + std::cout << "Unknown template '" << generationTask.m_template_name << "'." << std::endl; + return false; + } + + if (generationTask.m_all_assets) + { + for (auto* asset : assets) + { + auto context = RenderingContext::BuildContext(repository, asset); + if (!GenerateCodeForTemplate(context.get(), foundTemplate->second.get())) + return false; + } + } + else + { + StructureInformation* asset; + if (!GetAssetWithName(repository, generationTask.m_asset_name, asset)) + return false; + + auto context = RenderingContext::BuildContext(repository, asset); + if (!GenerateCodeForTemplate(context.get(), foundTemplate->second.get())) + return false; + } + } + + return true; +} diff --git a/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.h b/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.h index e69de29b..aee80023 100644 --- a/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.h +++ b/src/ZoneCodeGeneratorLib/Generating/CodeGenerator.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "ICodeTemplate.h" +#include "ZoneCodeGeneratorArguments.h" + +class CodeGenerator +{ + const ZoneCodeGeneratorArguments* m_args; + + std::unordered_map> m_template_mapping; + + void SetupTemplates(); + + bool GenerateCodeForTemplate(RenderingContext* context, ICodeTemplate* codeTemplate) const; + static bool GetAssetWithName(IDataRepository* repository, const std::string& name, StructureInformation*& asset); + +public: + explicit CodeGenerator(const ZoneCodeGeneratorArguments* args); + + bool GenerateCode(IDataRepository* repository); +}; diff --git a/src/ZoneCodeGeneratorLib/Generating/ICodeTemplate.h b/src/ZoneCodeGeneratorLib/Generating/ICodeTemplate.h new file mode 100644 index 00000000..0059843b --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/ICodeTemplate.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include + +#include "RenderingContext.h" + +class CodeTemplateFile +{ +public: + std::string m_file_name; + int m_tag; + + CodeTemplateFile(std::string fileName, const int tag) + : m_file_name(std::move(fileName)), + m_tag(tag) + { + } +}; + +class ICodeTemplate +{ +public: + ICodeTemplate() = default; + virtual ~ICodeTemplate() = default; + ICodeTemplate(const ICodeTemplate& other) = default; + ICodeTemplate(ICodeTemplate&& other) noexcept = default; + ICodeTemplate& operator=(const ICodeTemplate& other) = default; + ICodeTemplate& operator=(ICodeTemplate&& other) noexcept = default; + + virtual std::vector GetFilesToRender(RenderingContext* context) = 0; + virtual void RenderFile(std::ostream& stream, int fileTag) = 0; +}; diff --git a/src/ZoneCodeGeneratorLib/Generating/RenderingContext.cpp b/src/ZoneCodeGeneratorLib/Generating/RenderingContext.cpp new file mode 100644 index 00000000..d696fbd9 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/RenderingContext.cpp @@ -0,0 +1,166 @@ +#include "RenderingContext.h" + +#include "Domain/Computations/MemberComputations.h" +#include "Domain/Computations/StructureComputations.h" + +RenderingUsedType::RenderingUsedType(const DataDefinition* type, StructureInformation* info) + : m_members_loaded(false), + m_type(type), + m_info(info), + m_is_context_asset(false), + m_non_runtime_reference_exists(false), + m_non_embedded_reference_exists(false), + m_array_reference_exists(false), + m_pointer_array_reference_exists(false), + m_pointer_array_reference_is_reusable(false) +{ +} + +RenderingContext::RenderingContext(std::string game, std::vector fastFileBlocks) + : m_game(std::move(game)), + m_blocks(std::move(fastFileBlocks)), + m_asset(nullptr), + m_has_actions(false), + m_default_normal_block(nullptr), + m_default_temp_block(nullptr) +{ + for (const auto* block : m_blocks) + { + if (block->m_is_default) + { + if (block->m_type == FastFileBlockType::NORMAL && m_default_normal_block == nullptr) + m_default_normal_block = block; + else if (block->m_type == FastFileBlockType::TEMP && m_default_temp_block == nullptr) + m_default_temp_block = block; + } + } +} + +RenderingUsedType* RenderingContext::GetBaseType(RenderingUsedType* usedType) +{ + if(usedType->m_type->GetType() == DataDefinitionType::TYPEDEF) + { + const auto* typedefDefinition = dynamic_cast(usedType->m_type); + + while(typedefDefinition->m_type_declaration->m_type->GetType() == DataDefinitionType::TYPEDEF) + typedefDefinition = dynamic_cast(typedefDefinition->m_type_declaration->m_type); + + const auto foundUsedType = m_used_types_lookup.find(typedefDefinition); + if(foundUsedType == m_used_types_lookup.end()) + { + auto usedTypePtr = std::make_unique(typedefDefinition->m_type_declaration->m_type, nullptr); + auto* result = usedTypePtr.get(); + m_used_types_lookup.emplace(std::make_pair(usedTypePtr->m_type, std::move(usedTypePtr))); + + return result; + } + + return foundUsedType->second.get(); + } + + return nullptr; +} + +void RenderingContext::AddMembersToContext(StructureInformation* info) +{ + for(const auto& member : info->m_ordered_members) + { + MemberComputations computations(member.get()); + + if(computations.ShouldIgnore()) + continue; + + RenderingUsedType* usedType; + const auto existingUsedType = m_used_types_lookup.find(member->m_member->m_type_declaration->m_type); + if(existingUsedType == m_used_types_lookup.end()) + { + auto usedTypePtr = std::make_unique(member->m_member->m_type_declaration->m_type, member->m_type); + usedType = usedTypePtr.get(); + m_used_types_lookup.emplace(std::make_pair(usedTypePtr->m_type, std::move(usedTypePtr))); + } + else + { + usedType = existingUsedType->second.get(); + } + + auto* baseUsedType = GetBaseType(usedType); + + if(!computations.IsInRuntimeBlock()) + { + usedType->m_non_runtime_reference_exists = true; + + if (baseUsedType != nullptr) + baseUsedType->m_non_runtime_reference_exists = true; + } + + if (computations.ContainsNonEmbeddedReference()) + usedType->m_non_embedded_reference_exists = true; + + if (computations.ContainsArrayPointerReference() || computations.ContainsArrayReference()) + usedType->m_array_reference_exists = true; + + if(computations.ContainsPointerArrayReference() && !member->m_is_string) + { + usedType->m_pointer_array_reference_exists = true; + + if (member->m_is_reusable) + usedType->m_pointer_array_reference_is_reusable = true; + } + + if(usedType->m_info != nullptr && StructureComputations(usedType->m_info).IsAsset() && !computations.IsInRuntimeBlock() && !usedType->m_members_loaded) + { + usedType->m_members_loaded = true; + AddMembersToContext(usedType->m_info); + } + } +} + +void RenderingContext::MakeAsset(StructureInformation* asset) +{ + m_asset = asset; + auto assetUsedType = std::make_unique(asset->m_definition, asset); + assetUsedType->m_is_context_asset = true; + m_used_types_lookup.emplace(std::make_pair(asset->m_definition, std::move(assetUsedType))); + + AddMembersToContext(asset); +} + +void RenderingContext::CreateUsedTypeCollections() +{ + for(const auto& [dataDef, usedType] : m_used_types_lookup) + { + m_used_types.push_back(usedType.get()); + + if (usedType->m_info != nullptr) + { + StructureComputations computations(usedType->m_info); + + if(usedType->m_info->m_definition == dataDef) + m_used_structures.push_back(usedType.get()); + + if(computations.IsAsset() && usedType->m_info != m_asset) + m_referenced_assets.push_back(usedType.get()); + + if (!m_has_actions) + { + if ((!computations.IsAsset() || usedType->m_is_context_asset) + && usedType->m_non_runtime_reference_exists + && usedType->m_info->m_post_load_action) + { + m_has_actions = true; + } + } + } + + } +} + +std::unique_ptr RenderingContext::BuildContext(const IDataRepository* repository, StructureInformation* asset) +{ + auto context = std::make_unique(RenderingContext(repository->GetGameName(), repository->GetAllFastFileBlocks())); + + context->MakeAsset(asset); + context->CreateUsedTypeCollections(); + + return std::move(context); +} diff --git a/src/ZoneCodeGeneratorLib/Generating/RenderingContext.h b/src/ZoneCodeGeneratorLib/Generating/RenderingContext.h new file mode 100644 index 00000000..37a2bc5a --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/RenderingContext.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include + +#include "Domain/Information/StructureInformation.h" +#include "Persistence/IDataRepository.h" + +class RenderingUsedType +{ +public: + bool m_members_loaded; + const DataDefinition* m_type; + StructureInformation* m_info; + bool m_is_context_asset; + + bool m_non_runtime_reference_exists; + bool m_non_embedded_reference_exists; + bool m_array_reference_exists; + bool m_pointer_array_reference_exists; + bool m_pointer_array_reference_is_reusable; + + RenderingUsedType(const DataDefinition* type, StructureInformation* info); +}; + +class RenderingContext +{ + std::unordered_map> m_used_types_lookup; + + RenderingContext(std::string game, std::vector fastFileBlocks); + + RenderingUsedType* GetBaseType(RenderingUsedType* usedType); + void AddMembersToContext(StructureInformation* info); + void MakeAsset(StructureInformation* asset); + void CreateUsedTypeCollections(); + +public: + std::string m_game; + std::vector m_blocks; + + StructureInformation* m_asset; + + std::vector m_used_types; + std::vector m_used_structures; + std::vector m_referenced_assets; + bool m_has_actions; + + const FastFileBlock* m_default_normal_block; + const FastFileBlock* m_default_temp_block; + + static std::unique_ptr BuildContext(const IDataRepository* repository, StructureInformation* asset); +}; diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp new file mode 100644 index 00000000..d1e456c4 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.cpp @@ -0,0 +1,24 @@ +#include "AssetStructTestsTemplate.h" + +#include + +std::vector AssetStructTestsTemplate::GetFilesToRender(RenderingContext* context) +{ + std::vector files; + + auto assetName = context->m_asset->m_definition->m_name; + for (auto& c : assetName) + c = static_cast(tolower(c)); + + { + std::ostringstream str; + str << assetName << '/' << assetName << "_struct_test.cpp"; + files.emplace_back(str.str(), TAG_SOURCE); + } + + return files; +} + +void AssetStructTestsTemplate::RenderFile(std::ostream& stream, int fileTag) +{ +} diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.h b/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.h new file mode 100644 index 00000000..f371f0cd --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/AssetStructTestsTemplate.h @@ -0,0 +1,11 @@ +#pragma once +#include "Generating/ICodeTemplate.h" + +class AssetStructTestsTemplate final : public ICodeTemplate +{ + static constexpr int TAG_SOURCE = 1; + +public: + std::vector GetFilesToRender(RenderingContext* context) override; + void RenderFile(std::ostream& stream, int fileTag) override; +}; diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp new file mode 100644 index 00000000..d5c885c3 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp @@ -0,0 +1,42 @@ +#include "ZoneLoadTemplate.h" + +#include + +std::vector ZoneLoadTemplate::GetFilesToRender(RenderingContext* context) +{ + std::vector files; + + auto assetName = context->m_asset->m_definition->m_name; + for (auto& c : assetName) + c = static_cast(tolower(c)); + + { + std::ostringstream str; + str << assetName << '/' << assetName << "_load_db.h"; + files.emplace_back(str.str(), TAG_HEADER); + } + + { + std::ostringstream str; + str << assetName << '/' << assetName << "_load_db.cpp"; + files.emplace_back(str.str(), TAG_SOURCE); + } + + return files; +} + +void ZoneLoadTemplate::RenderFile(std::ostream& stream, const int fileTag) +{ + if (fileTag == TAG_HEADER) + { + stream << "Header"; + } + else if (fileTag == TAG_SOURCE) + { + stream << "Source"; + } + else + { + stream << "Unknown"; + } +} diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.h b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.h new file mode 100644 index 00000000..aebf2adb --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.h @@ -0,0 +1,12 @@ +#pragma once +#include "Generating/ICodeTemplate.h" + +class ZoneLoadTemplate final : public ICodeTemplate +{ + static constexpr int TAG_HEADER = 1; + static constexpr int TAG_SOURCE = 2; + +public: + std::vector GetFilesToRender(RenderingContext* context) override; + void RenderFile(std::ostream& stream, int fileTag) override; +}; diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp new file mode 100644 index 00000000..dad3e266 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp @@ -0,0 +1,30 @@ +#include "ZoneWriteTemplate.h" + +#include + +std::vector ZoneWriteTemplate::GetFilesToRender(RenderingContext* context) +{ + std::vector files; + + auto assetName = context->m_asset->m_definition->m_name; + for (auto& c : assetName) + c = static_cast(tolower(c)); + + { + std::ostringstream str; + str << assetName << '/' << assetName << "_write_db.h"; + files.emplace_back(str.str(), TAG_HEADER); + } + + { + std::ostringstream str; + str << assetName << '/' << assetName << "_write_db.cpp"; + files.emplace_back(str.str(), TAG_SOURCE); + } + + return files; +} + +void ZoneWriteTemplate::RenderFile(std::ostream& stream, const int fileTag) +{ +} diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.h b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.h new file mode 100644 index 00000000..4888f216 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.h @@ -0,0 +1,12 @@ +#pragma once +#include "Generating/ICodeTemplate.h" + +class ZoneWriteTemplate final : public ICodeTemplate +{ + static constexpr int TAG_HEADER = 1; + static constexpr int TAG_SOURCE = 2; + +public: + std::vector GetFilesToRender(RenderingContext* context) override; + void RenderFile(std::ostream& stream, int fileTag) override; +}; diff --git a/src/ZoneCodeGeneratorLib/Persistence/IDataRepository.h b/src/ZoneCodeGeneratorLib/Persistence/IDataRepository.h index 2cfd1c5a..8bb6758b 100644 --- a/src/ZoneCodeGeneratorLib/Persistence/IDataRepository.h +++ b/src/ZoneCodeGeneratorLib/Persistence/IDataRepository.h @@ -38,10 +38,10 @@ public: _NODISCARD virtual const std::vector& GetAllUnions() const = 0; _NODISCARD virtual const std::vector& GetAllTypedefs() const = 0; _NODISCARD virtual const std::vector& GetAllStructureInformation() const = 0; - _NODISCARD virtual const std::vector& GetAllFastFileBlocks() const = 0; + _NODISCARD virtual const std::vector& GetAllFastFileBlocks() const = 0; _NODISCARD virtual DataDefinition* GetDataDefinitionByName(const std::string& name) const = 0; _NODISCARD virtual StructureInformation* GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const = 0; _NODISCARD virtual EnumMember* GetEnumMemberByName(const std::string& name) const = 0; - _NODISCARD virtual FastFileBlock* GetFastFileBlockByName(const std::string& name) const = 0; + _NODISCARD virtual const FastFileBlock* GetFastFileBlockByName(const std::string& name) const = 0; }; diff --git a/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.cpp b/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.cpp index 0b70cdd3..62cd54f3 100644 --- a/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.cpp +++ b/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.cpp @@ -17,7 +17,7 @@ InMemoryRepository::~InMemoryRepository() delete typedefDefinition; for (auto* structureInformation : m_structures_information) delete structureInformation; - for (auto* fastFileBlock : m_fast_file_blocks) + for (const auto* fastFileBlock : m_fast_file_blocks) delete fastFileBlock; } @@ -111,7 +111,7 @@ const std::vector& InMemoryRepository::GetAllStructureInf return m_structures_information; } -const std::vector& InMemoryRepository::GetAllFastFileBlocks() const +const std::vector& InMemoryRepository::GetAllFastFileBlocks() const { return m_fast_file_blocks; } @@ -146,7 +146,7 @@ EnumMember* InMemoryRepository::GetEnumMemberByName(const std::string& name) con return nullptr; } -FastFileBlock* InMemoryRepository::GetFastFileBlockByName(const std::string& name) const +const FastFileBlock* InMemoryRepository::GetFastFileBlockByName(const std::string& name) const { const auto foundEntry = m_fast_file_blocks_by_name.find(name); diff --git a/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.h b/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.h index 389fab37..3ba5566d 100644 --- a/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.h +++ b/src/ZoneCodeGeneratorLib/Persistence/InMemory/InMemoryRepository.h @@ -11,10 +11,10 @@ class InMemoryRepository final : public IDataRepository std::vector m_unions; std::vector m_typedefs; std::vector m_structures_information; - std::vector m_fast_file_blocks; + std::vector m_fast_file_blocks; std::map m_data_definitions_by_name; std::map m_enum_members_by_name; - std::map m_fast_file_blocks_by_name; + std::map m_fast_file_blocks_by_name; std::map m_structure_information_by_definition; std::string m_game_name; Architecture m_architecture; @@ -44,10 +44,10 @@ public: _NODISCARD const std::vector& GetAllUnions() const override; _NODISCARD const std::vector& GetAllTypedefs() const override; _NODISCARD const std::vector& GetAllStructureInformation() const override; - _NODISCARD const std::vector& GetAllFastFileBlocks() const override; + _NODISCARD const std::vector& GetAllFastFileBlocks() const override; _NODISCARD DataDefinition* GetDataDefinitionByName(const std::string& name) const override; _NODISCARD StructureInformation* GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const override; _NODISCARD EnumMember* GetEnumMemberByName(const std::string& name) const override; - _NODISCARD FastFileBlock* GetFastFileBlockByName(const std::string& name) const override; + _NODISCARD const FastFileBlock* GetFastFileBlockByName(const std::string& name) const override; }; diff --git a/src/ZoneCodeGeneratorLib/ZoneCodeGenerator.cpp b/src/ZoneCodeGeneratorLib/ZoneCodeGenerator.cpp index 5d69e27d..ac4186e0 100644 --- a/src/ZoneCodeGeneratorLib/ZoneCodeGenerator.cpp +++ b/src/ZoneCodeGeneratorLib/ZoneCodeGenerator.cpp @@ -6,6 +6,7 @@ #include #include "ZoneCodeGeneratorArguments.h" +#include "Generating/CodeGenerator.h" #include "Parsing/Commands/CommandsFileReader.h" #include "Parsing/Header/HeaderFileReader.h" #include "Persistence/IDataRepository.h" @@ -49,15 +50,10 @@ class ZoneCodeGenerator::Impl prettyPrinter.PrintAll(); } - bool GenerateCode() + _NODISCARD bool GenerateCode() const { - for(const auto& generationTask : m_args.m_generation_tasks) - { - // TODO: Implement - std::cout << "Generating code for asset \"" << generationTask.m_asset_name << "\" and preset \"" << generationTask.m_preset_name << "\" ..." << std::endl; - } - - return true; + CodeGenerator codeGenerator(&m_args); + return codeGenerator.GenerateCode(m_repository.get()); } public: diff --git a/src/ZoneCodeGeneratorLib/ZoneCodeGeneratorArguments.cpp b/src/ZoneCodeGeneratorLib/ZoneCodeGeneratorArguments.cpp index bc76abe9..ccf778ef 100644 --- a/src/ZoneCodeGeneratorLib/ZoneCodeGeneratorArguments.cpp +++ b/src/ZoneCodeGeneratorLib/ZoneCodeGeneratorArguments.cpp @@ -85,11 +85,20 @@ const CommandLineOption* const COMMAND_LINE_OPTIONS[] }; ZoneCodeGeneratorArguments::GenerationTask::GenerationTask() -= default; + : m_all_assets(false) +{ +} -ZoneCodeGeneratorArguments::GenerationTask::GenerationTask(std::string assetName, std::string presetName) - : m_asset_name(std::move(assetName)), - m_preset_name(std::move(presetName)) +ZoneCodeGeneratorArguments::GenerationTask::GenerationTask(std::string templateName) + : m_all_assets(true), + m_template_name(std::move(templateName)) +{ +} + +ZoneCodeGeneratorArguments::GenerationTask::GenerationTask(std::string assetName, std::string templateName) + : m_all_assets(false), + m_asset_name(std::move(assetName)), + m_template_name(std::move(templateName)) { } @@ -169,7 +178,15 @@ bool ZoneCodeGeneratorArguments::Parse(const int argc, const char** argv) m_task_flags |= FLAG_TASK_GENERATE; const auto generateParameterValues = m_argument_parser.GetParametersForOption(OPTION_GENERATE); for (auto i = 0u; i < generateParameterValues.size(); i += 2) - m_generation_tasks.emplace_back(generateParameterValues[i], generateParameterValues[i + 1]); + { + const auto& assetName = generateParameterValues[i]; + const auto& templateName = generateParameterValues[i + 1]; + + if (assetName == "*") + m_generation_tasks.emplace_back(templateName); + else + m_generation_tasks.emplace_back(assetName, templateName); + } } if (m_task_flags == 0) diff --git a/src/ZoneCodeGeneratorLib/ZoneCodeGeneratorArguments.h b/src/ZoneCodeGeneratorLib/ZoneCodeGeneratorArguments.h index 302879de..286e5e68 100644 --- a/src/ZoneCodeGeneratorLib/ZoneCodeGeneratorArguments.h +++ b/src/ZoneCodeGeneratorLib/ZoneCodeGeneratorArguments.h @@ -21,11 +21,13 @@ public: class GenerationTask { public: + bool m_all_assets; std::string m_asset_name; - std::string m_preset_name; + std::string m_template_name; GenerationTask(); - GenerationTask(std::string assetName, std::string presetName); + explicit GenerationTask(std::string templateName); + GenerationTask(std::string assetName, std::string templateName); }; bool m_verbose;