mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-11-05 08:41:59 +00:00
327 lines
9.3 KiB
C++
327 lines
9.3 KiB
C++
#include "BaseTemplate.h"
|
|
|
|
#include "Domain/Computations/MemberComputations.h"
|
|
#include "Domain/Computations/StructureComputations.h"
|
|
#include "Domain/Definition/ArrayDeclarationModifier.h"
|
|
|
|
#include <sstream>
|
|
|
|
BaseTemplate::BaseTemplate(std::ostream& stream, const BaseRenderingContext& context)
|
|
: m_out(stream),
|
|
m_intendation(0u),
|
|
m_env(context)
|
|
{
|
|
}
|
|
|
|
void BaseTemplate::DoIntendation() const
|
|
{
|
|
for (auto i = 0u; i < m_intendation; i++)
|
|
m_out << INTENDATION;
|
|
}
|
|
|
|
// clang-format off
|
|
void BaseTemplate::AddGeneratedHint() const
|
|
{
|
|
LINE("// ====================================================================")
|
|
LINE("// This file has been generated by ZoneCodeGenerator.")
|
|
LINE("// Do not modify.")
|
|
LINE("// Any changes will be discarded when regenerating.")
|
|
LINE("// ====================================================================")
|
|
LINE("")
|
|
} // clang-format on
|
|
|
|
std::string BaseTemplate::Upper(std::string str)
|
|
{
|
|
for (auto& c : str)
|
|
c = static_cast<char>(toupper(c));
|
|
|
|
return str;
|
|
}
|
|
|
|
std::string BaseTemplate::Lower(std::string str)
|
|
{
|
|
for (auto& c : str)
|
|
c = static_cast<char>(tolower(c));
|
|
|
|
return str;
|
|
}
|
|
|
|
void BaseTemplate::MakeSafeTypeNameInternal(const DataDefinition* def, std::ostringstream& str)
|
|
{
|
|
for (const auto& c : def->m_name)
|
|
{
|
|
if (isspace(c))
|
|
str << "_";
|
|
else
|
|
str << c;
|
|
}
|
|
}
|
|
|
|
void BaseTemplate::MakeTypeVarNameInternal(const DataDefinition* def, std::ostringstream& str)
|
|
{
|
|
str << "var";
|
|
MakeSafeTypeNameInternal(def, str);
|
|
}
|
|
|
|
void BaseTemplate::MakeTypePtrVarNameInternal(const DataDefinition* def, std::ostringstream& str)
|
|
{
|
|
str << "var";
|
|
MakeSafeTypeNameInternal(def, str);
|
|
str << "Ptr";
|
|
}
|
|
|
|
void BaseTemplate::MakeArrayIndicesInternal(const DeclarationModifierComputations& modifierComputations, std::ostringstream& str)
|
|
{
|
|
for (const auto index : modifierComputations.GetArrayIndices())
|
|
{
|
|
str << "[" << index << "]";
|
|
}
|
|
}
|
|
|
|
std::string BaseTemplate::MakeTypeVarName(const DataDefinition* def)
|
|
{
|
|
std::ostringstream str;
|
|
MakeTypeVarNameInternal(def, str);
|
|
return str.str();
|
|
}
|
|
|
|
std::string BaseTemplate::MakeTypePtrVarName(const DataDefinition* def)
|
|
{
|
|
std::ostringstream str;
|
|
MakeTypePtrVarNameInternal(def, str);
|
|
return str.str();
|
|
}
|
|
|
|
std::string BaseTemplate::MakeSafeTypeName(const DataDefinition* def)
|
|
{
|
|
std::ostringstream str;
|
|
MakeSafeTypeNameInternal(def, str);
|
|
return str.str();
|
|
}
|
|
|
|
std::string BaseTemplate::MakeMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier)
|
|
{
|
|
std::ostringstream str;
|
|
MakeTypeVarNameInternal(info->m_definition, str);
|
|
str << "->" << member->m_member->m_name;
|
|
MakeArrayIndicesInternal(modifier, str);
|
|
|
|
return str.str();
|
|
}
|
|
|
|
std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl)
|
|
{
|
|
std::ostringstream str;
|
|
if (decl->m_is_const)
|
|
{
|
|
str << "const ";
|
|
}
|
|
|
|
str << decl->m_type->GetFullName();
|
|
return str.str();
|
|
}
|
|
|
|
std::string BaseTemplate::MakeFollowingReferences(const std::vector<DeclarationModifier*>& modifiers)
|
|
{
|
|
std::ostringstream str;
|
|
for (const auto* modifier : modifiers)
|
|
{
|
|
if (modifier->GetType() == DeclarationModifierType::ARRAY)
|
|
{
|
|
const auto* array = dynamic_cast<const ArrayDeclarationModifier*>(modifier);
|
|
str << "[" << array->m_size << "]";
|
|
}
|
|
else
|
|
{
|
|
str << "*";
|
|
}
|
|
}
|
|
|
|
return str.str();
|
|
}
|
|
|
|
std::string BaseTemplate::MakeArrayIndices(const DeclarationModifierComputations& modifierComputations)
|
|
{
|
|
std::ostringstream str;
|
|
MakeArrayIndicesInternal(modifierComputations, str);
|
|
return str.str();
|
|
}
|
|
|
|
std::string BaseTemplate::MakeCustomActionCall(const CustomAction* action)
|
|
{
|
|
std::ostringstream str;
|
|
str << "m_actions." << action->m_action_name << "(";
|
|
|
|
auto first = true;
|
|
for (const auto* def : action->m_parameter_types)
|
|
{
|
|
if (first)
|
|
{
|
|
first = false;
|
|
}
|
|
else
|
|
{
|
|
str << ", ";
|
|
}
|
|
|
|
MakeTypeVarNameInternal(def, str);
|
|
}
|
|
|
|
str << ");";
|
|
return str.str();
|
|
}
|
|
|
|
std::string BaseTemplate::MakeArrayCount(const ArrayDeclarationModifier* arrayModifier)
|
|
{
|
|
if (arrayModifier->m_dynamic_count_evaluation)
|
|
{
|
|
return MakeEvaluation(arrayModifier->m_dynamic_count_evaluation.get());
|
|
}
|
|
|
|
return std::to_string(arrayModifier->m_size);
|
|
}
|
|
|
|
void BaseTemplate::MakeOperandStatic(const OperandStatic* op, std::ostringstream& str)
|
|
{
|
|
if (op->m_enum_member != nullptr)
|
|
{
|
|
str << op->m_enum_member->m_name;
|
|
}
|
|
else
|
|
{
|
|
str << op->m_value;
|
|
}
|
|
}
|
|
|
|
void BaseTemplate::MakeOperandDynamic(const OperandDynamic* op, std::ostringstream& str)
|
|
{
|
|
MakeTypeVarNameInternal(op->m_structure->m_definition, str);
|
|
|
|
if (!op->m_referenced_member_chain.empty())
|
|
{
|
|
str << "->";
|
|
const auto lastEntry = op->m_referenced_member_chain.end() - 1;
|
|
for (auto i = op->m_referenced_member_chain.begin(); i != lastEntry; ++i)
|
|
{
|
|
MemberComputations computations(*i);
|
|
str << (*i)->m_member->m_name;
|
|
|
|
if (computations.ContainsNonEmbeddedReference())
|
|
str << "->";
|
|
else
|
|
str << ".";
|
|
}
|
|
|
|
str << (*lastEntry)->m_member->m_name;
|
|
}
|
|
|
|
for (const auto& arrayIndex : op->m_array_indices)
|
|
{
|
|
str << "[";
|
|
MakeEvaluationInternal(arrayIndex.get(), str);
|
|
str << "]";
|
|
}
|
|
}
|
|
|
|
void BaseTemplate::MakeOperation(const Operation* operation, std::ostringstream& str)
|
|
{
|
|
if (operation->Operand1NeedsParenthesis())
|
|
{
|
|
str << "(";
|
|
MakeEvaluationInternal(operation->m_operand1.get(), str);
|
|
str << ")";
|
|
}
|
|
else
|
|
MakeEvaluationInternal(operation->m_operand1.get(), str);
|
|
|
|
str << " " << operation->m_operation_type->m_syntax << " ";
|
|
|
|
if (operation->Operand2NeedsParenthesis())
|
|
{
|
|
str << "(";
|
|
MakeEvaluationInternal(operation->m_operand2.get(), str);
|
|
str << ")";
|
|
}
|
|
else
|
|
MakeEvaluationInternal(operation->m_operand2.get(), str);
|
|
}
|
|
|
|
void BaseTemplate::MakeEvaluationInternal(const IEvaluation* evaluation, std::ostringstream& str)
|
|
{
|
|
if (evaluation->GetType() == EvaluationType::OPERATION)
|
|
MakeOperation(dynamic_cast<const Operation*>(evaluation), str);
|
|
else if (evaluation->GetType() == EvaluationType::OPERAND_STATIC)
|
|
MakeOperandStatic(dynamic_cast<const OperandStatic*>(evaluation), str);
|
|
else if (evaluation->GetType() == EvaluationType::OPERAND_DYNAMIC)
|
|
MakeOperandDynamic(dynamic_cast<const OperandDynamic*>(evaluation), str);
|
|
}
|
|
|
|
std::string BaseTemplate::MakeAllocAlignment(const StructureInformation& info) const
|
|
{
|
|
if (info.m_alloc_alignment)
|
|
return MakeEvaluation(info.m_alloc_alignment.get());
|
|
|
|
return std::to_string(info.m_definition->GetAlignment(m_env.m_word_size));
|
|
}
|
|
|
|
std::string BaseTemplate::MakeEvaluation(const IEvaluation* evaluation)
|
|
{
|
|
std::ostringstream str;
|
|
MakeEvaluationInternal(evaluation, str);
|
|
return str.str();
|
|
}
|
|
|
|
bool BaseTemplate::ShouldGenerateFillMethod(const RenderingUsedType& type)
|
|
{
|
|
const auto isNotForeignAsset = type.m_is_context_asset || !type.m_info || !StructureComputations(type.m_info).IsAsset();
|
|
const auto hasMismatchingStructure = type.m_info && type.m_type == type.m_info->m_definition && !type.m_info->m_has_matching_cross_platform_memory_layout;
|
|
const auto isEmbeddedDynamic = type.m_info && type.m_info->m_embedded_reference_exists && StructureComputations(type.m_info).GetDynamicMember();
|
|
|
|
return isNotForeignAsset && (hasMismatchingStructure || isEmbeddedDynamic);
|
|
}
|
|
|
|
size_t BaseTemplate::SizeForDeclModifierLevel(const MemberInformation& memberInfo, const size_t level) const
|
|
{
|
|
const auto& declModifiers = memberInfo.m_member->m_type_declaration->m_declaration_modifiers;
|
|
if (declModifiers.empty())
|
|
return memberInfo.m_member->m_type_declaration->GetSize(m_env.m_word_size);
|
|
|
|
if (level == 0)
|
|
return memberInfo.m_member->m_type_declaration->GetSize(m_env.m_word_size);
|
|
|
|
size_t currentSize = memberInfo.m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size);
|
|
const auto end = declModifiers.rbegin() + (declModifiers.size() - level);
|
|
for (auto i = declModifiers.rbegin(); i != end; ++i)
|
|
{
|
|
if ((*i)->GetType() == DeclarationModifierType::POINTER)
|
|
currentSize = m_env.m_pointer_size;
|
|
else
|
|
currentSize *= dynamic_cast<ArrayDeclarationModifier*>(i->get())->m_size;
|
|
}
|
|
|
|
return currentSize;
|
|
}
|
|
|
|
size_t BaseTemplate::OffsetForMemberModifier(const MemberInformation& memberInfo,
|
|
const DeclarationModifierComputations& modifier,
|
|
const size_t nestedBaseOffset) const
|
|
{
|
|
size_t curOffset = memberInfo.m_member->m_offset;
|
|
|
|
auto curLevel = 0u;
|
|
for (const auto index : modifier.GetArrayIndices())
|
|
{
|
|
if (index > 0)
|
|
curOffset += index * SizeForDeclModifierLevel(memberInfo, curLevel + 1);
|
|
|
|
curLevel++;
|
|
}
|
|
|
|
return curOffset + nestedBaseOffset;
|
|
}
|
|
|
|
bool BaseTemplate::MemoryLayoutMatches(const StructureInformation& structureInfo) const
|
|
{
|
|
return !m_env.m_word_size_mismatch || structureInfo.m_has_matching_cross_platform_memory_layout;
|
|
}
|