/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #pragma once #include #include #include #include #include #include class QString; namespace AssetProcessor { class PlatformConfiguration; class AssetDatabaseConnection; const char ExcludedDependenciesSymbol = ':'; /// Handles resolving and saving product path dependencies class PathDependencyManager { public: // The two Ids needed for a ProductDependency entry, and platform. Used for saving ProductDependencies that are pending resolution struct DependencyProductIdInfo { AZ::s64 m_productId{}; AZ::s64 m_productDependencyId{}; AZStd::string m_platform; }; using DependencyProductMap = AZStd::unordered_map>; PathDependencyManager(AZStd::shared_ptr stateData, PlatformConfiguration* platformConfig); void QueueSourceForDependencyResolution(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry); void ProcessQueuedDependencyResolves(); struct SearchEntry { SearchEntry(AZStd::string path, bool isSourcePath, const AzToolsFramework::AssetDatabase::SourceDatabaseEntry* sourceEntry, const AzToolsFramework::AssetDatabase::ProductDatabaseEntry* productEntry) : m_path(std::move(path)), m_isSourcePath(isSourcePath), m_sourceEntry(sourceEntry), m_productEntry(productEntry) {} AZStd::string m_path; bool m_isSourcePath; const AzToolsFramework::AssetDatabase::SourceDatabaseEntry* m_sourceEntry = nullptr; const AzToolsFramework::AssetDatabase::ProductDatabaseEntry* m_productEntry = nullptr; }; /// This function is responsible for looking up existing, unresolved dependencies that the current asset satisfies. /// These can be dependencies on either the source asset or one of the product assets void RetryDeferredDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry, const AZStd::unordered_map>& matches, const AZStd::vector& products); /// This function is responsible for taking the path dependencies output by the current asset and trying to resolve them to AssetIds /// This does not look for dependencies that the current asset satisfies. void ResolveDependencies(AssetBuilderSDK::ProductPathDependencySet& pathDeps, AZStd::vector& resolvedDeps, const AZStd::string& platform, const AZStd::string& productName); /// Saves a product's unresolved dependencies to the database void SaveUnresolvedDependenciesToDatabase(AssetBuilderSDK::ProductPathDependencySet& unresolvedDependencies, const AzToolsFramework::AssetDatabase::ProductDatabaseEntry& productEntry, const AZStd::string& platform); using DependencyResolvedCallback = AZStd::function; void SetDependencyResolvedCallback(const DependencyResolvedCallback& callback); private: struct MapSet { DependencyProductMap m_sourcePathDependencyIds; DependencyProductMap m_productPathDependencyIds; DependencyProductMap m_wildcardSourcePathDependencyIds; DependencyProductMap m_wildcardProductPathDependencyIds; }; MapSet PopulateExclusionMaps() const; void NotifyResolvedDependencies(const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencyContainer) const; void SaveResolvedDependencies(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry, const MapSet& exclusionMaps, const AZStd::string& sourceNameWithScanFolder, const AZStd::unordered_set& dependencyEntries, AZStd::string_view matchedPath, bool isSourceDependency, const AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer& matchedProducts, AZStd::vector& dependencyContainer) const; static DependencyProductMap& SelectMap(MapSet& mapSet, bool wildcard, AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry::DependencyType type); /// Returns false if a path contains wildcards, true otherwise static bool IsExactDependency(AZStd::string_view path); /// Prefixes the scanFolderId to the relativePath AZStd::string ToScanFolderPrefixedPath(int scanFolderId, const char* relativePath) const; /// Takes a path and breaks it into a database-prefixed relative path and scanFolder path /// This function can accept an absolute source path, an un-prefixed relative path, and a prefixed relative path /// The file returned will be the first one matched based on scanfolder priority bool ProcessInputPathToDatabasePathAndScanFolder(const char* dependencyPathSearch, QString& databaseName, QString& scanFolder) const; /// Gets any matched dependency exclusions /// @param sourceEntry source database entry corresponds to the newly finished product /// @param productEntry product database entry corresponds to the newly finished product /// @param excludedDependencies dependencies that should be ignored even if their file paths match any existing wildcard pattern /// @param dependencyType type of the dependencies we are handling /// @param exclusionMaps MapSet containing all the path dependency exclusions void GetMatchedExclusions(const AzToolsFramework::AssetDatabase::SourceDatabaseEntry& sourceEntry, const AzToolsFramework::AssetDatabase::ProductDatabaseEntry& productEntry, AZStd::vector>& excludedDependencies, AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry::DependencyType dependencyType, const MapSet& exclusionMaps) const; AZStd::shared_ptr m_stateData; PlatformConfiguration* m_platformConfig{}; DependencyResolvedCallback m_dependencyResolvedCallback{}; AZStd::vector m_queuedForResolve; }; } // namespace AssetProcessor