mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-10-23 20:18:10 +00:00
feat: add possibility to only include structs in zcg for certain variants
This commit is contained in:
12 files changed
+124
-4
No files matched your search
@@ -1,7 +1,8 @@
|
||||
#include "GameVariant.h"
|
||||
|
||||
GameVariant::GameVariant(std::string name, const WordSize wordSize, const std::endian endianness)
|
||||
: m_name(std::move(name)),
|
||||
GameVariant::GameVariant(const unsigned index, std::string name, const WordSize wordSize, const std::endian endianness)
|
||||
: m_index(index),
|
||||
m_name(std::move(name)),
|
||||
m_word_size(wordSize),
|
||||
m_endianness(endianness)
|
||||
{
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
class GameVariant
|
||||
{
|
||||
public:
|
||||
GameVariant(std::string name, WordSize wordSize, std::endian endianness);
|
||||
GameVariant(unsigned index, std::string name, WordSize wordSize, std::endian endianness);
|
||||
|
||||
unsigned m_index;
|
||||
std::string m_name;
|
||||
WordSize m_word_size;
|
||||
std::endian m_endianness;
|
||||
|
||||
@@ -16,3 +16,8 @@ StructureInformation::StructureInformation(DefinitionWithMembers* definition, Ty
|
||||
m_block(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
bool StructureInformation::IsIncludedForVariant(const unsigned variantIndex) const
|
||||
{
|
||||
return m_variants.empty() || m_variants.contains(variantIndex);
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "TypeInformation.h"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
class MemberInformation;
|
||||
@@ -17,10 +18,17 @@ class StructureInformation
|
||||
public:
|
||||
StructureInformation(DefinitionWithMembers* definition, TypeInformation* typeInfo);
|
||||
|
||||
[[nodiscard]] bool IsIncludedForVariant(unsigned variantIndex) const;
|
||||
|
||||
DefinitionWithMembers* m_definition;
|
||||
TypeInformation* m_type_info;
|
||||
std::string m_asset_name;
|
||||
|
||||
/**
|
||||
* All variants this structure should be included in. If empty, it should be included in all variants.
|
||||
*/
|
||||
std::unordered_set<unsigned> m_variants;
|
||||
|
||||
std::unique_ptr<IEvaluation> m_alloc_alignment;
|
||||
std::vector<StructureInformation*> m_usages;
|
||||
std::vector<std::unique_ptr<MemberInformation>> m_ordered_members;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <filesystem>
|
||||
#include <format>
|
||||
#include <fstream>
|
||||
#include <variant>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -195,6 +196,9 @@ bool CodeGenerator::GenerateCode(const IDataRepository* repository)
|
||||
{
|
||||
for (auto* asset : assets)
|
||||
{
|
||||
if (!asset->IsIncludedForVariant(variant->m_index))
|
||||
continue;
|
||||
|
||||
auto context = std::make_unique<PerAssetRenderingContext>(repository, asset, variant);
|
||||
const auto result = GenerateCodeOncePerAsset(*context, foundTemplate->second.get());
|
||||
LogDirtyCheckResult(
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace
|
||||
|
||||
for (const auto* asset : m_env.m_all_assets)
|
||||
{
|
||||
if (!asset->IsIncludedForVariant(m_env.m_variant->m_index))
|
||||
continue;
|
||||
|
||||
LINEF("#include \"Game/{0}/XAssets/{1}/{1}_{2}_{3}_load_db.h\"",
|
||||
m_env.m_game,
|
||||
Lower(asset->m_definition->m_name),
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace
|
||||
|
||||
for (const auto* asset : m_env.m_all_assets)
|
||||
{
|
||||
if (!asset->IsIncludedForVariant(m_env.m_variant->m_index))
|
||||
continue;
|
||||
|
||||
LINEF("#include \"Game/{0}/XAssets/{1}/{1}_{2}_{3}_mark_db.h\"",
|
||||
m_env.m_game,
|
||||
Lower(asset->m_definition->m_name),
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace
|
||||
|
||||
for (const auto* asset : m_env.m_all_assets)
|
||||
{
|
||||
if (!asset->IsIncludedForVariant(m_env.m_variant->m_index))
|
||||
continue;
|
||||
|
||||
LINEF("#include \"Game/{0}/XAssets/{1}/{1}_{2}_{3}_write_db.h\"",
|
||||
m_env.m_game,
|
||||
Lower(asset->m_definition->m_name),
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "Parsing/Commands/Sequence/SequenceReusable.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceScriptString.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceSetBlock.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceSetVariant.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceString.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceUse.h"
|
||||
#include "Parsing/Commands/Sequence/SequenceVariant.h"
|
||||
@@ -41,6 +42,7 @@ const std::vector<CommandsParser::sequence_t*>& CommandsParser::GetTestsForState
|
||||
new SequenceReusable(),
|
||||
new SequenceScriptString(),
|
||||
new SequenceSetBlock(),
|
||||
new SequenceSetVariant(),
|
||||
new SequenceString(),
|
||||
new SequenceUse(),
|
||||
new SequenceVariant(),
|
||||
|
||||
@@ -76,7 +76,8 @@ void CommandsParserState::AddBlock(std::unique_ptr<FastFileBlock> block) const
|
||||
|
||||
void CommandsParserState::AddGameVariant(std::string variantName, const WordSize wordSize, const std::endian endianness) const
|
||||
{
|
||||
m_repository->AddGameVariant(std::make_unique<GameVariant>(std::move(variantName), wordSize, endianness));
|
||||
m_repository->AddGameVariant(
|
||||
std::make_unique<GameVariant>(static_cast<unsigned>(m_repository->GetGameVariants().size()), std::move(variantName), wordSize, endianness));
|
||||
}
|
||||
|
||||
void CommandsParserState::SetGame(std::string gameName) const
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "SequenceSetVariant.h"
|
||||
|
||||
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
|
||||
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto CAPTURE_START = 1;
|
||||
constexpr auto CAPTURE_TYPE_OR_VARIANT = 2;
|
||||
constexpr auto CAPTURE_VARIANT = 3;
|
||||
|
||||
std::optional<unsigned> GetVariantIndexForName(const IDataRepository& repository, const std::string& name)
|
||||
{
|
||||
for (const auto* variant : repository.GetGameVariants())
|
||||
{
|
||||
if (utils::StringEqualsIgnoreCase(variant->m_name, name))
|
||||
return variant->m_index;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SequenceSetVariant::SequenceSetVariant()
|
||||
{
|
||||
const CommandsMatcherFactory create(this);
|
||||
|
||||
AddLabeledMatchers(CommandsCommonMatchers::Typename(this), CommandsCommonMatchers::LABEL_TYPENAME);
|
||||
AddMatchers({
|
||||
create.Keyword("set").Capture(CAPTURE_START),
|
||||
create.Keyword("variant"),
|
||||
create.Label(CommandsCommonMatchers::LABEL_TYPENAME).Capture(CAPTURE_TYPE_OR_VARIANT),
|
||||
create.OptionalLoop(create.Identifier().Capture(CAPTURE_VARIANT)),
|
||||
create.Char(';'),
|
||||
});
|
||||
}
|
||||
|
||||
void SequenceSetVariant::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
||||
{
|
||||
const auto& typeOrVariantToken = result.NextCapture(CAPTURE_TYPE_OR_VARIANT);
|
||||
const auto& typeOrVariantValue = typeOrVariantToken.TypeNameValue();
|
||||
const auto maybeTypeOrVariantAsVariantIndex = GetVariantIndexForName(*state->GetRepository(), typeOrVariantValue);
|
||||
|
||||
StructureInformation* information;
|
||||
std::vector<MemberInformation*> memberChain;
|
||||
if (state->GetTypenameAndMembersFromTypename(typeOrVariantValue, information, memberChain))
|
||||
{
|
||||
if (maybeTypeOrVariantAsVariantIndex)
|
||||
throw ParsingException(typeOrVariantToken.GetPos(), "Expression is ambiguous, could both be a variant name or a type.");
|
||||
|
||||
if (!memberChain.empty())
|
||||
{
|
||||
information = memberChain.back()->m_type;
|
||||
if (information == nullptr)
|
||||
throw ParsingException(typeOrVariantToken.GetPos(), "Specified type must be a structure.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
information = state->GetInUse();
|
||||
if (information == nullptr)
|
||||
throw ParsingException(result.NextCapture(CAPTURE_START).GetPos(), "No type is used. Therefore one needs to be specified directly.");
|
||||
}
|
||||
|
||||
if (maybeTypeOrVariantAsVariantIndex.has_value())
|
||||
information->m_variants.emplace(*maybeTypeOrVariantAsVariantIndex);
|
||||
|
||||
while (result.HasNextCapture(CAPTURE_VARIANT))
|
||||
{
|
||||
const auto& variantToken = result.NextCapture(CAPTURE_VARIANT);
|
||||
const auto maybeVariant = GetVariantIndexForName(*state->GetRepository(), variantToken.TypeNameValue());
|
||||
if (!maybeVariant)
|
||||
throw ParsingException(variantToken.GetPos(), "No variant with this name.");
|
||||
|
||||
information->m_variants.emplace(*maybeVariant);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Commands/Impl/CommandsParser.h"
|
||||
|
||||
class SequenceSetVariant final : public CommandsParser::sequence_t
|
||||
{
|
||||
public:
|
||||
SequenceSetVariant();
|
||||
|
||||
protected:
|
||||
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
|
||||
};
|
||||
Reference in new issue
Block a user