/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #pragma once #include #include #include #include #include #include #include #include namespace AZ { namespace IO { class GenericStream; } } namespace AssetProcessor { class AssetDatabaseConnection; class LineByLineDependencyScanner; class MissingDependency; class PotentialDependencies; class SpecializedDependencyScanner; typedef AZStd::set MissingDependencies; enum class ScannerMatchType { // The scanner to run only matches based on the file extension, such as a "json" scanner will only // scan files with the .json extension. ExtensionOnlyFirstMatch, // The scanners open each file and inspect the contents to see if they look like the format. // The first scanner found that matches the file will be used. // Example: If a file named "Medium.difficulty" is in XML format, the XML scanner will catch this and scan it. FileContentsFirstMatch, // All scanners that can scan the given file are used to scan it. Time consuming but thorough. Deep }; class MissingDependencyScannerRequests : public AZ::EBusTraits { public: ////////////////////////////////////////////////////////////////////////// // Bus configuration static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; using MutexType = AZStd::mutex; /** * Scans the given file for a missing dependency. Note that the database connection is * not the AzToolsFramework version, it is the AssetProcessor version. This command needs * write access to the database. */ using scanFileCallback = AZStd::function; virtual void ScanFile( const AZStd::string& fullPath, int maxScanIteration, AZ::s64 productPK, const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencies, AZStd::shared_ptr databaseConnection, bool queueDbCommandsOnMainThread, scanFileCallback callback) = 0; }; using MissingDependencyScannerRequestBus = AZ::EBus; class MissingDependencyScanner : public MissingDependencyScannerRequestBus::Handler , AssetProcessor::ApplicationManagerNotifications::Bus::Handler { public: MissingDependencyScanner(); ~MissingDependencyScanner() override; // ApplicationManagerNotifications::Bus::Handler void ApplicationShutdownRequested() override; //! Scans the file at the fullPath for anything that looks like a missing dependency. //! Reporting is handled internally, no results are returned. //! Anything that matches a result in the given dependency list will not be reported as a missing dependency. //! The databaseConnection is used to query the database to transform relative paths into source or //! product assets that match those paths, as well as looking up products for UUIDs found in files. //! The matchtype is used to determine how to scan the given file, see the ScannerMatchType enum for more information. //! A specific scanner can be forced to be used, this will supercede the match type. void ScanFile( const AZStd::string& fullPath, int maxScanIteration, AZ::s64 productPK, const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencies, AZStd::shared_ptr databaseConnection, bool queueDbCommandsOnMainThread, scanFileCallback callback) override; void ScanFile(const AZStd::string& fullPath, int maxScanIteration, AZStd::shared_ptr databaseConnection, const AZStd::string& dependencyTokenName, bool queueDbCommandsOnMainThread, scanFileCallback callback); void ScanFile( const AZStd::string& fullPath, int maxScanIteration, AZ::s64 productPK, const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencies, AZStd::shared_ptr databaseConnection, AZStd::string dependencyTokenName, ScannerMatchType matchType, AZ::Crc32* forceScanner, bool queueDbCommandsOnMainThread, scanFileCallback callback); static const int DefaultMaxScanIteration; void RegisterSpecializedScanner(AZStd::shared_ptr scanner); bool PopulateRulesForScanFolder(const AZStd::string& scanFolderPath, const AZStd::vector& gemInfoList, AZStd::string& dependencyTokenName); protected: bool RunScan( const AZStd::string& fullPath, int maxScanIteration, AZ::IO::GenericStream& fileStream, PotentialDependencies& potentialDependencies, ScannerMatchType matchType, AZ::Crc32* forceScanner); void PopulateMissingDependencies( AZ::s64 productPK, AZStd::shared_ptr databaseConnection, const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencies, MissingDependencies& missingDependencies, const PotentialDependencies& potentialDependencies); void ReportMissingDependencies( AZ::s64 productPK, AZStd::shared_ptr databaseConnection, const AZStd::string& dependencyTokenName, const MissingDependencies& missingDependencies, scanFileCallback callback); void SetDependencyScanResultStatus( AZStd::string status, AZ::s64 productPK, const AZStd::string& analysisFingerprint, AZStd::shared_ptr databaseConnection, bool queueDbCommandsOnMainThread, scanFileCallback callback); typedef AZStd::unordered_map> DependencyScannerMap; DependencyScannerMap m_specializedScanners; AZStd::shared_ptr m_defaultScanner; AZStd::unordered_map> m_dependenciesRulesMap; AZStd::atomic_bool m_shutdownRequested = false; }; }