diff --git a/src/Linker/Game/IW3/ZoneCreatorIW3.cpp b/src/Linker/Game/IW3/ZoneCreatorIW3.cpp index 23d230c2..1bdd19ff 100644 --- a/src/Linker/Game/IW3/ZoneCreatorIW3.cpp +++ b/src/Linker/Game/IW3/ZoneCreatorIW3.cpp @@ -22,7 +22,7 @@ void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name) m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType)); } -std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) +std::vector ZoneCreator::CreateGdtList(const ZoneCreationContext& context) { std::vector gdtList; gdtList.reserve(context.m_gdt_files.size()); @@ -32,9 +32,9 @@ std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) return gdtList; } -bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const +bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const { - for (const auto& ignoreEntry : context.m_ignored_assets) + for (const auto& ignoreEntry : context.m_ignored_assets.m_entries) { const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type); if (foundAssetTypeEntry == m_asset_types_by_name.end()) @@ -72,7 +72,7 @@ std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& if (!assetEntry.m_is_reference) continue; - context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); + context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); } const auto assetLoadingContext = std::make_unique(zone.get(), context.m_asset_search_path, CreateGdtList(context)); diff --git a/src/Linker/Game/IW3/ZoneCreatorIW3.h b/src/Linker/Game/IW3/ZoneCreatorIW3.h index 37c77262..b1ae2b3d 100644 --- a/src/Linker/Game/IW3/ZoneCreatorIW3.h +++ b/src/Linker/Game/IW3/ZoneCreatorIW3.h @@ -12,8 +12,8 @@ namespace IW3 std::unordered_map m_asset_types_by_name; void AddAssetTypeName(asset_type_t assetType, std::string name); - static std::vector CreateGdtList(ZoneCreationContext& context); - bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; + static std::vector CreateGdtList(const ZoneCreationContext& context); + bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; void CreateZoneAssetPools(Zone* zone) const; public: diff --git a/src/Linker/Game/IW4/ZoneCreatorIW4.cpp b/src/Linker/Game/IW4/ZoneCreatorIW4.cpp index 3f175168..5030fbaa 100644 --- a/src/Linker/Game/IW4/ZoneCreatorIW4.cpp +++ b/src/Linker/Game/IW4/ZoneCreatorIW4.cpp @@ -21,7 +21,7 @@ void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name) m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType)); } -std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) +std::vector ZoneCreator::CreateGdtList(const ZoneCreationContext& context) { std::vector gdtList; gdtList.reserve(context.m_gdt_files.size()); @@ -31,9 +31,9 @@ std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) return gdtList; } -bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const +bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const { - for (const auto& ignoreEntry : context.m_ignored_assets) + for (const auto& ignoreEntry : context.m_ignored_assets.m_entries) { const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type); if (foundAssetTypeEntry == m_asset_types_by_name.end()) @@ -71,7 +71,7 @@ std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& if (!assetEntry.m_is_reference) continue; - context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); + context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); } const auto assetLoadingContext = std::make_unique(zone.get(), context.m_asset_search_path, CreateGdtList(context)); diff --git a/src/Linker/Game/IW4/ZoneCreatorIW4.h b/src/Linker/Game/IW4/ZoneCreatorIW4.h index 2906af3d..ef0cbc54 100644 --- a/src/Linker/Game/IW4/ZoneCreatorIW4.h +++ b/src/Linker/Game/IW4/ZoneCreatorIW4.h @@ -12,8 +12,8 @@ namespace IW4 std::unordered_map m_asset_types_by_name; void AddAssetTypeName(asset_type_t assetType, std::string name); - static std::vector CreateGdtList(ZoneCreationContext& context); - bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; + static std::vector CreateGdtList(const ZoneCreationContext& context); + bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; void CreateZoneAssetPools(Zone* zone) const; public: diff --git a/src/Linker/Game/IW5/ZoneCreatorIW5.cpp b/src/Linker/Game/IW5/ZoneCreatorIW5.cpp index 9a1b1ac2..51943da4 100644 --- a/src/Linker/Game/IW5/ZoneCreatorIW5.cpp +++ b/src/Linker/Game/IW5/ZoneCreatorIW5.cpp @@ -21,7 +21,7 @@ void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name) m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType)); } -std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) +std::vector ZoneCreator::CreateGdtList(const ZoneCreationContext& context) { std::vector gdtList; gdtList.reserve(context.m_gdt_files.size()); @@ -31,9 +31,9 @@ std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) return gdtList; } -bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const +bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const { - for (const auto& ignoreEntry : context.m_ignored_assets) + for (const auto& ignoreEntry : context.m_ignored_assets.m_entries) { const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type); if (foundAssetTypeEntry == m_asset_types_by_name.end()) @@ -71,7 +71,7 @@ std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& if (!assetEntry.m_is_reference) continue; - context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); + context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); } const auto assetLoadingContext = std::make_unique(zone.get(), context.m_asset_search_path, CreateGdtList(context)); diff --git a/src/Linker/Game/IW5/ZoneCreatorIW5.h b/src/Linker/Game/IW5/ZoneCreatorIW5.h index 7584ebfc..61f8475d 100644 --- a/src/Linker/Game/IW5/ZoneCreatorIW5.h +++ b/src/Linker/Game/IW5/ZoneCreatorIW5.h @@ -12,8 +12,8 @@ namespace IW5 std::unordered_map m_asset_types_by_name; void AddAssetTypeName(asset_type_t assetType, std::string name); - static std::vector CreateGdtList(ZoneCreationContext& context); - bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; + static std::vector CreateGdtList(const ZoneCreationContext& context); + bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; void CreateZoneAssetPools(Zone* zone) const; public: diff --git a/src/Linker/Game/T5/ZoneCreatorT5.cpp b/src/Linker/Game/T5/ZoneCreatorT5.cpp index 7bd31478..117a64c7 100644 --- a/src/Linker/Game/T5/ZoneCreatorT5.cpp +++ b/src/Linker/Game/T5/ZoneCreatorT5.cpp @@ -32,9 +32,9 @@ std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) return gdtList; } -bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const +bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const { - for (const auto& ignoreEntry : context.m_ignored_assets) + for (const auto& ignoreEntry : context.m_ignored_assets.m_entries) { const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type); if (foundAssetTypeEntry == m_asset_types_by_name.end()) @@ -72,7 +72,7 @@ std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& if (!assetEntry.m_is_reference) continue; - context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); + context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); } const auto assetLoadingContext = std::make_unique(zone.get(), context.m_asset_search_path, CreateGdtList(context)); diff --git a/src/Linker/Game/T5/ZoneCreatorT5.h b/src/Linker/Game/T5/ZoneCreatorT5.h index 0c676019..986ab855 100644 --- a/src/Linker/Game/T5/ZoneCreatorT5.h +++ b/src/Linker/Game/T5/ZoneCreatorT5.h @@ -13,7 +13,7 @@ namespace T5 void AddAssetTypeName(asset_type_t assetType, std::string name); static std::vector CreateGdtList(ZoneCreationContext& context); - bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; + bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; void CreateZoneAssetPools(Zone* zone) const; public: diff --git a/src/Linker/Game/T6/ZoneCreatorT6.cpp b/src/Linker/Game/T6/ZoneCreatorT6.cpp index 90f5f14d..cdd923b6 100644 --- a/src/Linker/Game/T6/ZoneCreatorT6.cpp +++ b/src/Linker/Game/T6/ZoneCreatorT6.cpp @@ -23,7 +23,7 @@ void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name) m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType)); } -std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) +std::vector ZoneCreator::CreateGdtList(const ZoneCreationContext& context) { std::vector gdtList; gdtList.reserve(context.m_gdt_files.size()); @@ -33,9 +33,9 @@ std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) return gdtList; } -bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const +bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const { - for (const auto& ignoreEntry : context.m_ignored_assets) + for (const auto& ignoreEntry : context.m_ignored_assets.m_entries) { const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type); if (foundAssetTypeEntry == m_asset_types_by_name.end()) @@ -58,7 +58,7 @@ void ZoneCreator::CreateZoneAssetPools(Zone* zone) const zone->m_pools->InitPoolDynamic(assetType); } -void ZoneCreator::HandleMetadata(Zone* zone, ZoneCreationContext& context) const +void ZoneCreator::HandleMetadata(Zone* zone, const ZoneCreationContext& context) const { std::vector kvpList; @@ -126,7 +126,7 @@ std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& if (!assetEntry.m_is_reference) continue; - context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); + context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); } const auto assetLoadingContext = std::make_unique(zone.get(), context.m_asset_search_path, CreateGdtList(context)); diff --git a/src/Linker/Game/T6/ZoneCreatorT6.h b/src/Linker/Game/T6/ZoneCreatorT6.h index ff0bcc7d..8e04d448 100644 --- a/src/Linker/Game/T6/ZoneCreatorT6.h +++ b/src/Linker/Game/T6/ZoneCreatorT6.h @@ -12,10 +12,10 @@ namespace T6 std::unordered_map m_asset_types_by_name; void AddAssetTypeName(asset_type_t assetType, std::string name); - static std::vector CreateGdtList(ZoneCreationContext& context); - bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; + static std::vector CreateGdtList(const ZoneCreationContext& context); + bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; void CreateZoneAssetPools(Zone* zone) const; - void HandleMetadata(Zone* zone, ZoneCreationContext& context) const; + void HandleMetadata(Zone* zone, const ZoneCreationContext& context) const; public: ZoneCreator(); diff --git a/src/Linker/Linker.cpp b/src/Linker/Linker.cpp index 9ddc255e..738173a3 100644 --- a/src/Linker/Linker.cpp +++ b/src/Linker/Linker.cpp @@ -12,7 +12,6 @@ #include "ObjWriting.h" #include "ObjLoading.h" #include "SearchPath/SearchPaths.h" -#include "SearchPath/SearchPathFilesystem.h" #include "ObjContainer/IWD/IWD.h" #include "LinkerArgs.h" #include "LinkerSearchPaths.h" @@ -115,6 +114,58 @@ class LinkerImpl final : public Linker return true; } + bool ReadAssetList(const std::string& zoneName, AssetList& assetList, ISearchPath* sourceSearchPath) const + { + { + const auto assetListFileName = "assetlist/" + zoneName + ".csv"; + const auto assetListStream = sourceSearchPath->Open(assetListFileName); + + if (assetListStream.IsOpen()) + { + const AssetListInputStream stream(*assetListStream.m_stream); + AssetListEntry entry; + + while (stream.NextEntry(entry)) + { + assetList.m_entries.emplace_back(std::move(entry)); + } + return true; + } + } + + { + const auto zoneDefinition = ReadZoneDefinition(zoneName, sourceSearchPath); + + if (zoneDefinition) + { + for (const auto& entry : zoneDefinition->m_assets) + { + assetList.m_entries.emplace_back(entry.m_asset_type, entry.m_asset_name); + } + return true; + } + } + + return false; + } + + bool IncludeAssetLists(ZoneDefinition& zoneDefinition, ISearchPath* sourceSearchPath) const + { + for (const auto& assetListName : zoneDefinition.m_asset_lists) + { + AssetList assetList; + if (!ReadAssetList(assetListName, assetList, sourceSearchPath)) + { + std::cerr << "Failed to read asset list \"" << assetListName << "\"\n"; + return false; + } + + zoneDefinition.Include(assetList); + } + + return true; + } + static bool GetNameFromZoneDefinition(std::string& name, const std::string& projectName, const ZoneDefinition& zoneDefinition) { auto firstNameEntry = true; @@ -170,44 +221,12 @@ class LinkerImpl final : public Linker if (!IncludeAdditionalZoneDefinitions(projectName, *zoneDefinition, sourceSearchPath)) return nullptr; + if (!IncludeAssetLists(*zoneDefinition, sourceSearchPath)) + return nullptr; + return zoneDefinition; } - bool ReadAssetList(const std::string& zoneName, std::vector& assetList, ISearchPath* sourceSearchPath) const - { - { - const auto assetListFileName = "assetlist/" + zoneName + ".csv"; - const auto assetListStream = sourceSearchPath->Open(assetListFileName); - - if (assetListStream.IsOpen()) - { - const AssetListInputStream stream(*assetListStream.m_stream); - AssetListEntry entry; - - while (stream.NextEntry(entry)) - { - assetList.emplace_back(std::move(entry)); - } - return true; - } - } - - { - const auto zoneDefinition = ReadZoneDefinition(zoneName, sourceSearchPath); - - if (zoneDefinition) - { - for (const auto& entry : zoneDefinition->m_assets) - { - assetList.emplace_back(entry.m_asset_type, entry.m_asset_name); - } - return true; - } - } - - return false; - } - bool ProcessZoneDefinitionIgnores(const std::string& projectName, ZoneCreationContext& context, ISearchPath* sourceSearchPath) const { if (context.m_definition->m_ignores.empty()) diff --git a/src/Linker/ZoneCreation/ZoneCreationContext.h b/src/Linker/ZoneCreation/ZoneCreationContext.h index 2db20e1d..a1c7800c 100644 --- a/src/Linker/ZoneCreation/ZoneCreationContext.h +++ b/src/Linker/ZoneCreation/ZoneCreationContext.h @@ -2,7 +2,6 @@ #include #include #include -#include #include "SearchPath/ISearchPath.h" #include "Obj/Gdt/Gdt.h" @@ -16,7 +15,7 @@ public: ISearchPath* m_asset_search_path; ZoneDefinition* m_definition; std::vector> m_gdt_files; - std::vector m_ignored_assets; + AssetList m_ignored_assets; ZoneCreationContext(); ZoneCreationContext(ISearchPath* assetSearchPath, ZoneDefinition* definition); diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionAssetList.cpp b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionAssetList.cpp new file mode 100644 index 00000000..39a35625 --- /dev/null +++ b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionAssetList.cpp @@ -0,0 +1,19 @@ +#include "SequenceZoneDefinitionAssetList.h" + +#include "Parsing/ZoneDefinition/Matcher/ZoneDefinitionMatcherFactory.h" + +SequenceZoneDefinitionAssetList::SequenceZoneDefinitionAssetList() +{ + const ZoneDefinitionMatcherFactory create(this); + + AddMatchers({ + create.Keyword("assetlist"), + create.Char(','), + create.Field().Capture(CAPTURE_ASSET_LIST_NAME) + }); +} + +void SequenceZoneDefinitionAssetList::ProcessMatch(ZoneDefinition* state, SequenceResult& result) const +{ + state->m_asset_lists.emplace_back(result.NextCapture(CAPTURE_ASSET_LIST_NAME).FieldValue()); +} diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionAssetList.h b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionAssetList.h new file mode 100644 index 00000000..f9a336e4 --- /dev/null +++ b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionAssetList.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Parsing/ZoneDefinition/ZoneDefinitionParser.h" + +class SequenceZoneDefinitionAssetList final : public ZoneDefinitionParser::sequence_t +{ + static constexpr auto CAPTURE_ASSET_LIST_NAME = 1; + +protected: + void ProcessMatch(ZoneDefinition* state, SequenceResult& result) const override; + +public: + SequenceZoneDefinitionAssetList(); +}; diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp index ed52f58f..a6ae9552 100644 --- a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp +++ b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp @@ -1,5 +1,6 @@ #include "ZoneDefinitionParser.h" +#include "Sequence/SequenceZoneDefinitionAssetList.h" #include "Sequence/SequenceZoneDefinitionEntry.h" #include "Sequence/SequenceZoneDefinitionIgnore.h" #include "Sequence/SequenceZoneDefinitionInclude.h" @@ -16,6 +17,7 @@ const std::vector::seq new SequenceZoneDefinitionMetaData(), new SequenceZoneDefinitionInclude(), new SequenceZoneDefinitionIgnore(), + new SequenceZoneDefinitionAssetList(), new SequenceZoneDefinitionEntry() }); diff --git a/src/ZoneCommon/Zone/AssetList/AssetList.h b/src/ZoneCommon/Zone/AssetList/AssetList.h index 0bd7c0f3..1f02b329 100644 --- a/src/ZoneCommon/Zone/AssetList/AssetList.h +++ b/src/ZoneCommon/Zone/AssetList/AssetList.h @@ -1,5 +1,6 @@ #pragma once #include +#include class AssetListEntry { @@ -10,3 +11,9 @@ public: AssetListEntry(); AssetListEntry(std::string type, std::string name); }; + +class AssetList +{ +public: + std::vector m_entries; +}; \ No newline at end of file diff --git a/src/ZoneCommon/Zone/Definition/ZoneDefinition.cpp b/src/ZoneCommon/Zone/Definition/ZoneDefinition.cpp index 1c3ed7e2..0c710d47 100644 --- a/src/ZoneCommon/Zone/Definition/ZoneDefinition.cpp +++ b/src/ZoneCommon/Zone/Definition/ZoneDefinition.cpp @@ -29,7 +29,15 @@ void ZoneDefinition::AddMetaData(std::string key, std::string value) m_metadata_lookup.emplace(std::make_pair(metaDataPtr->m_key, metaDataPtr)); } -void ZoneDefinition::Include(ZoneDefinition& definitionToInclude) +void ZoneDefinition::Include(const AssetList& assetListToInclude) +{ + for (const auto& entry : assetListToInclude.m_entries) + { + m_assets.emplace_back(entry.m_type, entry.m_name, false); + } +} + +void ZoneDefinition::Include(const ZoneDefinition& definitionToInclude) { for (const auto& metaData : definitionToInclude.m_metadata) { diff --git a/src/ZoneCommon/Zone/Definition/ZoneDefinition.h b/src/ZoneCommon/Zone/Definition/ZoneDefinition.h index 2a093f8d..4ec8a915 100644 --- a/src/ZoneCommon/Zone/Definition/ZoneDefinition.h +++ b/src/ZoneCommon/Zone/Definition/ZoneDefinition.h @@ -5,6 +5,8 @@ #include #include +#include "Zone/AssetList/AssetList.h" + class ZoneDefinitionEntry { public: @@ -33,9 +35,11 @@ public: std::vector> m_metadata; std::unordered_multimap m_metadata_lookup; std::vector m_includes; + std::vector m_asset_lists; std::vector m_ignores; std::vector m_assets; void AddMetaData(std::string key, std::string value); - void Include(ZoneDefinition& definitionToInclude); + void Include(const AssetList& assetListToInclude); + void Include(const ZoneDefinition& definitionToInclude); }; \ No newline at end of file