/* * 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 #if !defined(Q_MOC_RUN) #include #include #include #include #include #include #include #include #include "native/AssetDatabase/AssetDatabase.h" #include "native/assetprocessor.h" #include "native/utilities/AssetUtilEBusHelper.h" #include "native/utilities/PlatformConfiguration.h" #include #include #include #include #include #include #endif #include "AssetRequestHandler.h" namespace AzFramework { class AssetRegistry; namespace AssetSystem { class AssetNotificationMessage; } } namespace AssetProcessor { class AssetDatabaseConnection; class AssetCatalog : public QObject , private AssetRegistryRequestBus::Handler , private AzToolsFramework::AssetSystemRequestBus::Handler , private AzToolsFramework::ToolsAssetSystemBus::Handler , private AZ::Data::AssetCatalogRequestBus::Handler { using NetworkRequestID = AssetProcessor::NetworkRequestID; using BaseAssetProcessorMessage = AzFramework::AssetSystem::BaseAssetProcessorMessage; Q_OBJECT; public: AssetCatalog(QObject* parent, AssetProcessor::PlatformConfiguration* platformConfiguration); virtual ~AssetCatalog(); Q_SIGNALS: // outgoing message to the network void SendAssetMessage(AzFramework::AssetSystem::AssetNotificationMessage message); void AsyncAssetCatalogStatusResponse(AssetCatalogStatus status); void CatalogLoaded(); public Q_SLOTS: // incoming message from the AP void OnAssetMessage(AzFramework::AssetSystem::AssetNotificationMessage message); void OnDependencyResolved(const AZ::Data::AssetId& assetId, const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntry& entry); void OnConnect(unsigned int connectionId, QStringList platforms); void SaveRegistry_Impl(); virtual AzFramework::AssetSystem::GetUnresolvedDependencyCountsResponse HandleGetUnresolvedDependencyCountsRequest(MessageData messageData); virtual void HandleSaveAssetCatalogRequest(MessageData messageData); void BuildRegistry(); void OnSourceQueued(AZ::Uuid sourceUuid, AZStd::unordered_set legacyUuids, const SourceAssetReference& sourceAsset); void OnSourceFinished(AZ::Uuid sourceUuid, AZStd::unordered_set legacyUuids); void AsyncAssetCatalogStatusRequest(); protected: ////////////////////////////////////////////////////////////////////////// // AssetRegistryRequestBus::Handler overrides int SaveRegistry() override; void ValidatePreLoadDependency() override; ////////////////////////////////////////////////////////////////////////// void RegistrySaveComplete(int assetCatalogVersion, bool allCatalogsSaved); ////////////////////////////////////////////////////////////////////////// // AzToolsFramework::AssetSystem::AssetSystemRequestBus::Handler overrides bool GetRelativeProductPathFromFullSourceOrProductPath(const AZStd::string& fullPath, AZStd::string& relativeProductPath) override; //! Given a partial or full source file path, respond with its relative path and the watch folder it is relative to. //! The input source path does not need to exist, so this can be used for new files that haven't been saved yet. bool GenerateRelativeSourcePath( const AZStd::string& sourcePath, AZStd::string& relativePath, AZStd::string& watchFolder) override; bool GetFullSourcePathFromRelativeProductPath(const AZStd::string& relPath, AZStd::string& fullSourcePath) override; bool GetAssetInfoById(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& assetType, const AZStd::string& platformName, AZ::Data::AssetInfo& assetInfo, AZStd::string& rootFilePath) override; bool GetSourceInfoBySourcePath(const char* sourcePath, AZ::Data::AssetInfo& assetInfo, AZStd::string& watchFolder) override; bool GetSourceInfoBySourceUUID(const AZ::Uuid& sourceUuid, AZ::Data::AssetInfo& assetInfo, AZStd::string& watchFolder) override; bool GetScanFolders(AZStd::vector& scanFolders) override; bool GetAssetSafeFolders(AZStd::vector& assetSafeFolders) override; bool IsAssetPlatformEnabled(const char* platform) override; int GetPendingAssetsForPlatform(const char* platform) override; bool GetAssetsProducedBySourceUUID(const AZ::Uuid& sourceUuid, AZStd::vector& productsAssetInfo) override; bool ClearFingerprintForAsset(const AZStd::string& sourcePath) override; //////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // AssetCatalogRequestBus overrides AZStd::string GetAssetPathById(const AZ::Data::AssetId& id) override; AZ::Data::AssetId GetAssetIdByPath(const char* path, const AZ::Data::AssetType& typeToRegister, bool autoRegisterIfNotFound) override; AZ::Data::AssetInfo GetAssetInfoById(const AZ::Data::AssetId& id) override; AZ::Outcome, AZStd::string> GetDirectProductDependencies(const AZ::Data::AssetId& id) override; AZ::Outcome, AZStd::string> GetAllProductDependencies(const AZ::Data::AssetId& id) override; AZ::Outcome, AZStd::string> GetLoadBehaviorProductDependencies( const AZ::Data::AssetId& id, AZStd::unordered_set& noloadSet, AZ::Data::PreloadAssetListType& preloadAssetList) override; //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // AzToolsFramework::ToolsAssetSystemBus::Handler void RegisterSourceAssetType(const AZ::Data::AssetType& assetType, const char* assetFileFilter) override; void UnregisterSourceAssetType(const AZ::Data::AssetType& assetType) override; ////////////////////////////////////////////////////////////////////////// //! given some absolute path, please respond with its relative product path. For now, this will be a //! string like 'textures/blah.tif' (we don't care about extensions), but eventually, this will //! be an actual asset UUID. void ProcessGetRelativeProductPathFromFullSourceOrProductPathRequest(const AZStd::string& fullPath, AZStd::string& relativeProductPath); //! This function helps in determining the full product path of an relative product path. //! In the future we will be sending an asset UUID to this function to request for full path. void ProcessGetFullSourcePathFromRelativeProductPathRequest(const AZStd::string& relPath, AZStd::string& fullSourcePath); //! Gets the source file info for an Asset by checking the DB first and the APM queue second bool GetSourceFileInfoFromAssetId(const AZ::Data::AssetId &assetId, SourceAssetReference& sourceAsset); //! Gets the product AssetInfo based on a platform and assetId. If you specify a null or empty platform the current or first available will be used. AZ::Data::AssetInfo GetProductAssetInfo(const char* platformName, const AZ::Data::AssetId& id); //! GetAssetInfo that tries to figure out if the asset is a product or source so it can return info about the product or source respectively bool GetAssetInfoByIdOnly(const AZ::Data::AssetId& id, const AZStd::string& platformName, AZ::Data::AssetInfo& assetInfo, SourceAssetReference& sourceAsset); //! Checks in the currently-in-queue assets list for info on an asset (by source Id) bool GetQueuedAssetInfoById(const AZ::Uuid& guid, SourceAssetReference& sourceAsset); //! Checks in the currently-in-queue assets list for info on an asset (by source name) bool GetQueuedAssetInfoByRelativeSourceName(const SourceAssetReference& sourceAsset, AZ::Data::AssetInfo& assetInfo); //! Gets the source info for a source that is not in the DB or APM queue bool GetUncachedSourceInfoFromDatabaseNameAndWatchFolder(const SourceAssetReference& sourceAsset, AZ::Data::AssetInfo& assetInfo); bool ConnectToDatabase(); bool CheckValidatedAssets(AZ::Data::AssetId assetId, const QString& platform); //! For lookups that don't provide a specific platform, provide a default platform to use. QString GetDefaultAssetPlatform(); AZ::Outcome, AZStd::string> GetAllProductDependenciesFilter( const AZ::Data::AssetId& id, const AZStd::unordered_set& exclusionList, const AZStd::vector& wildcardPatternExclusionList) override; bool DoesAssetIdMatchWildcardPattern(const AZ::Data::AssetId& assetId, const AZStd::string& wildcardPattern) override; void AddAssetDependencies( const AZ::Data::AssetId& searchAssetId, AZStd::unordered_set& assetSet, AZStd::vector& dependencyList, const AZStd::unordered_set& exclusionList, const AZStd::vector& wildcardPatternExclusionList, AZ::Data::PreloadAssetListType& preloadAssetList); //! List of AssetTypes that should return info for the source instead of the product AZStd::unordered_set m_sourceAssetTypes; AZStd::unordered_map m_sourceAssetTypeFilters; AZStd::mutex m_sourceAssetTypesMutex; //! Used to protect access to the database connection, only one thread can use it at a time AZStd::mutex m_databaseMutex; AZStd::mutex m_sourceUUIDToSourceNameMapMutex; using SourceUUIDToSourceAssetMap = AZStd::unordered_map; using SourceAssetToSourceUuidMap = AZStd::unordered_map; SourceUUIDToSourceAssetMap m_sourceUUIDToSourceAssetMap; // map of uuids to SourceAssetReferences for assets that are currently in the processing queue SourceAssetToSourceUuidMap m_sourceAssetToSourceUUIDMap; // map of SourceAssetReferences to UUIDs for assets that are currently in the processing queue QMutex m_registriesMutex; QHash m_registries; // per platform. AssetProcessor::PlatformConfiguration* m_platformConfig; QStringList m_platforms; AZStd::unique_ptr m_db; QDir m_cacheRoot; bool m_registryBuiltOnce; bool m_catalogIsDirty = true; bool m_currentlySavingCatalog = false; bool m_currentlyValidatingPreloadDependency = false; int m_currentRegistrySaveVersion = 0; QMutex m_savingRegistryMutex; QMultiMap m_queuedSaveCatalogRequest; AZStd::vector> m_preloadAssetList; AZStd::unordered_multimap m_cachedNoPreloadDependenyAssetList; AZStd::vector m_saveBuffer; // so that we don't realloc all the time }; }