From 792509d11d3928b3b82c8648ec9df93ae27ca7b0 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 11 Mar 2021 14:04:53 +0100 Subject: [PATCH] Read assetlists for ignoring assets --- src/Linker/Linker.cpp | 178 ++++++++++++++++-- src/ZoneCommon/Zone/AssetList/AssetList.cpp | 10 + src/ZoneCommon/Zone/AssetList/AssetList.h | 12 ++ .../Zone/AssetList/AssetListStream.cpp | 37 ++++ .../Zone/AssetList/AssetListStream.h | 25 +++ .../Zone/Definition/ZoneDefinition.cpp | 21 +++ .../Zone/Definition/ZoneDefinition.h | 2 + 7 files changed, 269 insertions(+), 16 deletions(-) create mode 100644 src/ZoneCommon/Zone/AssetList/AssetList.cpp create mode 100644 src/ZoneCommon/Zone/AssetList/AssetList.h create mode 100644 src/ZoneCommon/Zone/AssetList/AssetListStream.cpp create mode 100644 src/ZoneCommon/Zone/AssetList/AssetListStream.h diff --git a/src/Linker/Linker.cpp b/src/Linker/Linker.cpp index 48b93e2b..ab726b69 100644 --- a/src/Linker/Linker.cpp +++ b/src/Linker/Linker.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "Utils/ClassUtils.h" #include "Utils/Arguments/ArgumentParser.h" @@ -16,6 +17,8 @@ #include "LinkerArgs.h" #include "Utils/ObjFileStream.h" +#include "Zone/AssetList/AssetList.h" +#include "Zone/AssetList/AssetListStream.h" #include "Zone/Definition/ZoneDefinitionStream.h" namespace fs = std::filesystem; @@ -203,6 +206,160 @@ class Linker::Impl return true; } + + bool IncludeAdditionalZoneDefinitions(const std::string& initialFileName, ZoneDefinition& zoneDefinition, ISearchPath* sourceSearchPath) const + { + std::set sourceNames; + sourceNames.emplace(initialFileName); + + std::deque toIncludeQueue; + for (const auto& include : zoneDefinition.m_includes) + toIncludeQueue.emplace_back(include); + + while(!toIncludeQueue.empty()) + { + const auto& source = toIncludeQueue.front(); + + if(sourceNames.find(source) == sourceNames.end()) + { + sourceNames.emplace(source); + + std::unique_ptr includeDefinition; + { + const auto definitionFileName = source + ".zone"; + const auto definitionStream = sourceSearchPath->Open(definitionFileName); + if (!definitionStream) + { + std::cout << "Could not find zone definition file for zone \"" << source << "\"." << std::endl; + return false; + } + + ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream, definitionFileName, m_args.m_verbose); + includeDefinition = zoneDefinitionInputStream.ReadDefinition(); + } + + if (!includeDefinition) + { + std::cout << "Failed to read zone definition file for zone \"" << source << "\"." << std::endl; + return false; + } + + for (const auto& include : includeDefinition->m_includes) + toIncludeQueue.emplace_back(include); + + zoneDefinition.Include(*includeDefinition); + } + + toIncludeQueue.pop_front(); + } + + return true; + } + + std::unique_ptr ReadZoneDefinition(const std::string& zoneName, ISearchPath* sourceSearchPath) const + { + std::unique_ptr zoneDefinition; + { + const auto definitionFileName = zoneName + ".zone"; + const auto definitionStream = sourceSearchPath->Open(definitionFileName); + if (!definitionStream) + { + std::cout << "Could not find zone definition file for zone \"" << zoneName << "\"." << std::endl; + return nullptr; + } + + ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream, definitionFileName, m_args.m_verbose); + zoneDefinition = zoneDefinitionInputStream.ReadDefinition(); + } + + if (!zoneDefinition) + { + std::cout << "Failed to read zone definition file for zone \"" << zoneName << "\"." << std::endl; + return nullptr; + } + + if (!IncludeAdditionalZoneDefinitions(zoneName, *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) + { + const AssetListInputStream stream(*assetListStream); + 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& zoneName, ZoneDefinition& zoneDefinition, ISearchPath* sourceSearchPath) const + { + if (zoneDefinition.m_ignores.empty()) + return true; + + std::map> zoneDefinitionAssetsByName; + for (auto& entry : zoneDefinition.m_assets) + { + zoneDefinitionAssetsByName.try_emplace(entry.m_asset_name, entry); + } + + for(const auto& ignore : zoneDefinition.m_ignores) + { + if(ignore == zoneName) + continue; + + std::vector assetList; + if(!ReadAssetList(ignore, assetList, sourceSearchPath)) + { + std::cout << "Failed to read asset listing for ignoring assets of zone \"" << ignore << "\"." << std::endl; + return false; + } + + for(const auto& assetListEntry : assetList) + { + const auto foundAsset = zoneDefinitionAssetsByName.find(assetListEntry.m_name); + + if(foundAsset != zoneDefinitionAssetsByName.end() + && foundAsset->second.get().m_asset_type == assetListEntry.m_type) + { + foundAsset->second.get().m_is_reference = true; + } + } + } + return true; + } + + std::unique_ptr CreateZoneForDefinition(const std::string& zoneName, ZoneDefinition& zoneDefinition) + { + return nullptr; + } bool BuildZone(const std::string& zoneName) { @@ -210,26 +367,15 @@ class Linker::Impl auto gdtSearchPaths = GetGdtSearchPathsForZone(zoneName); auto sourceSearchPaths = GetSourceSearchPathsForZone(zoneName); - std::unique_ptr zoneDefinition; + const auto zoneDefinition = ReadZoneDefinition(zoneName, &sourceSearchPaths); + if (!zoneDefinition + || !ProcessZoneDefinitionIgnores(zoneName, *zoneDefinition, &sourceSearchPaths)) { - const auto definitionFileName = zoneName + ".zone"; - const auto definitionStream = sourceSearchPaths.Open(definitionFileName); - if (!definitionStream) - { - std::cout << "Could not find zone definition file for zone \"" << zoneName << "\"." << std::endl; - return false; - } - - ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream, definitionFileName, m_args.m_verbose); - zoneDefinition = zoneDefinitionInputStream.ReadDefinition(); - } - - if(!zoneDefinition) - { - std::cout << "Failed to read zone definition file for zone \"" << zoneName << "\"." << std::endl; return false; } + const auto zone = CreateZoneForDefinition(zoneName, *zoneDefinition); + for(const auto& loadedSearchPath : m_loaded_zone_search_paths) { UnloadSearchPath(loadedSearchPath.get()); diff --git a/src/ZoneCommon/Zone/AssetList/AssetList.cpp b/src/ZoneCommon/Zone/AssetList/AssetList.cpp new file mode 100644 index 00000000..56bb487e --- /dev/null +++ b/src/ZoneCommon/Zone/AssetList/AssetList.cpp @@ -0,0 +1,10 @@ +#include "AssetList.h" + +AssetListEntry::AssetListEntry() += default; + +AssetListEntry::AssetListEntry(std::string type, std::string name) + : m_type(std::move(type)), + m_name(std::move(name)) +{ +} diff --git a/src/ZoneCommon/Zone/AssetList/AssetList.h b/src/ZoneCommon/Zone/AssetList/AssetList.h new file mode 100644 index 00000000..0bd7c0f3 --- /dev/null +++ b/src/ZoneCommon/Zone/AssetList/AssetList.h @@ -0,0 +1,12 @@ +#pragma once +#include + +class AssetListEntry +{ +public: + std::string m_type; + std::string m_name; + + AssetListEntry(); + AssetListEntry(std::string type, std::string name); +}; diff --git a/src/ZoneCommon/Zone/AssetList/AssetListStream.cpp b/src/ZoneCommon/Zone/AssetList/AssetListStream.cpp new file mode 100644 index 00000000..e1d84954 --- /dev/null +++ b/src/ZoneCommon/Zone/AssetList/AssetListStream.cpp @@ -0,0 +1,37 @@ +#include "AssetListStream.h" + +AssetListInputStream::AssetListInputStream(std::istream& stream) + : m_stream(stream) +{ +} + +bool AssetListInputStream::NextEntry(AssetListEntry& entry) const +{ + std::vector row; + + while(true) + { + if (!m_stream.NextRow(row)) + return false; + + if (row.empty()) + continue; + + entry.m_type = row[0]; + if (row.size() >= 2) + entry.m_name = row[1]; + return true; + } +} + +AssetListOutputStream::AssetListOutputStream(std::ostream& stream) + : m_stream(stream) +{ +} + +void AssetListOutputStream::WriteEntry(const AssetListEntry& entry) +{ + m_stream.WriteColumn(entry.m_type); + m_stream.WriteColumn(entry.m_name); + m_stream.NextRow(); +} diff --git a/src/ZoneCommon/Zone/AssetList/AssetListStream.h b/src/ZoneCommon/Zone/AssetList/AssetListStream.h new file mode 100644 index 00000000..d15807c6 --- /dev/null +++ b/src/ZoneCommon/Zone/AssetList/AssetListStream.h @@ -0,0 +1,25 @@ +#pragma once +#include + +#include "AssetList.h" +#include "Csv/CsvStream.h" + +class AssetListInputStream +{ + CsvInputStream m_stream; + +public: + explicit AssetListInputStream(std::istream& stream); + + bool NextEntry(AssetListEntry& entry) const; +}; + +class AssetListOutputStream +{ + CsvOutputStream m_stream; + +public: + explicit AssetListOutputStream(std::ostream& stream); + + void WriteEntry(const AssetListEntry& entry); +}; \ No newline at end of file diff --git a/src/ZoneCommon/Zone/Definition/ZoneDefinition.cpp b/src/ZoneCommon/Zone/Definition/ZoneDefinition.cpp index 821285e2..6954652e 100644 --- a/src/ZoneCommon/Zone/Definition/ZoneDefinition.cpp +++ b/src/ZoneCommon/Zone/Definition/ZoneDefinition.cpp @@ -11,3 +11,24 @@ ZoneDefinitionEntry::ZoneDefinitionEntry(std::string type, std::string name, boo m_is_reference(isReference) { } + +void ZoneDefinition::Include(ZoneDefinition& definitionToInclude) +{ + for(const auto& [key, value] : definitionToInclude.m_metadata) + { + if(m_metadata.find(key) == m_metadata.end()) + { + m_metadata.emplace(std::make_pair(key, value)); + } + } + + for(const auto& ignore : definitionToInclude.m_ignores) + { + m_ignores.emplace_back(ignore); + } + + for(const auto& asset : definitionToInclude.m_assets) + { + m_assets.emplace_back(asset); + } +} diff --git a/src/ZoneCommon/Zone/Definition/ZoneDefinition.h b/src/ZoneCommon/Zone/Definition/ZoneDefinition.h index 65bd3c01..61bffa09 100644 --- a/src/ZoneCommon/Zone/Definition/ZoneDefinition.h +++ b/src/ZoneCommon/Zone/Definition/ZoneDefinition.h @@ -21,4 +21,6 @@ public: std::vector m_includes; std::vector m_ignores; std::vector m_assets; + + void Include(ZoneDefinition& definitionToInclude); }; \ No newline at end of file