mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
add basis for code rendering
This commit is contained in:
parent
48afb4d514
commit
d4a98b7c52
@ -0,0 +1,126 @@
|
|||||||
|
#include "CodeGenerator.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#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<ZoneLoadTemplate>();
|
||||||
|
m_template_mapping["zonewrite"] = std::make_unique<ZoneWriteTemplate>();
|
||||||
|
m_template_mapping["assetstructtests"] = std::make_unique<AssetStructTestsTemplate>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<DefinitionWithMembers*>(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<StructureInformation*> 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<char>(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;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "ICodeTemplate.h"
|
||||||
|
#include "ZoneCodeGeneratorArguments.h"
|
||||||
|
|
||||||
|
class CodeGenerator
|
||||||
|
{
|
||||||
|
const ZoneCodeGeneratorArguments* m_args;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<ICodeTemplate>> 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);
|
||||||
|
};
|
34
src/ZoneCodeGeneratorLib/Generating/ICodeTemplate.h
Normal file
34
src/ZoneCodeGeneratorLib/Generating/ICodeTemplate.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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<CodeTemplateFile> GetFilesToRender(RenderingContext* context) = 0;
|
||||||
|
virtual void RenderFile(std::ostream& stream, int fileTag) = 0;
|
||||||
|
};
|
166
src/ZoneCodeGeneratorLib/Generating/RenderingContext.cpp
Normal file
166
src/ZoneCodeGeneratorLib/Generating/RenderingContext.cpp
Normal file
@ -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<const FastFileBlock*> 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<const TypedefDefinition*>(usedType->m_type);
|
||||||
|
|
||||||
|
while(typedefDefinition->m_type_declaration->m_type->GetType() == DataDefinitionType::TYPEDEF)
|
||||||
|
typedefDefinition = dynamic_cast<const TypedefDefinition*>(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<RenderingUsedType>(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<RenderingUsedType>(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<RenderingUsedType>(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> RenderingContext::BuildContext(const IDataRepository* repository, StructureInformation* asset)
|
||||||
|
{
|
||||||
|
auto context = std::make_unique<RenderingContext>(RenderingContext(repository->GetGameName(), repository->GetAllFastFileBlocks()));
|
||||||
|
|
||||||
|
context->MakeAsset(asset);
|
||||||
|
context->CreateUsedTypeCollections();
|
||||||
|
|
||||||
|
return std::move(context);
|
||||||
|
}
|
52
src/ZoneCodeGeneratorLib/Generating/RenderingContext.h
Normal file
52
src/ZoneCodeGeneratorLib/Generating/RenderingContext.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#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<const DataDefinition*, std::unique_ptr<RenderingUsedType>> m_used_types_lookup;
|
||||||
|
|
||||||
|
RenderingContext(std::string game, std::vector<const FastFileBlock*> fastFileBlocks);
|
||||||
|
|
||||||
|
RenderingUsedType* GetBaseType(RenderingUsedType* usedType);
|
||||||
|
void AddMembersToContext(StructureInformation* info);
|
||||||
|
void MakeAsset(StructureInformation* asset);
|
||||||
|
void CreateUsedTypeCollections();
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string m_game;
|
||||||
|
std::vector<const FastFileBlock*> m_blocks;
|
||||||
|
|
||||||
|
StructureInformation* m_asset;
|
||||||
|
|
||||||
|
std::vector<RenderingUsedType*> m_used_types;
|
||||||
|
std::vector<RenderingUsedType*> m_used_structures;
|
||||||
|
std::vector<RenderingUsedType*> m_referenced_assets;
|
||||||
|
bool m_has_actions;
|
||||||
|
|
||||||
|
const FastFileBlock* m_default_normal_block;
|
||||||
|
const FastFileBlock* m_default_temp_block;
|
||||||
|
|
||||||
|
static std::unique_ptr<RenderingContext> BuildContext(const IDataRepository* repository, StructureInformation* asset);
|
||||||
|
};
|
@ -0,0 +1,24 @@
|
|||||||
|
#include "AssetStructTestsTemplate.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
std::vector<CodeTemplateFile> AssetStructTestsTemplate::GetFilesToRender(RenderingContext* context)
|
||||||
|
{
|
||||||
|
std::vector<CodeTemplateFile> files;
|
||||||
|
|
||||||
|
auto assetName = context->m_asset->m_definition->m_name;
|
||||||
|
for (auto& c : assetName)
|
||||||
|
c = static_cast<char>(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)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Generating/ICodeTemplate.h"
|
||||||
|
|
||||||
|
class AssetStructTestsTemplate final : public ICodeTemplate
|
||||||
|
{
|
||||||
|
static constexpr int TAG_SOURCE = 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::vector<CodeTemplateFile> GetFilesToRender(RenderingContext* context) override;
|
||||||
|
void RenderFile(std::ostream& stream, int fileTag) override;
|
||||||
|
};
|
@ -0,0 +1,42 @@
|
|||||||
|
#include "ZoneLoadTemplate.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
std::vector<CodeTemplateFile> ZoneLoadTemplate::GetFilesToRender(RenderingContext* context)
|
||||||
|
{
|
||||||
|
std::vector<CodeTemplateFile> files;
|
||||||
|
|
||||||
|
auto assetName = context->m_asset->m_definition->m_name;
|
||||||
|
for (auto& c : assetName)
|
||||||
|
c = static_cast<char>(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";
|
||||||
|
}
|
||||||
|
}
|
@ -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<CodeTemplateFile> GetFilesToRender(RenderingContext* context) override;
|
||||||
|
void RenderFile(std::ostream& stream, int fileTag) override;
|
||||||
|
};
|
@ -0,0 +1,30 @@
|
|||||||
|
#include "ZoneWriteTemplate.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
std::vector<CodeTemplateFile> ZoneWriteTemplate::GetFilesToRender(RenderingContext* context)
|
||||||
|
{
|
||||||
|
std::vector<CodeTemplateFile> files;
|
||||||
|
|
||||||
|
auto assetName = context->m_asset->m_definition->m_name;
|
||||||
|
for (auto& c : assetName)
|
||||||
|
c = static_cast<char>(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)
|
||||||
|
{
|
||||||
|
}
|
@ -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<CodeTemplateFile> GetFilesToRender(RenderingContext* context) override;
|
||||||
|
void RenderFile(std::ostream& stream, int fileTag) override;
|
||||||
|
};
|
@ -38,10 +38,10 @@ public:
|
|||||||
_NODISCARD virtual const std::vector<UnionDefinition*>& GetAllUnions() const = 0;
|
_NODISCARD virtual const std::vector<UnionDefinition*>& GetAllUnions() const = 0;
|
||||||
_NODISCARD virtual const std::vector<TypedefDefinition*>& GetAllTypedefs() const = 0;
|
_NODISCARD virtual const std::vector<TypedefDefinition*>& GetAllTypedefs() const = 0;
|
||||||
_NODISCARD virtual const std::vector<StructureInformation*>& GetAllStructureInformation() const = 0;
|
_NODISCARD virtual const std::vector<StructureInformation*>& GetAllStructureInformation() const = 0;
|
||||||
_NODISCARD virtual const std::vector<FastFileBlock*>& GetAllFastFileBlocks() const = 0;
|
_NODISCARD virtual const std::vector<const FastFileBlock*>& GetAllFastFileBlocks() const = 0;
|
||||||
|
|
||||||
_NODISCARD virtual DataDefinition* GetDataDefinitionByName(const std::string& name) const = 0;
|
_NODISCARD virtual DataDefinition* GetDataDefinitionByName(const std::string& name) const = 0;
|
||||||
_NODISCARD virtual StructureInformation* GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const = 0;
|
_NODISCARD virtual StructureInformation* GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const = 0;
|
||||||
_NODISCARD virtual EnumMember* GetEnumMemberByName(const std::string& name) 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;
|
||||||
};
|
};
|
||||||
|
@ -17,7 +17,7 @@ InMemoryRepository::~InMemoryRepository()
|
|||||||
delete typedefDefinition;
|
delete typedefDefinition;
|
||||||
for (auto* structureInformation : m_structures_information)
|
for (auto* structureInformation : m_structures_information)
|
||||||
delete structureInformation;
|
delete structureInformation;
|
||||||
for (auto* fastFileBlock : m_fast_file_blocks)
|
for (const auto* fastFileBlock : m_fast_file_blocks)
|
||||||
delete fastFileBlock;
|
delete fastFileBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ const std::vector<StructureInformation*>& InMemoryRepository::GetAllStructureInf
|
|||||||
return m_structures_information;
|
return m_structures_information;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<FastFileBlock*>& InMemoryRepository::GetAllFastFileBlocks() const
|
const std::vector<const FastFileBlock*>& InMemoryRepository::GetAllFastFileBlocks() const
|
||||||
{
|
{
|
||||||
return m_fast_file_blocks;
|
return m_fast_file_blocks;
|
||||||
}
|
}
|
||||||
@ -146,7 +146,7 @@ EnumMember* InMemoryRepository::GetEnumMemberByName(const std::string& name) con
|
|||||||
return nullptr;
|
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);
|
const auto foundEntry = m_fast_file_blocks_by_name.find(name);
|
||||||
|
|
||||||
|
@ -11,10 +11,10 @@ class InMemoryRepository final : public IDataRepository
|
|||||||
std::vector<UnionDefinition*> m_unions;
|
std::vector<UnionDefinition*> m_unions;
|
||||||
std::vector<TypedefDefinition*> m_typedefs;
|
std::vector<TypedefDefinition*> m_typedefs;
|
||||||
std::vector<StructureInformation*> m_structures_information;
|
std::vector<StructureInformation*> m_structures_information;
|
||||||
std::vector<FastFileBlock*> m_fast_file_blocks;
|
std::vector<const FastFileBlock*> m_fast_file_blocks;
|
||||||
std::map<std::string, DataDefinition*> m_data_definitions_by_name;
|
std::map<std::string, DataDefinition*> m_data_definitions_by_name;
|
||||||
std::map<std::string, EnumMember*> m_enum_members_by_name;
|
std::map<std::string, EnumMember*> m_enum_members_by_name;
|
||||||
std::map<std::string, FastFileBlock*> m_fast_file_blocks_by_name;
|
std::map<std::string, const FastFileBlock*> m_fast_file_blocks_by_name;
|
||||||
std::map<const DefinitionWithMembers*, StructureInformation*> m_structure_information_by_definition;
|
std::map<const DefinitionWithMembers*, StructureInformation*> m_structure_information_by_definition;
|
||||||
std::string m_game_name;
|
std::string m_game_name;
|
||||||
Architecture m_architecture;
|
Architecture m_architecture;
|
||||||
@ -44,10 +44,10 @@ public:
|
|||||||
_NODISCARD const std::vector<UnionDefinition*>& GetAllUnions() const override;
|
_NODISCARD const std::vector<UnionDefinition*>& GetAllUnions() const override;
|
||||||
_NODISCARD const std::vector<TypedefDefinition*>& GetAllTypedefs() const override;
|
_NODISCARD const std::vector<TypedefDefinition*>& GetAllTypedefs() const override;
|
||||||
_NODISCARD const std::vector<StructureInformation*>& GetAllStructureInformation() const override;
|
_NODISCARD const std::vector<StructureInformation*>& GetAllStructureInformation() const override;
|
||||||
_NODISCARD const std::vector<FastFileBlock*>& GetAllFastFileBlocks() const override;
|
_NODISCARD const std::vector<const FastFileBlock*>& GetAllFastFileBlocks() const override;
|
||||||
|
|
||||||
_NODISCARD DataDefinition* GetDataDefinitionByName(const std::string& name) const override;
|
_NODISCARD DataDefinition* GetDataDefinitionByName(const std::string& name) const override;
|
||||||
_NODISCARD StructureInformation* GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const override;
|
_NODISCARD StructureInformation* GetInformationFor(const DefinitionWithMembers* definitionWithMembers) const override;
|
||||||
_NODISCARD EnumMember* GetEnumMemberByName(const std::string& name) 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;
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "ZoneCodeGeneratorArguments.h"
|
#include "ZoneCodeGeneratorArguments.h"
|
||||||
|
#include "Generating/CodeGenerator.h"
|
||||||
#include "Parsing/Commands/CommandsFileReader.h"
|
#include "Parsing/Commands/CommandsFileReader.h"
|
||||||
#include "Parsing/Header/HeaderFileReader.h"
|
#include "Parsing/Header/HeaderFileReader.h"
|
||||||
#include "Persistence/IDataRepository.h"
|
#include "Persistence/IDataRepository.h"
|
||||||
@ -49,15 +50,10 @@ class ZoneCodeGenerator::Impl
|
|||||||
prettyPrinter.PrintAll();
|
prettyPrinter.PrintAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateCode()
|
_NODISCARD bool GenerateCode() const
|
||||||
{
|
{
|
||||||
for(const auto& generationTask : m_args.m_generation_tasks)
|
CodeGenerator codeGenerator(&m_args);
|
||||||
{
|
return codeGenerator.GenerateCode(m_repository.get());
|
||||||
// TODO: Implement
|
|
||||||
std::cout << "Generating code for asset \"" << generationTask.m_asset_name << "\" and preset \"" << generationTask.m_preset_name << "\" ..." << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -85,11 +85,20 @@ const CommandLineOption* const COMMAND_LINE_OPTIONS[]
|
|||||||
};
|
};
|
||||||
|
|
||||||
ZoneCodeGeneratorArguments::GenerationTask::GenerationTask()
|
ZoneCodeGeneratorArguments::GenerationTask::GenerationTask()
|
||||||
= default;
|
: m_all_assets(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ZoneCodeGeneratorArguments::GenerationTask::GenerationTask(std::string assetName, std::string presetName)
|
ZoneCodeGeneratorArguments::GenerationTask::GenerationTask(std::string templateName)
|
||||||
: m_asset_name(std::move(assetName)),
|
: m_all_assets(true),
|
||||||
m_preset_name(std::move(presetName))
|
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;
|
m_task_flags |= FLAG_TASK_GENERATE;
|
||||||
const auto generateParameterValues = m_argument_parser.GetParametersForOption(OPTION_GENERATE);
|
const auto generateParameterValues = m_argument_parser.GetParametersForOption(OPTION_GENERATE);
|
||||||
for (auto i = 0u; i < generateParameterValues.size(); i += 2)
|
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)
|
if (m_task_flags == 0)
|
||||||
|
@ -21,11 +21,13 @@ public:
|
|||||||
class GenerationTask
|
class GenerationTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool m_all_assets;
|
||||||
std::string m_asset_name;
|
std::string m_asset_name;
|
||||||
std::string m_preset_name;
|
std::string m_template_name;
|
||||||
|
|
||||||
GenerationTask();
|
GenerationTask();
|
||||||
GenerationTask(std::string assetName, std::string presetName);
|
explicit GenerationTask(std::string templateName);
|
||||||
|
GenerationTask(std::string assetName, std::string templateName);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool m_verbose;
|
bool m_verbose;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user