From 4f0a405bdc09369231e1d512167686bcb139a803 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 13 Dec 2024 23:28:28 +0000 Subject: [PATCH] chore: adjust asset creation process to use separated AssetCreators --- src/Linker/Game/IW3/ZoneCreatorIW3.cpp | 15 -- src/Linker/Game/IW3/ZoneCreatorIW3.h | 13 -- src/Linker/Game/IW4/ZoneCreatorIW4.cpp | 15 -- src/Linker/Game/IW4/ZoneCreatorIW4.h | 13 -- src/Linker/Game/IW5/ZoneCreatorIW5.cpp | 15 -- src/Linker/Game/IW5/ZoneCreatorIW5.h | 13 -- src/Linker/Game/T5/ZoneCreatorT5.cpp | 15 -- src/Linker/Game/T5/ZoneCreatorT5.h | 13 -- src/Linker/Game/T6/ZoneCreatorT6.h | 16 --- src/Linker/Linker.cpp | 59 ++++---- src/Linker/ZoneCreation/ZoneCreator.cpp | 79 ++++------ src/Linker/ZoneCreation/ZoneCreator.h | 22 +-- src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp | 5 +- src/ObjCompiling/Game/IW3/ObjCompilerIW3.h | 2 +- src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp | 5 +- src/ObjCompiling/Game/IW4/ObjCompilerIW4.h | 2 +- src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp | 5 +- src/ObjCompiling/Game/IW5/ObjCompilerIW5.h | 2 +- src/ObjCompiling/Game/T5/ObjCompilerT5.cpp | 5 +- src/ObjCompiling/Game/T5/ObjCompilerT5.h | 2 +- .../Game/T6/Image/ImageCompilerT6.cpp | 0 .../Game/T6/Image/ImageCompilerT6.h | 0 .../KeyValuePairs/KeyValuePairsCreator.cpp} | 28 ++-- .../T6/KeyValuePairs/KeyValuePairsCreator.h | 21 +++ src/ObjCompiling/Game/T6/ObjCompilerT6.cpp | 7 +- src/ObjCompiling/Game/T6/ObjCompilerT6.h | 2 +- src/ObjCompiling/IObjCompiler.h | 11 +- src/ObjLoading/Asset/AssetCreationContext.cpp | 135 ++++++++++++++++++ src/ObjLoading/Asset/AssetCreationContext.h | 85 +++++++++++ .../Asset/AssetCreatorCollection.cpp | 65 +++++++++ src/ObjLoading/Asset/AssetCreatorCollection.h | 32 +++++ src/ObjLoading/Asset/AssetRegistration.h | 51 +++++++ src/ObjLoading/Asset/IAssetCreator.cpp | 37 +++++ src/ObjLoading/Asset/IAssetCreator.h | 57 ++++++++ src/ObjLoading/Asset/IDefaultAssetCreator.h | 46 ++++++ src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp | 2 + src/ObjLoading/Game/IW3/ObjLoaderIW3.h | 2 + src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp | 2 + src/ObjLoading/Game/IW4/ObjLoaderIW4.h | 2 + src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp | 2 + src/ObjLoading/Game/IW5/ObjLoaderIW5.h | 2 + src/ObjLoading/Game/T5/ObjLoaderT5.cpp | 2 + src/ObjLoading/Game/T5/ObjLoaderT5.h | 2 + src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 2 + src/ObjLoading/Game/T6/ObjLoaderT6.h | 2 + src/ObjLoading/IObjLoader.h | 3 + 46 files changed, 638 insertions(+), 278 deletions(-) delete mode 100644 src/Linker/Game/IW3/ZoneCreatorIW3.cpp delete mode 100644 src/Linker/Game/IW3/ZoneCreatorIW3.h delete mode 100644 src/Linker/Game/IW4/ZoneCreatorIW4.cpp delete mode 100644 src/Linker/Game/IW4/ZoneCreatorIW4.h delete mode 100644 src/Linker/Game/IW5/ZoneCreatorIW5.cpp delete mode 100644 src/Linker/Game/IW5/ZoneCreatorIW5.h delete mode 100644 src/Linker/Game/T5/ZoneCreatorT5.cpp delete mode 100644 src/Linker/Game/T5/ZoneCreatorT5.h delete mode 100644 src/Linker/Game/T6/ZoneCreatorT6.h create mode 100644 src/ObjCompiling/Game/T6/Image/ImageCompilerT6.cpp create mode 100644 src/ObjCompiling/Game/T6/Image/ImageCompilerT6.h rename src/{Linker/Game/T6/ZoneCreatorT6.cpp => ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCreator.cpp} (55%) create mode 100644 src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCreator.h create mode 100644 src/ObjLoading/Asset/AssetCreationContext.cpp create mode 100644 src/ObjLoading/Asset/AssetCreationContext.h create mode 100644 src/ObjLoading/Asset/AssetCreatorCollection.cpp create mode 100644 src/ObjLoading/Asset/AssetCreatorCollection.h create mode 100644 src/ObjLoading/Asset/AssetRegistration.h create mode 100644 src/ObjLoading/Asset/IAssetCreator.cpp create mode 100644 src/ObjLoading/Asset/IAssetCreator.h create mode 100644 src/ObjLoading/Asset/IDefaultAssetCreator.h diff --git a/src/Linker/Game/IW3/ZoneCreatorIW3.cpp b/src/Linker/Game/IW3/ZoneCreatorIW3.cpp deleted file mode 100644 index 969380b3..00000000 --- a/src/Linker/Game/IW3/ZoneCreatorIW3.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "ZoneCreatorIW3.h" - -#include "Game/IW3/IW3.h" - -using namespace IW3; - -GameId ZoneCreator::GetGameId() const -{ - return GameId::IW3; -} - -asset_type_t ZoneCreator::GetImageAssetType() const -{ - return ASSET_TYPE_IMAGE; -} diff --git a/src/Linker/Game/IW3/ZoneCreatorIW3.h b/src/Linker/Game/IW3/ZoneCreatorIW3.h deleted file mode 100644 index 91cc2a19..00000000 --- a/src/Linker/Game/IW3/ZoneCreatorIW3.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "ZoneCreation/ZoneCreator.h" - -namespace IW3 -{ - class ZoneCreator final : public IZoneCreator - { - public: - [[nodiscard]] GameId GetGameId() const override; - [[nodiscard]] asset_type_t GetImageAssetType() const override; - }; -} // namespace IW3 diff --git a/src/Linker/Game/IW4/ZoneCreatorIW4.cpp b/src/Linker/Game/IW4/ZoneCreatorIW4.cpp deleted file mode 100644 index 2b33cb68..00000000 --- a/src/Linker/Game/IW4/ZoneCreatorIW4.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "ZoneCreatorIW4.h" - -#include "Game/IW4/IW4.h" - -using namespace IW4; - -GameId ZoneCreator::GetGameId() const -{ - return GameId::IW4; -} - -asset_type_t ZoneCreator::GetImageAssetType() const -{ - return ASSET_TYPE_IMAGE; -} diff --git a/src/Linker/Game/IW4/ZoneCreatorIW4.h b/src/Linker/Game/IW4/ZoneCreatorIW4.h deleted file mode 100644 index 5c439361..00000000 --- a/src/Linker/Game/IW4/ZoneCreatorIW4.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "ZoneCreation/ZoneCreator.h" - -namespace IW4 -{ - class ZoneCreator final : public IZoneCreator - { - public: - [[nodiscard]] GameId GetGameId() const override; - [[nodiscard]] asset_type_t GetImageAssetType() const override; - }; -} // namespace IW4 diff --git a/src/Linker/Game/IW5/ZoneCreatorIW5.cpp b/src/Linker/Game/IW5/ZoneCreatorIW5.cpp deleted file mode 100644 index c7700dd4..00000000 --- a/src/Linker/Game/IW5/ZoneCreatorIW5.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "ZoneCreatorIW5.h" - -#include "Game/IW5/IW5.h" - -using namespace IW5; - -GameId ZoneCreator::GetGameId() const -{ - return GameId::IW5; -} - -asset_type_t ZoneCreator::GetImageAssetType() const -{ - return ASSET_TYPE_IMAGE; -} diff --git a/src/Linker/Game/IW5/ZoneCreatorIW5.h b/src/Linker/Game/IW5/ZoneCreatorIW5.h deleted file mode 100644 index 02856166..00000000 --- a/src/Linker/Game/IW5/ZoneCreatorIW5.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "ZoneCreation/ZoneCreator.h" - -namespace IW5 -{ - class ZoneCreator final : public IZoneCreator - { - public: - [[nodiscard]] GameId GetGameId() const override; - [[nodiscard]] asset_type_t GetImageAssetType() const override; - }; -} // namespace IW5 diff --git a/src/Linker/Game/T5/ZoneCreatorT5.cpp b/src/Linker/Game/T5/ZoneCreatorT5.cpp deleted file mode 100644 index 47dc181d..00000000 --- a/src/Linker/Game/T5/ZoneCreatorT5.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "ZoneCreatorT5.h" - -#include "Game/T5/T5.h" - -using namespace T5; - -GameId ZoneCreator::GetGameId() const -{ - return GameId::T5; -} - -asset_type_t ZoneCreator::GetImageAssetType() const -{ - return ASSET_TYPE_IMAGE; -} diff --git a/src/Linker/Game/T5/ZoneCreatorT5.h b/src/Linker/Game/T5/ZoneCreatorT5.h deleted file mode 100644 index 25e34eb2..00000000 --- a/src/Linker/Game/T5/ZoneCreatorT5.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "ZoneCreation/ZoneCreator.h" - -namespace T5 -{ - class ZoneCreator final : public IZoneCreator - { - public: - [[nodiscard]] GameId GetGameId() const override; - [[nodiscard]] asset_type_t GetImageAssetType() const override; - }; -} // namespace T5 diff --git a/src/Linker/Game/T6/ZoneCreatorT6.h b/src/Linker/Game/T6/ZoneCreatorT6.h deleted file mode 100644 index 5ec4a9db..00000000 --- a/src/Linker/Game/T6/ZoneCreatorT6.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "ZoneCreation/ZoneCreator.h" - -namespace T6 -{ - class ZoneCreator final : public IZoneCreator - { - public: - [[nodiscard]] GameId GetGameId() const override; - [[nodiscard]] asset_type_t GetImageAssetType() const override; - - protected: - void HandleMetadata(Zone& zone, const ZoneCreationContext& context) const override; - }; -} // namespace T6 diff --git a/src/Linker/Linker.cpp b/src/Linker/Linker.cpp index 6af6b286..3aee78ab 100644 --- a/src/Linker/Linker.cpp +++ b/src/Linker/Linker.cpp @@ -344,8 +344,7 @@ class LinkerImpl final : public Linker if (!LoadGdtFilesFromZoneDefinition(context.m_gdt_files, zoneDefinition, &paths.m_gdt_paths.GetSearchPaths())) return nullptr; - const auto* creator = IZoneCreator::GetCreatorForGame(zoneDefinition.m_game); - return creator->CreateZoneForDefinition(context); + return zone_creator::CreateZoneForDefinition(zoneDefinition.m_game, context); } bool WriteZoneToFile(const LinkerPathManager& paths, const std::string& projectName, Zone* zone) const @@ -390,41 +389,41 @@ class LinkerImpl final : public Linker return result; } - bool BuildIPak(const LinkerPathManager& paths, const std::string& projectName, const ZoneDefinition& zoneDefinition, SearchPaths& assetSearchPaths) const - { - const fs::path ipakFolderPath(paths.m_linker_paths->BuildOutputFolderPath(projectName, zoneDefinition.m_game)); - auto ipakFilePath(ipakFolderPath); - ipakFilePath.append(std::format("{}.ipak", zoneDefinition.m_name)); + // bool BuildIPak(const LinkerPathManager& paths, const std::string& projectName, const ZoneDefinition& zoneDefinition, SearchPaths& assetSearchPaths) const + // { + // const fs::path ipakFolderPath(paths.m_linker_paths->BuildOutputFolderPath(projectName, zoneDefinition.m_game)); + // auto ipakFilePath(ipakFolderPath); + // ipakFilePath.append(std::format("{}.ipak", zoneDefinition.m_name)); - fs::create_directories(ipakFolderPath); + // fs::create_directories(ipakFolderPath); - std::ofstream stream(ipakFilePath, std::fstream::out | std::fstream::binary); - if (!stream.is_open()) - return false; + // std::ofstream stream(ipakFilePath, std::fstream::out | std::fstream::binary); + // if (!stream.is_open()) + // return false; - const auto ipakWriter = IPakWriter::Create(stream, &assetSearchPaths); - const auto imageAssetType = IZoneCreator::GetCreatorForGame(zoneDefinition.m_game)->GetImageAssetType(); - for (const auto& assetEntry : zoneDefinition.m_assets) - { - if (assetEntry.m_is_reference) - continue; + // const auto ipakWriter = IPakWriter::Create(stream, &assetSearchPaths); + // const auto imageAssetType = IZoneCreator::GetCreatorForGame(zoneDefinition.m_game)->GetImageAssetType(); + // for (const auto& assetEntry : zoneDefinition.m_assets) + // { + // if (assetEntry.m_is_reference) + // continue; - if (assetEntry.m_asset_type == imageAssetType) - ipakWriter->AddImage(assetEntry.m_asset_name); - } + // if (assetEntry.m_asset_type == imageAssetType) + // ipakWriter->AddImage(assetEntry.m_asset_name); + // } - if (!ipakWriter->Write()) - { - std::cerr << "Writing ipak failed.\n"; - stream.close(); - return false; - } + // if (!ipakWriter->Write()) + // { + // std::cerr << "Writing ipak failed.\n"; + // stream.close(); + // return false; + // } - std::cout << std::format("Created ipak \"{}\"\n", ipakFilePath.string()); + // std::cout << std::format("Created ipak \"{}\"\n", ipakFilePath.string()); - stream.close(); - return true; - } + // stream.close(); + // return true; + // } bool BuildProject(LinkerPathManager& paths, const std::string& projectName, const std::string& targetName) const { diff --git a/src/Linker/ZoneCreation/ZoneCreator.cpp b/src/Linker/ZoneCreation/ZoneCreator.cpp index 4cb25667..8535829a 100644 --- a/src/Linker/ZoneCreation/ZoneCreator.cpp +++ b/src/Linker/ZoneCreation/ZoneCreator.cpp @@ -1,34 +1,11 @@ #include "ZoneCreator.h" #include "AssetLoading/AssetLoadingContext.h" -#include "Game/IW3/ZoneCreatorIW3.h" -#include "Game/IW4/ZoneCreatorIW4.h" -#include "Game/IW5/ZoneCreatorIW5.h" -#include "Game/T5/ZoneCreatorT5.h" -#include "Game/T6/ZoneCreatorT6.h" #include "IObjCompiler.h" #include "IObjLoader.h" #include -const IZoneCreator* IZoneCreator::GetCreatorForGame(GameId game) -{ - static const IZoneCreator* zoneCreators[static_cast(GameId::COUNT)]{ - new IW3::ZoneCreator(), - new IW4::ZoneCreator(), - new IW5::ZoneCreator(), - new T5::ZoneCreator(), - new T6::ZoneCreator(), - }; - static_assert(std::extent_v == static_cast(GameId::COUNT)); - - assert(static_cast(game) < static_cast(GameId::COUNT)); - const auto* result = zoneCreators[static_cast(game)]; - assert(result); - - return result; -} - namespace { std::unique_ptr CreateZone(const ZoneCreationContext& context, const GameId gameId) @@ -64,43 +41,37 @@ namespace context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name, assetEntry.m_is_reference); } } - - void ApplyIgnoredAssetsToLoadingContext(const ZoneCreationContext& creationContext, AssetLoadingContext& loadingContext) - { - for (const auto& ignoreEntry : creationContext.m_ignored_assets.m_entries) - loadingContext.m_ignored_asset_map[ignoreEntry.m_name] = ignoreEntry.m_type; - } } // namespace -std::unique_ptr IZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const +namespace zone_creator { - const auto gameId = GetGameId(); - - auto zone = CreateZone(context, gameId); - InitializeAssetPools(*zone, gameId); - - AssetLoadingContext assetLoadingContext(*zone, *context.m_asset_search_path, CreateGdtList(context)); - IgnoreReferencesFromAssets(context); - ApplyIgnoredAssetsToLoadingContext(context, assetLoadingContext); - - HandleMetadata(*zone, context); - - const auto* objCompiler = IObjCompiler::GetObjCompilerForGame(gameId); - const auto* objLoader = IObjLoader::GetObjLoaderForGame(gameId); - for (const auto& assetEntry : context.m_definition->m_assets) + std::unique_ptr CreateZoneForDefinition(GameId gameId, ZoneCreationContext& context) { - const auto compilerResult = objCompiler->CompileAssetForZone(assetLoadingContext, assetEntry.m_asset_type, assetEntry.m_asset_name); - if (compilerResult == ObjCompilerResult::FAILURE) - return nullptr; + auto zone = CreateZone(context, gameId); + InitializeAssetPools(*zone, gameId); - if (compilerResult == ObjCompilerResult::NO_COMPILATION_DONE) + IgnoreReferencesFromAssets(context); + IgnoredAssetLookup ignoredAssetLookup(context.m_ignored_assets); + + const auto* objCompiler = IObjCompiler::GetObjCompilerForGame(gameId); + const auto* objLoader = IObjLoader::GetObjLoaderForGame(gameId); + + AssetCreatorCollection creatorCollection(*zone); + objCompiler->ConfigureCreatorCollection(creatorCollection, *zone, *context.m_definition); + objLoader->ConfigureCreatorCollection(creatorCollection); + + AssetCreationContext creationContext(zone.get(), &creatorCollection, &ignoredAssetLookup); + + for (const auto& assetEntry : context.m_definition->m_assets) { - if (!objLoader->LoadAssetForZone(assetLoadingContext, assetEntry.m_asset_type, assetEntry.m_asset_name)) + const auto* createdAsset = creationContext.LoadDependencyGeneric(assetEntry.m_asset_type, assetEntry.m_asset_name); + + if (!createdAsset) return nullptr; } + + creatorCollection.FinalizeZone(creationContext); + + return zone; } - - objLoader->FinalizeAssetsForZone(assetLoadingContext); - - return zone; -} +} // namespace zone_creator diff --git a/src/Linker/ZoneCreation/ZoneCreator.h b/src/Linker/ZoneCreation/ZoneCreator.h index 05cc729f..c95c7cd9 100644 --- a/src/Linker/ZoneCreation/ZoneCreator.h +++ b/src/Linker/ZoneCreation/ZoneCreator.h @@ -3,23 +3,7 @@ #include "Zone/Zone.h" #include "ZoneCreationContext.h" -class IZoneCreator +namespace zone_creator { -public: - IZoneCreator() = default; - virtual ~IZoneCreator() = default; - IZoneCreator(const IZoneCreator& other) = default; - IZoneCreator(IZoneCreator&& other) noexcept = default; - IZoneCreator& operator=(const IZoneCreator& other) = default; - IZoneCreator& operator=(IZoneCreator&& other) noexcept = default; - - [[nodiscard]] virtual GameId GetGameId() const = 0; - [[nodiscard]] virtual asset_type_t GetImageAssetType() const = 0; - - [[nodiscard]] std::unique_ptr CreateZoneForDefinition(ZoneCreationContext& context) const; - - static const IZoneCreator* GetCreatorForGame(GameId game); - -protected: - virtual void HandleMetadata(Zone& zone, const ZoneCreationContext& context) const {} -}; + [[nodiscard]] std::unique_ptr CreateZoneForDefinition(GameId game, ZoneCreationContext& context); +} diff --git a/src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp b/src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp index c0a754db..cf73b2cb 100644 --- a/src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp +++ b/src/ObjCompiling/Game/IW3/ObjCompilerIW3.cpp @@ -2,7 +2,4 @@ using namespace IW3; -ObjCompilerResult ObjCompiler::CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const -{ - return ObjCompilerResult::NO_COMPILATION_DONE; -} +void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const {} diff --git a/src/ObjCompiling/Game/IW3/ObjCompilerIW3.h b/src/ObjCompiling/Game/IW3/ObjCompilerIW3.h index 0f364b10..6b161b07 100644 --- a/src/ObjCompiling/Game/IW3/ObjCompilerIW3.h +++ b/src/ObjCompiling/Game/IW3/ObjCompilerIW3.h @@ -7,6 +7,6 @@ namespace IW3 class ObjCompiler final : public IObjCompiler { public: - ObjCompilerResult CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const override; }; } // namespace IW3 diff --git a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp index d560aa15..8f7c42b8 100644 --- a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp +++ b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.cpp @@ -2,7 +2,4 @@ using namespace IW4; -ObjCompilerResult ObjCompiler::CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const -{ - return ObjCompilerResult::NO_COMPILATION_DONE; -} +void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const {} diff --git a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.h b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.h index fe52b3a7..980e6a2d 100644 --- a/src/ObjCompiling/Game/IW4/ObjCompilerIW4.h +++ b/src/ObjCompiling/Game/IW4/ObjCompilerIW4.h @@ -7,6 +7,6 @@ namespace IW4 class ObjCompiler final : public IObjCompiler { public: - ObjCompilerResult CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const override; }; } // namespace IW4 diff --git a/src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp b/src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp index ced84ecf..3d0b99d7 100644 --- a/src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp +++ b/src/ObjCompiling/Game/IW5/ObjCompilerIW5.cpp @@ -2,7 +2,4 @@ using namespace IW5; -ObjCompilerResult ObjCompiler::CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const -{ - return ObjCompilerResult::NO_COMPILATION_DONE; -} +void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const {} diff --git a/src/ObjCompiling/Game/IW5/ObjCompilerIW5.h b/src/ObjCompiling/Game/IW5/ObjCompilerIW5.h index b2d07c9a..5ff7229b 100644 --- a/src/ObjCompiling/Game/IW5/ObjCompilerIW5.h +++ b/src/ObjCompiling/Game/IW5/ObjCompilerIW5.h @@ -7,6 +7,6 @@ namespace IW5 class ObjCompiler final : public IObjCompiler { public: - ObjCompilerResult CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const override; }; } // namespace IW5 diff --git a/src/ObjCompiling/Game/T5/ObjCompilerT5.cpp b/src/ObjCompiling/Game/T5/ObjCompilerT5.cpp index 9b4794de..5fae8470 100644 --- a/src/ObjCompiling/Game/T5/ObjCompilerT5.cpp +++ b/src/ObjCompiling/Game/T5/ObjCompilerT5.cpp @@ -2,7 +2,4 @@ using namespace T5; -ObjCompilerResult ObjCompiler::CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const -{ - return ObjCompilerResult::NO_COMPILATION_DONE; -} +void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const {} diff --git a/src/ObjCompiling/Game/T5/ObjCompilerT5.h b/src/ObjCompiling/Game/T5/ObjCompilerT5.h index c4130338..a4cd6c20 100644 --- a/src/ObjCompiling/Game/T5/ObjCompilerT5.h +++ b/src/ObjCompiling/Game/T5/ObjCompilerT5.h @@ -7,6 +7,6 @@ namespace T5 class ObjCompiler final : public IObjCompiler { public: - ObjCompilerResult CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const override; }; } // namespace T5 diff --git a/src/ObjCompiling/Game/T6/Image/ImageCompilerT6.cpp b/src/ObjCompiling/Game/T6/Image/ImageCompilerT6.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/ObjCompiling/Game/T6/Image/ImageCompilerT6.h b/src/ObjCompiling/Game/T6/Image/ImageCompilerT6.h new file mode 100644 index 00000000..e69de29b diff --git a/src/Linker/Game/T6/ZoneCreatorT6.cpp b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCreator.cpp similarity index 55% rename from src/Linker/Game/T6/ZoneCreatorT6.cpp rename to src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCreator.cpp index 7bf7d79d..aab09be9 100644 --- a/src/Linker/Game/T6/ZoneCreatorT6.cpp +++ b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCreator.cpp @@ -1,30 +1,30 @@ -#include "ZoneCreatorT6.h" +#include "KeyValuePairsCreator.h" #include "Game/T6/CommonT6.h" #include "Game/T6/T6.h" -#include "IObjLoader.h" -#include "ObjLoading.h" #include #include using namespace T6; -GameId ZoneCreator::GetGameId() const +KeyValuePairsCreator::KeyValuePairsCreator(const Zone& zone, const ZoneDefinition& zoneDefinition) + : m_zone(zone), + m_zone_definition(zoneDefinition) { - return GameId::T6; } -asset_type_t ZoneCreator::GetImageAssetType() const +AssetCreationResult KeyValuePairsCreator::CreateAsset(const std::string& assetName, AssetCreationContext& context) { - return ASSET_TYPE_IMAGE; + return AssetCreationResult::NoAction(); } -void ZoneCreator::HandleMetadata(Zone& zone, const ZoneCreationContext& context) const +void KeyValuePairsCreator::FinalizeZone(AssetCreationContext& context) { std::vector kvpList; + auto& memory = *m_zone.GetMemory(); - for (const auto& metaData : context.m_definition->m_properties.m_properties) + for (const auto& metaData : m_zone_definition.m_properties.m_properties) { if (metaData.first.rfind("level.", 0) == 0) { @@ -49,21 +49,21 @@ void ZoneCreator::HandleMetadata(Zone& zone, const ZoneCreationContext& context) keyHash = Common::Com_HashKey(strValue.c_str(), 64); } - KeyValuePair kvp{keyHash, Common::Com_HashKey(zone.m_name.c_str(), 64), zone.GetMemory()->Dup(metaData.second.c_str())}; + KeyValuePair kvp{keyHash, Common::Com_HashKey(m_zone.m_name.c_str(), 64), memory.Dup(metaData.second.c_str())}; kvpList.push_back(kvp); } } if (!kvpList.empty()) { - auto* kvps = zone.GetMemory()->Create(); - kvps->name = zone.GetMemory()->Dup(zone.m_name.c_str()); + auto* kvps = memory.Create(); + kvps->name = memory.Dup(m_zone.m_name.c_str()); kvps->numVariables = static_cast(kvpList.size()); - kvps->keyValuePairs = zone.GetMemory()->Alloc(kvpList.size()); + kvps->keyValuePairs = m_zone.GetMemory()->Alloc(kvpList.size()); for (auto i = 0u; i < kvpList.size(); i++) kvps->keyValuePairs[i] = kvpList[i]; - zone.m_pools->AddAsset(std::make_unique>(ASSET_TYPE_KEYVALUEPAIRS, zone.m_name, kvps)); + context.AddAsset(AssetRegistration(m_zone.m_name, kvps)); } } diff --git a/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCreator.h b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCreator.h new file mode 100644 index 00000000..f826110e --- /dev/null +++ b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCreator.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/T6/T6.h" +#include "Zone/Definition/ZoneDefinition.h" + +namespace T6 +{ + class KeyValuePairsCreator : public AssetCreator + { + public: + KeyValuePairsCreator(const Zone& zone, const ZoneDefinition& zoneDefinition); + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override; + void FinalizeZone(AssetCreationContext& context) override; + + private: + const Zone& m_zone; + const ZoneDefinition& m_zone_definition; + }; +} // namespace T6 diff --git a/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp b/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp index 3064e1cb..8b82b69d 100644 --- a/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp +++ b/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp @@ -1,8 +1,7 @@ #include "ObjCompilerT6.h" +#include "Game/T6/T6.h" + using namespace T6; -ObjCompilerResult ObjCompiler::CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const -{ - return ObjCompilerResult::NO_COMPILATION_DONE; -} +void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const {} diff --git a/src/ObjCompiling/Game/T6/ObjCompilerT6.h b/src/ObjCompiling/Game/T6/ObjCompilerT6.h index d5283dcc..29f312ae 100644 --- a/src/ObjCompiling/Game/T6/ObjCompilerT6.h +++ b/src/ObjCompiling/Game/T6/ObjCompilerT6.h @@ -7,6 +7,6 @@ namespace T6 class ObjCompiler final : public IObjCompiler { public: - ObjCompilerResult CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const override; }; } // namespace T6 diff --git a/src/ObjCompiling/IObjCompiler.h b/src/ObjCompiling/IObjCompiler.h index 3ef095ab..c03a0ef5 100644 --- a/src/ObjCompiling/IObjCompiler.h +++ b/src/ObjCompiling/IObjCompiler.h @@ -1,19 +1,14 @@ #pragma once +#include "Asset/AssetCreatorCollection.h" #include "AssetLoading/AssetLoadingContext.h" #include "SearchPath/ISearchPath.h" +#include "Zone/Definition/ZoneDefinition.h" #include "Zone/Zone.h" #include #include -enum class ObjCompilerResult : std::uint8_t -{ - COMPILED, - NO_COMPILATION_DONE, - FAILURE -}; - class IObjCompiler { public: @@ -24,7 +19,7 @@ public: IObjCompiler& operator=(const IObjCompiler& other) = default; IObjCompiler& operator=(IObjCompiler&& other) noexcept = default; - virtual ObjCompilerResult CompileAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const = 0; + virtual void ConfigureCreatorCollection(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinition& zoneDefinition) const = 0; static const IObjCompiler* GetObjCompilerForGame(GameId game); }; diff --git a/src/ObjLoading/Asset/AssetCreationContext.cpp b/src/ObjLoading/Asset/AssetCreationContext.cpp new file mode 100644 index 00000000..58159f12 --- /dev/null +++ b/src/ObjLoading/Asset/AssetCreationContext.cpp @@ -0,0 +1,135 @@ +#include "AssetCreationContext.h" + +#include +#include + +IgnoredAssetLookup::IgnoredAssetLookup(const AssetList& assetList) +{ + m_ignored_asset_lookup.reserve(assetList.m_entries.size()); + for (const auto& asset : assetList.m_entries) + { + m_ignored_asset_lookup.emplace(asset.m_name, asset.m_type); + } +} + +bool IgnoredAssetLookup::IsAssetIgnored(asset_type_t assetType, const std::string& name) const +{ + const auto entries = m_ignored_asset_lookup.equal_range(name); + + for (auto i = entries.first; i != entries.second; ++i) + { + if (i->second == assetType) + return true; + } + + return false; +} + +GenericAssetRegistration::GenericAssetRegistration(const asset_type_t type, std::string name, void* asset) + : m_type(type), + m_name(std::move(name)), + m_asset(asset) +{ +} + +void GenericAssetRegistration::AddDependency(XAssetInfoGeneric* dependency) +{ + m_dependencies.emplace(dependency); +} + +void GenericAssetRegistration::AddScriptString(scr_string_t scriptString) +{ + m_used_script_strings.emplace(scriptString); +} + +void GenericAssetRegistration::AddIndirectAssetReference(IndirectAssetReference indirectAssetReference) +{ + m_indirect_asset_references.emplace(std::move(indirectAssetReference)); +} + +std::unique_ptr GenericAssetRegistration::CreateXAssetInfo() +{ + std::vector dependencies(m_dependencies.begin(), m_dependencies.end()); + std::vector scriptStrings(m_used_script_strings.begin(), m_used_script_strings.end()); + std::vector indirectAssetReferences(m_indirect_asset_references.begin(), m_indirect_asset_references.end()); + + return std::make_unique( + m_type, std::move(m_name), m_asset, std::move(dependencies), std::move(scriptStrings), std::move(indirectAssetReferences)); +} + +AssetCreationContext::AssetCreationContext(Zone* zone, const AssetCreatorCollection* creators, const IgnoredAssetLookup* ignoredAssetLookup) + : m_zone(zone), + m_creators(creators), + m_ignored_asset_lookup(ignoredAssetLookup) +{ +} + +XAssetInfoGeneric* AssetCreationContext::AddAssetGeneric(GenericAssetRegistration registration) const +{ + auto xAssetInfo = registration.CreateXAssetInfo(); + xAssetInfo->m_zone = m_zone; + + const auto assetType = xAssetInfo->m_type; + const auto* pAssetName = xAssetInfo->m_name.c_str(); + + auto* addedAsset = m_zone->m_pools->AddAsset(std::move(xAssetInfo)); + if (addedAsset == nullptr) + std::cerr << std::format("Failed to add asset of type \"{}\" to pool: \"{}\"\n", *m_zone->m_pools->GetAssetTypeName(assetType), pAssetName); + + return addedAsset; +} + +XAssetInfoGeneric* AssetCreationContext::LoadDefaultAssetDependency(const asset_type_t assetType, const std::string& assetName) const +{ + const auto result = m_creators->CreateDefaultAsset(assetType, assetName, *this); + if (result.HasTakenAction() && !result.HasFailed()) + return result.GetAssetInfo(); + + std::cerr << std::format("Failed to create default asset of type {}\n", *m_zone->m_pools->GetAssetTypeName(assetType)); + + return nullptr; +} + +XAssetInfoGeneric* AssetCreationContext::LoadDependencyGeneric(const asset_type_t assetType, const std::string& assetName) +{ + auto* alreadyLoadedAsset = m_zone->m_pools->GetAssetOrAssetReference(assetType, assetName); + if (alreadyLoadedAsset) + return alreadyLoadedAsset; + + if (m_ignored_asset_lookup->IsAssetIgnored(assetType, assetName)) + return LoadDefaultAssetDependency(assetType, std::format(",{}", assetName)); + + const auto result = m_creators->CreateAsset(assetType, assetName, *this); + if (result.HasTakenAction()) + { + if (!result.HasFailed()) + return result.GetAssetInfo(); + + std::cerr << std::format( + "Could not load indirectly referenced asset \"{}\" of type \"{}\"\n", assetName, *m_zone->m_pools->GetAssetTypeName(assetType)); + } + else + { + std::cerr << std::format("Could not find creator for asset \"{}\" of type \"{}\"\n", assetName, *m_zone->m_pools->GetAssetTypeName(assetType)); + } + + return nullptr; +} + +IndirectAssetReference AssetCreationContext::LoadIndirectAssetReferenceGeneric(asset_type_t assetType, const std::string& assetName) +{ + auto* alreadyLoadedAsset = m_zone->m_pools->GetAssetOrAssetReference(assetType, assetName); + if (alreadyLoadedAsset) + return IndirectAssetReference(assetType, assetName); + + if (m_ignored_asset_lookup->IsAssetIgnored(assetType, assetName)) + return IndirectAssetReference(assetType, assetName); + + const auto result = m_creators->CreateAsset(assetType, assetName, *this); + if (!result.HasTakenAction() && !result.HasFailed()) + { + std::cerr << std::format( + "Could not load indirectly referenced asset \"{}\" of type \"{}\"\n", assetName, *m_zone->m_pools->GetAssetTypeName(assetType)); + } + return IndirectAssetReference(assetType, assetName); +} diff --git a/src/ObjLoading/Asset/AssetCreationContext.h b/src/ObjLoading/Asset/AssetCreationContext.h new file mode 100644 index 00000000..1e837494 --- /dev/null +++ b/src/ObjLoading/Asset/AssetCreationContext.h @@ -0,0 +1,85 @@ +#pragma once + +#include "AssetCreatorCollection.h" +#include "AssetLoading/IZoneAssetLoaderState.h" +#include "AssetRegistration.h" +#include "Game/IAsset.h" +#include "Pool/XAssetInfo.h" +#include "Zone/AssetList/AssetList.h" +#include "Zone/ZoneTypes.h" + +#include +#include +#include +#include +#include +#include + +class AssetCreatorCollection; + +class IgnoredAssetLookup +{ +public: + explicit IgnoredAssetLookup(const AssetList& assetList); + + [[nodiscard]] bool IsAssetIgnored(asset_type_t assetType, const std::string& name) const; + + std::unordered_multimap m_ignored_asset_lookup; +}; + +class AssetCreationContext +{ +public: + AssetCreationContext(Zone* zone, const AssetCreatorCollection* creators, const IgnoredAssetLookup* ignoredAssetLookup); + + template XAssetInfo* AddAsset(AssetRegistration registration) + { + static_assert(std::is_base_of_v); + + return static_cast*>(AddAssetGeneric(std::move(registration))); + } + + XAssetInfoGeneric* AddAssetGeneric(GenericAssetRegistration registration) const; + + template XAssetInfo* LoadDependency(const std::string& assetName) + { + static_assert(std::is_base_of_v); + + return static_cast*>(LoadDependencyInternal(AssetType::EnumEntry, assetName)); + } + + XAssetInfoGeneric* LoadDependencyGeneric(asset_type_t assetType, const std::string& assetName); + + template IndirectAssetReference LoadIndirectAssetReference(const std::string& assetName) + { + static_assert(std::is_base_of_v); + + return LoadIndirectAssetReferenceInternal(AssetType::EnumEntry, assetName); + } + + IndirectAssetReference LoadIndirectAssetReferenceGeneric(asset_type_t assetType, const std::string& assetName); + + template T* GetZoneAssetLoaderState() + { + static_assert(std::is_base_of_v, "T must inherit IZoneAssetLoaderState"); + // T must also have a public default constructor + + const auto foundEntry = m_zone_asset_loader_states.find(typeid(T)); + if (foundEntry != m_zone_asset_loader_states.end()) + return dynamic_cast(foundEntry->second.get()); + + auto newState = std::make_unique(); + newState->SetZone(&m_zone); + auto* newStatePtr = newState.get(); + m_zone_asset_loader_states.emplace(std::make_pair>(typeid(T), std::move(newState))); + return newStatePtr; + } + +private: + [[nodiscard]] XAssetInfoGeneric* LoadDefaultAssetDependency(asset_type_t assetType, const std::string& assetName) const; + + Zone* m_zone; + const AssetCreatorCollection* m_creators; + const IgnoredAssetLookup* m_ignored_asset_lookup; + std::unordered_map> m_zone_asset_loader_states; +}; diff --git a/src/ObjLoading/Asset/AssetCreatorCollection.cpp b/src/ObjLoading/Asset/AssetCreatorCollection.cpp new file mode 100644 index 00000000..eb7c180f --- /dev/null +++ b/src/ObjLoading/Asset/AssetCreatorCollection.cpp @@ -0,0 +1,65 @@ +#include "AssetCreatorCollection.h" + +#include + +AssetCreatorCollection::AssetCreatorCollection(const Zone& zone) +{ + m_asset_creators_by_type.resize(zone.m_pools->GetAssetTypeCount()); +} + +void AssetCreatorCollection::AddAssetCreator(std::unique_ptr creator) +{ + const auto maybeHandlingAssetType = creator->GetHandlingAssetType(); + assert(!maybeHandlingAssetType || static_cast(*maybeHandlingAssetType) < m_asset_creators_by_type.size()); + if (maybeHandlingAssetType && static_cast(*maybeHandlingAssetType) < m_asset_creators_by_type.size()) + m_asset_creators_by_type[static_cast(*maybeHandlingAssetType)].emplace_back(creator.get()); + + m_asset_creators.emplace_back(std::move(creator)); +} + +void AssetCreatorCollection::AddDefaultAssetCreator(std::unique_ptr defaultAssetCreator) +{ + const auto handlingAssetType = defaultAssetCreator->GetHandlingAssetType(); + assert(static_cast(handlingAssetType) < m_default_asset_creators_by_type.size()); + assert(!m_default_asset_creators_by_type[handlingAssetType]); + + if (static_cast(handlingAssetType) < m_default_asset_creators_by_type.size()) + m_default_asset_creators_by_type[handlingAssetType] = std::move(defaultAssetCreator); +} + +AssetCreationResult AssetCreatorCollection::CreateAsset(const asset_type_t assetType, const std::string& assetName, AssetCreationContext& context) const +{ + assert(assetType >= 0 && static_cast(assetType) < m_asset_creators_by_type.size()); + + if (assetType >= 0 && static_cast(assetType) < m_asset_creators_by_type.size()) + { + for (const auto& creator : m_asset_creators_by_type[assetType]) + { + const auto result = creator->CreateAsset(assetName, context); + if (result.HasTakenAction()) + return result; + } + } + + return AssetCreationResult::NoAction(); +} + +AssetCreationResult + AssetCreatorCollection::CreateDefaultAsset(const asset_type_t assetType, const std::string& assetName, const AssetCreationContext& context) const +{ + assert(assetType >= 0 && static_cast(assetType) < m_default_asset_creators_by_type.size()); + + if (assetType >= 0 && static_cast(assetType) < m_default_asset_creators_by_type.size() && m_default_asset_creators_by_type[assetType]) + { + auto defaultAsset = m_default_asset_creators_by_type[assetType]->CreateDefaultAsset(assetName); + return AssetCreationResult::Success(context.AddAssetGeneric(std::move(defaultAsset))); + } + + return AssetCreationResult::NoAction(); +} + +void AssetCreatorCollection::FinalizeZone(AssetCreationContext& context) const +{ + for (const auto& creator : m_asset_creators) + creator->FinalizeZone(context); +} diff --git a/src/ObjLoading/Asset/AssetCreatorCollection.h b/src/ObjLoading/Asset/AssetCreatorCollection.h new file mode 100644 index 00000000..89604ab7 --- /dev/null +++ b/src/ObjLoading/Asset/AssetCreatorCollection.h @@ -0,0 +1,32 @@ +#pragma once + +#include "AssetCreationContext.h" +#include "Game/IGame.h" +#include "IAssetCreator.h" +#include "IDefaultAssetCreator.h" +#include "Zone/ZoneTypes.h" + +#include + +class AssetCreationContext; +class IAssetCreator; +class AssetCreationResult; +class IDefaultAssetCreator; + +class AssetCreatorCollection +{ +public: + explicit AssetCreatorCollection(const Zone& zone); + + void AddAssetCreator(std::unique_ptr creator); + void AddDefaultAssetCreator(std::unique_ptr defaultAssetCreator); + + AssetCreationResult CreateAsset(asset_type_t assetType, const std::string& assetName, AssetCreationContext& context) const; + AssetCreationResult CreateDefaultAsset(asset_type_t assetType, const std::string& assetName, const AssetCreationContext& context) const; + void FinalizeZone(AssetCreationContext& context) const; + +private: + std::vector> m_asset_creators_by_type; + std::vector> m_default_asset_creators_by_type; + std::vector> m_asset_creators; +}; diff --git a/src/ObjLoading/Asset/AssetRegistration.h b/src/ObjLoading/Asset/AssetRegistration.h new file mode 100644 index 00000000..18e9794b --- /dev/null +++ b/src/ObjLoading/Asset/AssetRegistration.h @@ -0,0 +1,51 @@ +#pragma once + +#include "Game/IAsset.h" +#include "Pool/XAssetInfo.h" +#include "Zone/ZoneTypes.h" + +#include +#include +#include + +class GenericAssetRegistration +{ +protected: + GenericAssetRegistration(asset_type_t type, std::string name, void* asset); + +public: + GenericAssetRegistration(const GenericAssetRegistration& other) = delete; + GenericAssetRegistration(GenericAssetRegistration&& other) = default; + GenericAssetRegistration& operator=(const GenericAssetRegistration& other) = delete; + GenericAssetRegistration& operator=(GenericAssetRegistration&& other) noexcept = default; + + void AddDependency(XAssetInfoGeneric* dependency); + void AddScriptString(scr_string_t scriptString); + void AddIndirectAssetReference(IndirectAssetReference indirectAssetReference); + + std::unique_ptr CreateXAssetInfo(); + +private: + asset_type_t m_type; + std::string m_name; + void* m_asset; + std::unordered_set m_dependencies; + std::unordered_set m_used_script_strings; + std::unordered_set m_indirect_asset_references; +}; + +template class AssetRegistration : public GenericAssetRegistration +{ + static_assert(std::is_base_of_v); + +public: + AssetRegistration(std::string assetName, typename AssetType::Type* asset) + : GenericAssetRegistration(AssetType::EnumEntry, std::move(assetName), asset) + { + } + + AssetRegistration(const AssetRegistration& other) = delete; + AssetRegistration(AssetRegistration&& other) = default; + AssetRegistration& operator=(const AssetRegistration& other) = delete; + AssetRegistration& operator=(AssetRegistration&& other) noexcept = default; +}; diff --git a/src/ObjLoading/Asset/IAssetCreator.cpp b/src/ObjLoading/Asset/IAssetCreator.cpp new file mode 100644 index 00000000..b2482ea1 --- /dev/null +++ b/src/ObjLoading/Asset/IAssetCreator.cpp @@ -0,0 +1,37 @@ +#include "IAssetCreator.h" + +AssetCreationResult AssetCreationResult::Success(XAssetInfoGeneric* assetInfo) +{ + return AssetCreationResult(true, assetInfo); +} + +AssetCreationResult AssetCreationResult::Failure() +{ + return AssetCreationResult(true, nullptr); +} + +AssetCreationResult AssetCreationResult::NoAction() +{ + return AssetCreationResult(false, nullptr); +} + +bool AssetCreationResult::HasTakenAction() const +{ + return m_taken_action; +} + +bool AssetCreationResult::HasFailed() const +{ + return m_taken_action && m_asset_info == nullptr; +} + +XAssetInfoGeneric* AssetCreationResult::GetAssetInfo() const +{ + return m_asset_info; +} + +AssetCreationResult::AssetCreationResult(const bool takenAction, XAssetInfoGeneric* assetInfo) + : m_taken_action(takenAction), + m_asset_info(assetInfo) +{ +} diff --git a/src/ObjLoading/Asset/IAssetCreator.h b/src/ObjLoading/Asset/IAssetCreator.h new file mode 100644 index 00000000..bc7c9c8e --- /dev/null +++ b/src/ObjLoading/Asset/IAssetCreator.h @@ -0,0 +1,57 @@ +#pragma once + +#include "AssetCreationContext.h" +#include "Game/IAsset.h" +#include "Pool/XAssetInfo.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" +#include "Zone/ZoneTypes.h" + +#include +#include + +class AssetCreationResult +{ +public: + static AssetCreationResult Success(XAssetInfoGeneric* assetInfo); + static AssetCreationResult Failure(); + static AssetCreationResult NoAction(); + + [[nodiscard]] bool HasTakenAction() const; + [[nodiscard]] bool HasFailed() const; + [[nodiscard]] XAssetInfoGeneric* GetAssetInfo() const; + +private: + AssetCreationResult(bool takenAction, XAssetInfoGeneric* assetInfo); + + bool m_taken_action; + XAssetInfoGeneric* m_asset_info; +}; + +class AssetCreationContext; + +class IAssetCreator +{ +public: + IAssetCreator() = default; + virtual ~IAssetCreator() = default; + IAssetCreator(const IAssetCreator& other) = default; + IAssetCreator(IAssetCreator&& other) noexcept = default; + IAssetCreator& operator=(const IAssetCreator& other) = default; + IAssetCreator& operator=(IAssetCreator&& other) noexcept = default; + + [[nodiscard]] virtual std::optional GetHandlingAssetType() const = 0; + virtual AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) = 0; + virtual void FinalizeZone(AssetCreationContext& context) {}; +}; + +template class AssetCreator : public IAssetCreator +{ +public: + static_assert(std::is_base_of_v); + + [[nodiscard]] std::optional GetHandlingAssetType() const override + { + return AssetType::EnumEntry; + }; +}; diff --git a/src/ObjLoading/Asset/IDefaultAssetCreator.h b/src/ObjLoading/Asset/IDefaultAssetCreator.h new file mode 100644 index 00000000..01d49778 --- /dev/null +++ b/src/ObjLoading/Asset/IDefaultAssetCreator.h @@ -0,0 +1,46 @@ +#pragma once + +#include "AssetCreationContext.h" +#include "AssetRegistration.h" +#include "Game/IAsset.h" +#include "Utils/MemoryManager.h" +#include "Zone/ZoneTypes.h" + +#include +#include + +class GenericAssetRegistration; +template class AssetRegistration; + +class IDefaultAssetCreator +{ +public: + IDefaultAssetCreator() = default; + virtual ~IDefaultAssetCreator() = default; + IDefaultAssetCreator(const IDefaultAssetCreator& other) = default; + IDefaultAssetCreator(IDefaultAssetCreator&& other) noexcept = default; + IDefaultAssetCreator& operator=(const IDefaultAssetCreator& other) = default; + IDefaultAssetCreator& operator=(IDefaultAssetCreator&& other) noexcept = default; + + [[nodiscard]] virtual asset_type_t GetHandlingAssetType() const = 0; + virtual GenericAssetRegistration CreateDefaultAsset(const std::string& assetName) const = 0; +}; + +template class DefaultAssetCreator : public IDefaultAssetCreator +{ +public: + static_assert(std::is_base_of_v); + + [[nodiscard]] asset_type_t GetHandlingAssetType() const override + { + return AssetType::EnumEntry; + } + + GenericAssetRegistration CreateDefaultAsset(const std::string& assetName) const override + { + return CreateDefaultAssetInternal(assetName); + } + +protected: + virtual AssetRegistration CreateDefaultAssetInternal(const std::string& assetName) const = 0; +}; diff --git a/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp b/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp index 4ea79be1..76c08a2d 100644 --- a/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp +++ b/src/ObjLoading/Game/IW3/ObjLoaderIW3.cpp @@ -62,6 +62,8 @@ void ObjLoader::LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& z void ObjLoader::UnloadContainersOfZone(Zone& zone) const {} +void ObjLoader::ConfigureCreatorCollection(AssetCreatorCollection& collection) const {} + bool ObjLoader::LoadAssetForZone(AssetLoadingContext& context, const asset_type_t assetType, const std::string& assetName) const { AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, context); diff --git a/src/ObjLoading/Game/IW3/ObjLoaderIW3.h b/src/ObjLoading/Game/IW3/ObjLoaderIW3.h index f027ecb4..887bd07c 100644 --- a/src/ObjLoading/Game/IW3/ObjLoaderIW3.h +++ b/src/ObjLoading/Game/IW3/ObjLoaderIW3.h @@ -22,6 +22,8 @@ namespace IW3 void LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const override; void UnloadContainersOfZone(Zone& zone) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection) const override; + bool LoadAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; void FinalizeAssetsForZone(AssetLoadingContext& context) const override; }; diff --git a/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp b/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp index 0960b737..80b06fef 100644 --- a/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp +++ b/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp @@ -106,6 +106,8 @@ void ObjLoader::LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& z void ObjLoader::UnloadContainersOfZone(Zone& zone) const {} +void ObjLoader::ConfigureCreatorCollection(AssetCreatorCollection& collection) const {} + bool ObjLoader::LoadAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const { AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, context); diff --git a/src/ObjLoading/Game/IW4/ObjLoaderIW4.h b/src/ObjLoading/Game/IW4/ObjLoaderIW4.h index ab4e10b3..9dd8798c 100644 --- a/src/ObjLoading/Game/IW4/ObjLoaderIW4.h +++ b/src/ObjLoading/Game/IW4/ObjLoaderIW4.h @@ -17,6 +17,8 @@ namespace IW4 void LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const override; void UnloadContainersOfZone(Zone& zone) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection) const override; + bool LoadAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; void FinalizeAssetsForZone(AssetLoadingContext& context) const override; diff --git a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp index de35f87a..f6920242 100644 --- a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp @@ -113,6 +113,8 @@ void ObjLoader::LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& z void ObjLoader::UnloadContainersOfZone(Zone& zone) const {} +void ObjLoader::ConfigureCreatorCollection(AssetCreatorCollection& collection) const {} + bool ObjLoader::LoadAssetForZone(AssetLoadingContext& context, const asset_type_t assetType, const std::string& assetName) const { AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, context); diff --git a/src/ObjLoading/Game/IW5/ObjLoaderIW5.h b/src/ObjLoading/Game/IW5/ObjLoaderIW5.h index 2b259032..4067dc8c 100644 --- a/src/ObjLoading/Game/IW5/ObjLoaderIW5.h +++ b/src/ObjLoading/Game/IW5/ObjLoaderIW5.h @@ -17,6 +17,8 @@ namespace IW5 void LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const override; void UnloadContainersOfZone(Zone& zone) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection) const override; + bool LoadAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; void FinalizeAssetsForZone(AssetLoadingContext& context) const override; diff --git a/src/ObjLoading/Game/T5/ObjLoaderT5.cpp b/src/ObjLoading/Game/T5/ObjLoaderT5.cpp index 3ec02cf4..66b0dc3d 100644 --- a/src/ObjLoading/Game/T5/ObjLoaderT5.cpp +++ b/src/ObjLoading/Game/T5/ObjLoaderT5.cpp @@ -70,6 +70,8 @@ void ObjLoader::LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& z void ObjLoader::UnloadContainersOfZone(Zone& zone) const {} +void ObjLoader::ConfigureCreatorCollection(AssetCreatorCollection& collection) const {} + bool ObjLoader::LoadAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const { AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, context); diff --git a/src/ObjLoading/Game/T5/ObjLoaderT5.h b/src/ObjLoading/Game/T5/ObjLoaderT5.h index 4ede43c4..743c0388 100644 --- a/src/ObjLoading/Game/T5/ObjLoaderT5.h +++ b/src/ObjLoading/Game/T5/ObjLoaderT5.h @@ -17,6 +17,8 @@ namespace T5 void LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const override; void UnloadContainersOfZone(Zone& zone) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection) const override; + bool LoadAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; void FinalizeAssetsForZone(AssetLoadingContext& context) const override; diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index 99d48000..a32be94e 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -356,6 +356,8 @@ namespace T6 IPak::Repository.RemoveContainerReferences(&zone); } + void ObjLoader::ConfigureCreatorCollection(AssetCreatorCollection& collection) const {} + bool ObjLoader::LoadAssetForZone(AssetLoadingContext& context, const asset_type_t assetType, const std::string& assetName) const { AssetLoadingManager assetLoadingManager(m_asset_loaders_by_type, context); diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.h b/src/ObjLoading/Game/T6/ObjLoaderT6.h index 3e9aa741..2b540f0a 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.h +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.h @@ -22,6 +22,8 @@ namespace T6 void LoadReferencedContainersForZone(ISearchPath& searchPath, Zone& zone) const override; void UnloadContainersOfZone(Zone& zone) const override; + void ConfigureCreatorCollection(AssetCreatorCollection& collection) const override; + bool LoadAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const override; void FinalizeAssetsForZone(AssetLoadingContext& context) const override; diff --git a/src/ObjLoading/IObjLoader.h b/src/ObjLoading/IObjLoader.h index 9302b943..59aa1a46 100644 --- a/src/ObjLoading/IObjLoader.h +++ b/src/ObjLoading/IObjLoader.h @@ -1,5 +1,6 @@ #pragma once +#include "Asset/AssetCreatorCollection.h" #include "AssetLoading/AssetLoadingContext.h" #include "SearchPath/ISearchPath.h" #include "Zone/Zone.h" @@ -27,6 +28,8 @@ public: */ virtual void UnloadContainersOfZone(Zone& zone) const = 0; + virtual void ConfigureCreatorCollection(AssetCreatorCollection& collection) const = 0; + virtual bool LoadAssetForZone(AssetLoadingContext& context, asset_type_t assetType, const std::string& assetName) const = 0; virtual void FinalizeAssetsForZone(AssetLoadingContext& context) const = 0;