#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::AddUsedType(std::unique_ptr usedType) { auto* result = usedType.get(); m_used_types.push_back(usedType.get()); m_used_types_lookup.emplace(std::make_pair(usedType->m_type, std::move(usedType))); return result; } RenderingUsedType* RenderingContext::GetBaseType(const IDataRepository* repository, MemberComputations* computations, 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->m_type_declaration->m_type); if(foundUsedType == m_used_types_lookup.end()) { const auto* memberDef = dynamic_cast(typedefDefinition->m_type_declaration->m_type); StructureInformation* info = nullptr; if (memberDef) info = repository->GetInformationFor(memberDef); auto* addedUsedType = AddUsedType(std::make_unique(typedefDefinition->m_type_declaration->m_type, info)); ScanUsedTypeIfNeeded(repository, computations, usedType); return addedUsedType; } return foundUsedType->second.get(); } return nullptr; } void RenderingContext::AddMembersToContext(const IDataRepository* repository, 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()) usedType = AddUsedType(std::make_unique(member->m_member->m_type_declaration->m_type, member->m_type)); else usedType = existingUsedType->second.get(); auto* baseUsedType = GetBaseType(repository, &computations, 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; } ScanUsedTypeIfNeeded(repository, &computations, usedType); } } void RenderingContext::ScanUsedTypeIfNeeded(const IDataRepository* repository, MemberComputations* computations, RenderingUsedType* usedType) { if (usedType->m_info != nullptr && !StructureComputations(usedType->m_info).IsAsset() && !computations->IsInRuntimeBlock() && !usedType->m_members_loaded) { usedType->m_members_loaded = true; AddMembersToContext(repository, usedType->m_info); } } void RenderingContext::MakeAsset(const IDataRepository* repository, StructureInformation* asset) { m_asset = asset; AddUsedType(std::make_unique(asset->m_definition, asset)); AddMembersToContext(repository, asset); } void RenderingContext::CreateUsedTypeCollections() { for(auto* usedType : m_used_types) { if (usedType->m_info != nullptr) { StructureComputations computations(usedType->m_info); if(usedType->m_info->m_definition == usedType->m_type) m_used_structures.push_back(usedType); if(computations.IsAsset() && usedType->m_info != m_asset) m_referenced_assets.push_back(usedType); 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(repository, asset); context->CreateUsedTypeCollections(); return std::move(context); }