From fe5d0f79ffa1aed645b3da66e1f8fa2573b1cb57 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 2 Jan 2025 16:26:42 +0100 Subject: [PATCH] chore: consider specified obj containers when post processing --- src/Linker/ZoneCreation/ZoneCreator.cpp | 5 +- src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp | 10 ++-- src/ObjCompiling/Game/IW3/ObjCompilerIW3.h | 2 +- src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp | 10 ++-- src/ObjCompiling/Game/IW4/ObjCompilerIW4.h | 2 +- src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp | 10 ++-- src/ObjCompiling/Game/IW5/ObjCompilerIW5.h | 2 +- src/ObjCompiling/Game/T5/ObjCompilerT5.cpp | 10 ++-- src/ObjCompiling/Game/T5/ObjCompilerT5.h | 2 +- src/ObjCompiling/Game/T6/ObjCompilerT6.cpp | 14 +++-- src/ObjCompiling/Game/T6/ObjCompilerT6.h | 2 +- src/ObjCompiling/IObjCompiler.h | 3 +- src/ObjCompiling/Image/IPak/IPakCreator.cpp | 30 +++++++++- src/ObjCompiling/Image/IPak/IPakCreator.h | 21 ++++++- .../Image/ImageIPakPostProcessor.cpp | 59 ++++++++++++++++-- .../Image/ImageIPakPostProcessor.h | 19 +++++- .../Image/ImageIwdPostProcessor.cpp | 60 +++++++++++++++++-- .../Image/ImageIwdPostProcessor.h | 19 +++++- src/ObjCompiling/Iwd/IwdCreator.cpp | 32 +++++++++- src/ObjCompiling/Iwd/IwdCreator.h | 21 ++++++- src/ObjLoading/Asset/ZoneDefinitionContext.h | 16 +++++ 21 files changed, 296 insertions(+), 53 deletions(-) create mode 100644 src/ObjLoading/Asset/ZoneDefinitionContext.h diff --git a/src/Linker/ZoneCreation/ZoneCreator.cpp b/src/Linker/ZoneCreation/ZoneCreator.cpp index 332465fc..d8ba67d5 100644 --- a/src/Linker/ZoneCreation/ZoneCreator.cpp +++ b/src/Linker/ZoneCreation/ZoneCreator.cpp @@ -64,8 +64,9 @@ namespace zone_creator const auto* objLoader = IObjLoader::GetObjLoaderForGame(gameId); AssetCreatorCollection creatorCollection(*zone); + ZoneDefinitionContext zoneDefinitionContext(*context.m_definition); objCompiler->ConfigureCreatorCollection( - creatorCollection, *zone, *context.m_definition, *context.m_asset_search_path, lookup, context.m_out_dir, context.m_cache_dir); + creatorCollection, *zone, zoneDefinitionContext, *context.m_asset_search_path, lookup, context.m_out_dir, context.m_cache_dir); objLoader->ConfigureCreatorCollection(creatorCollection, *zone, *context.m_asset_search_path, lookup); AssetCreationContext creationContext(zone.get(), &creatorCollection, &ignoredAssetLookup); @@ -76,6 +77,8 @@ namespace zone_creator if (!createdAsset) return nullptr; + + ++zoneDefinitionContext.m_asset_index_in_definition; } creatorCollection.FinalizeZone(creationContext); diff --git a/src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp b/src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp index 632c8e62..31350591 100644 --- a/src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp +++ b/src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp @@ -17,21 +17,23 @@ namespace // No compilers yet } - void ConfigurePostProcessors(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, const fs::path& outDir) + void ConfigurePostProcessors( + AssetCreatorCollection& collection, Zone& zone, const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const fs::path& outDir) { auto& memory = *zone.GetMemory(); - collection.AddAssetPostProcessor(std::make_unique>(searchPath, outDir)); + if (ImageIwdPostProcessor::AppliesToZoneDefinition(zoneDefinition)) + collection.AddAssetPostProcessor(std::make_unique>(zoneDefinition, searchPath, outDir)); } } // namespace void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const fs::path& outDir, const fs::path& cacheDir) const { - ConfigurePostProcessors(collection, zone, searchPath, outDir); + ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, outDir); } diff --git a/src/ObjCompiling/Game/IW3/ObjCompilerIW3.h b/src/ObjCompiling/Game/IW3/ObjCompilerIW3.h index c24af94f..5b3644ac 100644 --- a/src/ObjCompiling/Game/IW3/ObjCompilerIW3.h +++ b/src/ObjCompiling/Game/IW3/ObjCompilerIW3.h @@ -9,7 +9,7 @@ namespace IW3 public: void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const std::filesystem::path& outDir, diff --git a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp index 4e290ee5..7d7f17f5 100644 --- a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp +++ b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp @@ -17,21 +17,23 @@ namespace // No compilers yet } - void ConfigurePostProcessors(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, const fs::path& outDir) + void ConfigurePostProcessors( + AssetCreatorCollection& collection, Zone& zone, const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const fs::path& outDir) { auto& memory = *zone.GetMemory(); - collection.AddAssetPostProcessor(std::make_unique>(searchPath, outDir)); + if (ImageIwdPostProcessor::AppliesToZoneDefinition(zoneDefinition)) + collection.AddAssetPostProcessor(std::make_unique>(zoneDefinition, searchPath, outDir)); } } // namespace void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const fs::path& outDir, const fs::path& cacheDir) const { - ConfigurePostProcessors(collection, zone, searchPath, outDir); + ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, outDir); } diff --git a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.h b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.h index c9a6185c..07edb7b9 100644 --- a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.h +++ b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.h @@ -9,7 +9,7 @@ namespace IW4 public: void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const std::filesystem::path& outDir, diff --git a/src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp b/src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp index ae52973e..0f970267 100644 --- a/src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp +++ b/src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp @@ -17,21 +17,23 @@ namespace // No compilers yet } - void ConfigurePostProcessors(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, const fs::path& outDir) + void ConfigurePostProcessors( + AssetCreatorCollection& collection, Zone& zone, const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const fs::path& outDir) { auto& memory = *zone.GetMemory(); - collection.AddAssetPostProcessor(std::make_unique>(searchPath, outDir)); + if (ImageIwdPostProcessor::AppliesToZoneDefinition(zoneDefinition)) + collection.AddAssetPostProcessor(std::make_unique>(zoneDefinition, searchPath, outDir)); } } // namespace void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const fs::path& outDir, const fs::path& cacheDir) const { - ConfigurePostProcessors(collection, zone, searchPath, outDir); + ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, outDir); } diff --git a/src/ObjCompiling/Game/IW5/ObjCompilerIW5.h b/src/ObjCompiling/Game/IW5/ObjCompilerIW5.h index b96637ce..77b4be0c 100644 --- a/src/ObjCompiling/Game/IW5/ObjCompilerIW5.h +++ b/src/ObjCompiling/Game/IW5/ObjCompilerIW5.h @@ -9,7 +9,7 @@ namespace IW5 public: void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const std::filesystem::path& outDir, diff --git a/src/ObjCompiling/Game/T5/ObjCompilerT5.cpp b/src/ObjCompiling/Game/T5/ObjCompilerT5.cpp index 5ea0be38..642cb9f0 100644 --- a/src/ObjCompiling/Game/T5/ObjCompilerT5.cpp +++ b/src/ObjCompiling/Game/T5/ObjCompilerT5.cpp @@ -17,21 +17,23 @@ namespace // No compilers yet } - void ConfigurePostProcessors(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, const fs::path& outDir) + void ConfigurePostProcessors( + AssetCreatorCollection& collection, Zone& zone, const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const fs::path& outDir) { auto& memory = *zone.GetMemory(); - collection.AddAssetPostProcessor(std::make_unique>(searchPath, outDir)); + if (ImageIwdPostProcessor::AppliesToZoneDefinition(zoneDefinition)) + collection.AddAssetPostProcessor(std::make_unique>(zoneDefinition, searchPath, outDir)); } } // namespace void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const fs::path& outDir, const fs::path& cacheDir) const { - ConfigurePostProcessors(collection, zone, searchPath, outDir); + ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, outDir); } diff --git a/src/ObjCompiling/Game/T5/ObjCompilerT5.h b/src/ObjCompiling/Game/T5/ObjCompilerT5.h index 1ccd8f7c..9a1d6d21 100644 --- a/src/ObjCompiling/Game/T5/ObjCompilerT5.h +++ b/src/ObjCompiling/Game/T5/ObjCompilerT5.h @@ -9,7 +9,7 @@ namespace T5 public: void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const std::filesystem::path& outDir, diff --git a/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp b/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp index 580a5cf9..a63fbca3 100644 --- a/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp +++ b/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp @@ -1,6 +1,7 @@ #include "ObjCompilerT6.h" #include "Game/T6/T6.h" +#include "Image/ImageIPakPostProcessor.h" #include "Image/ImageIwdPostProcessor.h" #include @@ -17,21 +18,26 @@ namespace // No compilers yet } - void ConfigurePostProcessors(AssetCreatorCollection& collection, Zone& zone, ISearchPath& searchPath, const fs::path& outDir) + void ConfigurePostProcessors( + AssetCreatorCollection& collection, Zone& zone, const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const fs::path& outDir) { auto& memory = *zone.GetMemory(); - collection.AddAssetPostProcessor(std::make_unique>(searchPath, outDir)); + if (ImageIPakPostProcessor::AppliesToZoneDefinition(zoneDefinition)) + collection.AddAssetPostProcessor(std::make_unique>(zoneDefinition, searchPath, outDir)); + + if (ImageIwdPostProcessor::AppliesToZoneDefinition(zoneDefinition)) + collection.AddAssetPostProcessor(std::make_unique>(zoneDefinition, searchPath, outDir)); } } // namespace void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const fs::path& outDir, const fs::path& cacheDir) const { - ConfigurePostProcessors(collection, zone, searchPath, outDir); + ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, outDir); } diff --git a/src/ObjCompiling/Game/T6/ObjCompilerT6.h b/src/ObjCompiling/Game/T6/ObjCompilerT6.h index 2cd4705c..9080a8bd 100644 --- a/src/ObjCompiling/Game/T6/ObjCompilerT6.h +++ b/src/ObjCompiling/Game/T6/ObjCompilerT6.h @@ -9,7 +9,7 @@ namespace T6 public: void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const std::filesystem::path& outDir, diff --git a/src/ObjCompiling/IObjCompiler.h b/src/ObjCompiling/IObjCompiler.h index 927b3b8b..e4babff7 100644 --- a/src/ObjCompiling/IObjCompiler.h +++ b/src/ObjCompiling/IObjCompiler.h @@ -1,6 +1,7 @@ #pragma once #include "Asset/AssetCreatorCollection.h" +#include "Asset/ZoneDefinitionContext.h" #include "Gdt/IGdtQueryable.h" #include "SearchPath/ISearchPath.h" #include "Zone/Definition/ZoneDefinition.h" @@ -22,7 +23,7 @@ public: virtual void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, - const ZoneDefinition& zoneDefinition, + const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, IGdtQueryable& gdt, const std::filesystem::path& outDir, diff --git a/src/ObjCompiling/Image/IPak/IPakCreator.cpp b/src/ObjCompiling/Image/IPak/IPakCreator.cpp index bf533e5e..ab62a9e1 100644 --- a/src/ObjCompiling/Image/IPak/IPakCreator.cpp +++ b/src/ObjCompiling/Image/IPak/IPakCreator.cpp @@ -3,15 +3,39 @@ #include #include -void IPakCreator::AddImage(std::string imageName) +IPakToCreate::IPakToCreate(std::string name) + : m_name(std::move(name)) +{ +} + +void IPakToCreate::AddImage(std::string imageName) { m_image_names.emplace_back(std::move(imageName)); } -void IPakCreator::Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath) +void IPakToCreate::Build(ISearchPath& searchPath, const std::filesystem::path& outPath) { - std::cout << std::format("Creating ipak with {} entries:\n", m_image_names.size()); + std::cout << std::format("Creating ipak {} with {} entries:\n", m_name, m_image_names.size()); for (const auto& imageName : m_image_names) std::cout << std::format(" {}\n", imageName); } + +IPakToCreate* IPakCreator::GetOrAddIPak(const std::string& ipakName) +{ + const auto existingIPak = m_ipak_lookup.find(ipakName); + if (existingIPak != m_ipak_lookup.end()) + return existingIPak->second; + + auto newIPak = std::make_unique(ipakName); + auto* result = newIPak.get(); + m_ipaks.emplace_back(std::move(newIPak)); + + return result; +} + +void IPakCreator::Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath) +{ + for (const auto& ipakToCreate : m_ipaks) + ipakToCreate->Build(searchPath, outPath); +} diff --git a/src/ObjCompiling/Image/IPak/IPakCreator.h b/src/ObjCompiling/Image/IPak/IPakCreator.h index 19686150..699cea0d 100644 --- a/src/ObjCompiling/Image/IPak/IPakCreator.h +++ b/src/ObjCompiling/Image/IPak/IPakCreator.h @@ -4,13 +4,30 @@ #include "SearchPath/ISearchPath.h" #include +#include +#include +#include + +class IPakToCreate +{ +public: + explicit IPakToCreate(std::string name); + + void AddImage(std::string imageName); + void Build(ISearchPath& searchPath, const std::filesystem::path& outPath); + +private: + std::string m_name; + std::vector m_image_names; +}; class IPakCreator : public IZoneAssetLoaderState { public: - void AddImage(std::string imageName); + IPakToCreate* GetOrAddIPak(const std::string& ipakName); void Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath); private: - std::vector m_image_names; + std::unordered_map m_ipak_lookup; + std::vector> m_ipaks; }; diff --git a/src/ObjCompiling/Image/ImageIPakPostProcessor.cpp b/src/ObjCompiling/Image/ImageIPakPostProcessor.cpp index f20a5dfb..2188b500 100644 --- a/src/ObjCompiling/Image/ImageIPakPostProcessor.cpp +++ b/src/ObjCompiling/Image/ImageIPakPostProcessor.cpp @@ -4,19 +4,68 @@ #include -AbstractImageIPakPostProcessor::AbstractImageIPakPostProcessor(ISearchPath& searchPath, const std::filesystem::path& outDir) - : m_search_path(searchPath), - m_out_dir(outDir) +AbstractImageIPakPostProcessor::AbstractImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition, + ISearchPath& searchPath, + const std::filesystem::path& outDir) + : m_zone_definition(zoneDefinition), + m_search_path(searchPath), + m_out_dir(outDir), + m_initialized(false), + m_obj_container_index(0u), + m_current_ipak(nullptr), + m_current_ipak_start_index(0u), + m_current_ipak_end_index(0u) { } +bool AbstractImageIPakPostProcessor::AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition) +{ + for (const auto& objContainer : zoneDefinition.m_zone_definition.m_obj_containers) + { + if (objContainer.m_type == ZoneDefinitionObjContainerType::IPAK) + return true; + } + + return false; +} + +void AbstractImageIPakPostProcessor::FindNextObjContainer(AssetCreationContext& context) +{ + const auto objContainerCount = m_zone_definition.m_zone_definition.m_obj_containers.size(); + while (m_obj_container_index < objContainerCount) + { + const auto& objContainer = m_zone_definition.m_zone_definition.m_obj_containers[m_obj_container_index++]; + + if (objContainer.m_type != ZoneDefinitionObjContainerType::IPAK) + continue; + + auto* ipakCreator = context.GetZoneAssetLoaderState(); + m_current_ipak = ipakCreator->GetOrAddIPak(objContainer.m_name); + m_current_ipak_start_index = objContainer.m_asset_start; + m_current_ipak_end_index = objContainer.m_asset_end; + return; + } + + m_current_ipak = nullptr; +} + void AbstractImageIPakPostProcessor::PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context) { if (assetInfo.m_name.empty() || assetInfo.m_name[0] == ',') return; - auto* ipakCreator = context.GetZoneAssetLoaderState(); - ipakCreator->AddImage(assetInfo.m_name); + // Initialize on first image occurance + if (!m_initialized) + { + FindNextObjContainer(context); + m_initialized = true; + } + + while (m_current_ipak && m_zone_definition.m_asset_index_in_definition >= m_current_ipak_end_index) + FindNextObjContainer(context); + + if (m_current_ipak && m_zone_definition.m_asset_index_in_definition <= m_current_ipak_start_index) + m_current_ipak->AddImage(assetInfo.m_name); } void AbstractImageIPakPostProcessor::FinalizeZone(AssetCreationContext& context) diff --git a/src/ObjCompiling/Image/ImageIPakPostProcessor.h b/src/ObjCompiling/Image/ImageIPakPostProcessor.h index 34208c67..95f92436 100644 --- a/src/ObjCompiling/Image/ImageIPakPostProcessor.h +++ b/src/ObjCompiling/Image/ImageIPakPostProcessor.h @@ -1,20 +1,33 @@ #pragma once #include "Asset/IAssetPostProcessor.h" +#include "Asset/ZoneDefinitionContext.h" +#include "Image/IPak/IPakCreator.h" #include class AbstractImageIPakPostProcessor : public IAssetPostProcessor { public: - AbstractImageIPakPostProcessor(ISearchPath& searchPath, const std::filesystem::path& outDir); + AbstractImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const std::filesystem::path& outDir); + + static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition); void PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context) override; void FinalizeZone(AssetCreationContext& context) override; private: + void FindNextObjContainer(AssetCreationContext& context); + + const ZoneDefinitionContext& m_zone_definition; ISearchPath& m_search_path; const std::filesystem::path& m_out_dir; + + bool m_initialized; + unsigned m_obj_container_index; + IPakToCreate* m_current_ipak; + unsigned m_current_ipak_start_index; + unsigned m_current_ipak_end_index; }; template class ImageIPakPostProcessor final : public AbstractImageIPakPostProcessor @@ -22,8 +35,8 @@ template class ImageIPakPostProcessor final : public Abstrac public: static_assert(std::is_base_of_v); - ImageIPakPostProcessor(ISearchPath& searchPath, const std::filesystem::path& outDir) - : AbstractImageIPakPostProcessor(searchPath, outDir) + ImageIPakPostProcessor(const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const std::filesystem::path& outDir) + : AbstractImageIPakPostProcessor(zoneDefinition, searchPath, outDir) { } diff --git a/src/ObjCompiling/Image/ImageIwdPostProcessor.cpp b/src/ObjCompiling/Image/ImageIwdPostProcessor.cpp index af7d037d..f882593b 100644 --- a/src/ObjCompiling/Image/ImageIwdPostProcessor.cpp +++ b/src/ObjCompiling/Image/ImageIwdPostProcessor.cpp @@ -3,20 +3,70 @@ #include "Iwd/IwdCreator.h" #include +#include -AbstractImageIwdPostProcessor::AbstractImageIwdPostProcessor(ISearchPath& searchPath, const std::filesystem::path& outDir) - : m_search_path(searchPath), - m_out_dir(outDir) +AbstractImageIwdPostProcessor::AbstractImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition, + ISearchPath& searchPath, + const std::filesystem::path& outDir) + : m_zone_definition(zoneDefinition), + m_search_path(searchPath), + m_out_dir(outDir), + m_initialized(false), + m_obj_container_index(0u), + m_current_iwd(nullptr), + m_current_iwd_start_index(0u), + m_current_iwd_end_index(0u) { } +bool AbstractImageIwdPostProcessor::AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition) +{ + for (const auto& objContainer : zoneDefinition.m_zone_definition.m_obj_containers) + { + if (objContainer.m_type == ZoneDefinitionObjContainerType::IWD) + return true; + } + + return false; +} + +void AbstractImageIwdPostProcessor::FindNextObjContainer(AssetCreationContext& context) +{ + const auto objContainerCount = m_zone_definition.m_zone_definition.m_obj_containers.size(); + while (m_obj_container_index < objContainerCount) + { + const auto& objContainer = m_zone_definition.m_zone_definition.m_obj_containers[m_obj_container_index++]; + + if (objContainer.m_type != ZoneDefinitionObjContainerType::IWD) + continue; + + auto* iwdCreator = context.GetZoneAssetLoaderState(); + m_current_iwd = iwdCreator->GetOrAddIwd(objContainer.m_name); + m_current_iwd_start_index = objContainer.m_asset_start; + m_current_iwd_end_index = objContainer.m_asset_end; + return; + } + + m_current_iwd = nullptr; +} + void AbstractImageIwdPostProcessor::PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context) { if (assetInfo.m_name.empty() || assetInfo.m_name[0] == ',') return; - auto* iwdCreator = context.GetZoneAssetLoaderState(); - iwdCreator->AddFile(std::format("images/{}.iwi", assetInfo.m_name)); + // Initialize on first image occurance + if (!m_initialized) + { + FindNextObjContainer(context); + m_initialized = true; + } + + while (m_current_iwd && m_zone_definition.m_asset_index_in_definition >= m_current_iwd_end_index) + FindNextObjContainer(context); + + if (m_current_iwd && m_zone_definition.m_asset_index_in_definition <= m_current_iwd_start_index) + m_current_iwd->AddFile(std::format("images/{}.iwi", assetInfo.m_name)); } void AbstractImageIwdPostProcessor::FinalizeZone(AssetCreationContext& context) diff --git a/src/ObjCompiling/Image/ImageIwdPostProcessor.h b/src/ObjCompiling/Image/ImageIwdPostProcessor.h index 2e10bec4..3b35cd8d 100644 --- a/src/ObjCompiling/Image/ImageIwdPostProcessor.h +++ b/src/ObjCompiling/Image/ImageIwdPostProcessor.h @@ -1,20 +1,33 @@ #pragma once #include "Asset/IAssetPostProcessor.h" +#include "Asset/ZoneDefinitionContext.h" +#include "Iwd/IwdCreator.h" #include class AbstractImageIwdPostProcessor : public IAssetPostProcessor { public: - AbstractImageIwdPostProcessor(ISearchPath& searchPath, const std::filesystem::path& outDir); + AbstractImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const std::filesystem::path& outDir); + + static bool AppliesToZoneDefinition(const ZoneDefinitionContext& zoneDefinition); void PostProcessAsset(XAssetInfoGeneric& assetInfo, AssetCreationContext& context) override; void FinalizeZone(AssetCreationContext& context) override; private: + void FindNextObjContainer(AssetCreationContext& context); + + const ZoneDefinitionContext& m_zone_definition; ISearchPath& m_search_path; const std::filesystem::path& m_out_dir; + + bool m_initialized; + unsigned m_obj_container_index; + IwdToCreate* m_current_iwd; + unsigned m_current_iwd_start_index; + unsigned m_current_iwd_end_index; }; template class ImageIwdPostProcessor final : public AbstractImageIwdPostProcessor @@ -22,8 +35,8 @@ template class ImageIwdPostProcessor final : public Abstract public: static_assert(std::is_base_of_v); - ImageIwdPostProcessor(ISearchPath& searchPath, const std::filesystem::path& outDir) - : AbstractImageIwdPostProcessor(searchPath, outDir) + ImageIwdPostProcessor(const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath, const std::filesystem::path& outDir) + : AbstractImageIwdPostProcessor(zoneDefinition, searchPath, outDir) { } diff --git a/src/ObjCompiling/Iwd/IwdCreator.cpp b/src/ObjCompiling/Iwd/IwdCreator.cpp index d2e516a2..96dd7adb 100644 --- a/src/ObjCompiling/Iwd/IwdCreator.cpp +++ b/src/ObjCompiling/Iwd/IwdCreator.cpp @@ -1,17 +1,43 @@ #include "IwdCreator.h" +#include "Utils/FileToZlibWrapper.h" + #include #include -void IwdCreator::AddFile(std::string filePath) +IwdToCreate::IwdToCreate(std::string name) + : m_name(std::move(name)) +{ +} + +void IwdToCreate::AddFile(std::string filePath) { m_file_paths.emplace_back(std::move(filePath)); } -void IwdCreator::Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath) +void IwdToCreate::Build(ISearchPath& searchPath, const std::filesystem::path& outPath) { - std::cout << std::format("Creating iwd with {} entries:\n", m_file_paths.size()); + std::cout << std::format("Creating iwd {} with {} entries:\n", m_name, m_file_paths.size()); for (const auto& filePath : m_file_paths) std::cout << std::format(" {}\n", filePath); } + +IwdToCreate* IwdCreator::GetOrAddIwd(const std::string& iwdName) +{ + const auto existingIwd = m_iwd_lookup.find(iwdName); + if (existingIwd != m_iwd_lookup.end()) + return existingIwd->second; + + auto newIwd = std::make_unique(iwdName); + auto* result = newIwd.get(); + m_iwds.emplace_back(std::move(newIwd)); + + return result; +} + +void IwdCreator::Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath) +{ + for (const auto& iwdToCreate : m_iwds) + iwdToCreate->Build(searchPath, outPath); +} diff --git a/src/ObjCompiling/Iwd/IwdCreator.h b/src/ObjCompiling/Iwd/IwdCreator.h index a6b2df51..68fff8f9 100644 --- a/src/ObjCompiling/Iwd/IwdCreator.h +++ b/src/ObjCompiling/Iwd/IwdCreator.h @@ -4,13 +4,30 @@ #include "SearchPath/ISearchPath.h" #include +#include +#include +#include + +class IwdToCreate +{ +public: + explicit IwdToCreate(std::string name); + + void AddFile(std::string filePath); + void Build(ISearchPath& searchPath, const std::filesystem::path& outPath); + +private: + std::string m_name; + std::vector m_file_paths; +}; class IwdCreator : public IZoneAssetLoaderState { public: - void AddFile(std::string filePath); + IwdToCreate* GetOrAddIwd(const std::string& iwdName); void Finalize(ISearchPath& searchPath, const std::filesystem::path& outPath); private: - std::vector m_file_paths; + std::unordered_map m_iwd_lookup; + std::vector> m_iwds; }; diff --git a/src/ObjLoading/Asset/ZoneDefinitionContext.h b/src/ObjLoading/Asset/ZoneDefinitionContext.h new file mode 100644 index 00000000..780b959c --- /dev/null +++ b/src/ObjLoading/Asset/ZoneDefinitionContext.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Zone/Definition/ZoneDefinition.h" + +class ZoneDefinitionContext +{ +public: + ZoneDefinitionContext(const ZoneDefinition& zoneDefinition) + : m_zone_definition(zoneDefinition), + m_asset_index_in_definition(0u) + { + } + + const ZoneDefinition& m_zone_definition; + unsigned m_asset_index_in_definition; +};