mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
add post processors for leafs, memberleafs, unions and usages
This commit is contained in:
parent
42851bcaf8
commit
a6f547f1df
@ -11,6 +11,10 @@
|
||||
#include "Parsing/Impl/IncludingStreamProxy.h"
|
||||
#include "Parsing/Impl/ParserFilesystemStream.h"
|
||||
#include "Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/LeafsPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/MemberLeafsPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/UnionsPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/UsagesPostProcessor.h"
|
||||
|
||||
CommandsFileReader::CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
||||
: m_args(args),
|
||||
@ -50,7 +54,12 @@ void CommandsFileReader::SetupStreamProxies()
|
||||
|
||||
void CommandsFileReader::SetupPostProcessors()
|
||||
{
|
||||
// Order is important
|
||||
m_post_processors.emplace_back(std::make_unique<CalculateSizeAndAlignPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<UsagesPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<LeafsPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<MemberLeafsPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<UnionsPostProcessor>());
|
||||
}
|
||||
|
||||
bool CommandsFileReader::ReadCommandsFile(IDataRepository* repository)
|
||||
|
@ -0,0 +1,59 @@
|
||||
#include "LeafsPostProcessor.h"
|
||||
|
||||
#include "Domain/Computations/MemberComputations.h"
|
||||
#include "Domain/Computations/StructureComputations.h"
|
||||
#include "Domain/Definition/PointerDeclarationModifier.h"
|
||||
|
||||
bool LeafsPostProcessor::IsLeaf(StructureInformation* info)
|
||||
{
|
||||
for (const auto& member : info->m_ordered_members)
|
||||
{
|
||||
// If there is a condition to this member and it always evaluates to false: Skip this member
|
||||
if (member->m_condition && member->m_condition->IsStatic() && member->m_condition->EvaluateNumeric() == 0)
|
||||
continue;
|
||||
|
||||
// Any ScriptStrings or Strings need to be processed.
|
||||
if (member->m_is_script_string || member->m_is_string)
|
||||
return false;
|
||||
|
||||
// If there are any Pointer members that are not always count 0 it needs to be processed.
|
||||
for (const auto& modifier : member->m_member->m_type_declaration->m_declaration_modifiers)
|
||||
{
|
||||
if (modifier->GetType() == DeclarationModifierType::POINTER)
|
||||
{
|
||||
auto* pointer = dynamic_cast<PointerDeclarationModifier*>(modifier.get());
|
||||
const auto* countEvaluation = pointer->GetCountEvaluation();
|
||||
|
||||
if (!countEvaluation->IsStatic() || countEvaluation->EvaluateNumeric() != 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MemberComputations computations(member.get());
|
||||
|
||||
// If the member has an embedded type with dynamic size
|
||||
if (computations.HasDynamicArraySize())
|
||||
return false;
|
||||
|
||||
if (member->m_type != nullptr
|
||||
&& member->m_type != info
|
||||
&& !IsLeaf(member->m_type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LeafsPostProcessor::PostProcess(IDataRepository* repository)
|
||||
{
|
||||
const auto& allInfos = repository->GetAllStructureInformation();
|
||||
|
||||
for (const auto& info : allInfos)
|
||||
{
|
||||
info->m_is_leaf = IsLeaf(info);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "IPostProcessor.h"
|
||||
|
||||
class LeafsPostProcessor final : public IPostProcessor
|
||||
{
|
||||
static bool IsLeaf(StructureInformation* info);
|
||||
|
||||
public:
|
||||
bool PostProcess(IDataRepository* repository) override;
|
||||
};
|
@ -0,0 +1,53 @@
|
||||
#include "MemberLeafsPostProcessor.h"
|
||||
|
||||
#include "Domain/Computations/MemberComputations.h"
|
||||
#include "Domain/Definition/PointerDeclarationModifier.h"
|
||||
|
||||
bool MemberLeafsPostProcessor::MemberIsLeaf(MemberInformation* member)
|
||||
{
|
||||
if (member->m_is_string || member->m_is_script_string)
|
||||
return false;
|
||||
|
||||
if (member->m_type != nullptr && !member->m_type->m_is_leaf)
|
||||
return false;
|
||||
|
||||
// If there are any Pointer members that are not always count 0 it needs to be processed.
|
||||
for (const auto& modifier : member->m_member->m_type_declaration->m_declaration_modifiers)
|
||||
{
|
||||
if (modifier->GetType() == DeclarationModifierType::POINTER)
|
||||
{
|
||||
auto* pointer = dynamic_cast<PointerDeclarationModifier*>(modifier.get());
|
||||
const auto* countEvaluation = pointer->GetCountEvaluation();
|
||||
|
||||
if (!countEvaluation->IsStatic() || countEvaluation->EvaluateNumeric() != 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const MemberComputations computations(member);
|
||||
|
||||
if (computations.HasDynamicArraySize())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MemberLeafsPostProcessor::ProcessInfo(StructureInformation* info)
|
||||
{
|
||||
for(const auto& member : info->m_ordered_members)
|
||||
{
|
||||
member->m_is_leaf = MemberIsLeaf(member.get());
|
||||
}
|
||||
}
|
||||
|
||||
bool MemberLeafsPostProcessor::PostProcess(IDataRepository* repository)
|
||||
{
|
||||
const auto& allInfos = repository->GetAllStructureInformation();
|
||||
|
||||
for (const auto& info : allInfos)
|
||||
{
|
||||
ProcessInfo(info);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "IPostProcessor.h"
|
||||
|
||||
class MemberLeafsPostProcessor final : public IPostProcessor
|
||||
{
|
||||
static bool MemberIsLeaf(MemberInformation* member);
|
||||
static void ProcessInfo(StructureInformation* info);
|
||||
|
||||
public:
|
||||
bool PostProcess(IDataRepository* repository) override;
|
||||
};
|
@ -0,0 +1,50 @@
|
||||
#include "UnionsPostProcessor.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
bool UnionsPostProcessor::ProcessUnion(StructureInformation* info)
|
||||
{
|
||||
auto index = 0u;
|
||||
auto lastEntryWithoutCondition = 0u;
|
||||
auto entriesWithoutConditionCount = 0u;
|
||||
|
||||
for(const auto& member : info->m_ordered_members)
|
||||
{
|
||||
if(!member->m_condition && !member->m_is_leaf)
|
||||
{
|
||||
entriesWithoutConditionCount++;
|
||||
lastEntryWithoutCondition = index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (entriesWithoutConditionCount > 1 && !info->m_usages.empty() && !info->m_is_leaf)
|
||||
{
|
||||
std::cout << "Union '" << info->m_definition->GetFullName() << "' has more than one entry without a condition!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entriesWithoutConditionCount == 1)
|
||||
{
|
||||
// If there is only one entry without condition make it the last of the ordered members
|
||||
auto entryWithoutCondition = std::move(info->m_ordered_members.at(lastEntryWithoutCondition));
|
||||
info->m_ordered_members.erase(info->m_ordered_members.begin() + lastEntryWithoutCondition);
|
||||
info->m_ordered_members.emplace_back(std::move(entryWithoutCondition));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UnionsPostProcessor::PostProcess(IDataRepository* repository)
|
||||
{
|
||||
const auto& allInfos = repository->GetAllStructureInformation();
|
||||
|
||||
return std::all_of(allInfos.begin(), allInfos.end(), [](StructureInformation* info)
|
||||
{
|
||||
if (info->m_definition->GetType() != DataDefinitionType::UNION)
|
||||
return true;
|
||||
|
||||
return ProcessUnion(info);
|
||||
});
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "IPostProcessor.h"
|
||||
|
||||
class UnionsPostProcessor final : public IPostProcessor
|
||||
{
|
||||
static bool ProcessUnion(StructureInformation* info);
|
||||
|
||||
public:
|
||||
bool PostProcess(IDataRepository* repository) override;
|
||||
};
|
@ -0,0 +1,68 @@
|
||||
#include "UsagesPostProcessor.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
#include "Domain/Computations/MemberComputations.h"
|
||||
#include "Domain/Computations/StructureComputations.h"
|
||||
|
||||
bool UsagesPostProcessor::ProcessAsset(StructureInformation* info)
|
||||
{
|
||||
std::set<StructureInformation*> processedInfos;
|
||||
std::queue<StructureInformation*> processingQueue;
|
||||
|
||||
processingQueue.push(info);
|
||||
|
||||
while(!processingQueue.empty())
|
||||
{
|
||||
auto* currentStructure = processingQueue.front();
|
||||
processingQueue.pop();
|
||||
|
||||
if(processedInfos.find(currentStructure) != processedInfos.end())
|
||||
continue;
|
||||
processedInfos.emplace(currentStructure);
|
||||
|
||||
for (const auto& member : currentStructure->m_ordered_members)
|
||||
{
|
||||
if(member->m_type == nullptr)
|
||||
continue;
|
||||
|
||||
const MemberComputations computations(member.get());
|
||||
|
||||
if(computations.ShouldIgnore())
|
||||
continue;
|
||||
|
||||
if (computations.ContainsNonEmbeddedReference())
|
||||
member->m_type->m_non_embedded_reference_exists = true;
|
||||
|
||||
if (computations.ContainsSinglePointerReference())
|
||||
member->m_type->m_single_pointer_reference_exists = true;
|
||||
|
||||
if (computations.ContainsArrayPointerReference())
|
||||
member->m_type->m_array_pointer_reference_exists = true;
|
||||
|
||||
if (computations.ContainsArrayReference())
|
||||
member->m_type->m_array_reference_exists = true;
|
||||
|
||||
if (computations.IsNotInDefaultNormalBlock())
|
||||
member->m_type->m_reference_from_non_default_normal_block_exists = true;
|
||||
|
||||
member->m_type->m_usages.push_back(currentStructure);
|
||||
processingQueue.push(member->m_type);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UsagesPostProcessor::PostProcess(IDataRepository* repository)
|
||||
{
|
||||
const auto& allInfos = repository->GetAllStructureInformation();
|
||||
|
||||
return std::all_of(allInfos.begin(), allInfos.end(), [](StructureInformation* info)
|
||||
{
|
||||
const StructureComputations computations(info);
|
||||
return !computations.IsAsset() || ProcessAsset(info);
|
||||
});
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "IPostProcessor.h"
|
||||
|
||||
class UsagesPostProcessor final : public IPostProcessor
|
||||
{
|
||||
static bool ProcessAsset(StructureInformation* info);
|
||||
|
||||
public:
|
||||
bool PostProcess(IDataRepository* repository) override;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user