MissingDependencyScanner.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/std/containers/set.h>
  10. #include <AzCore/std/containers/unordered_map.h>
  11. #include <AzCore/std/string/regex.h>
  12. #include <AzCore/std/string/string.h>
  13. #include <AzCore/std/smart_ptr/shared_ptr.h>
  14. #include <AzToolsFramework/AssetDatabase/AssetDatabaseConnection.h>
  15. #include <AzToolsFramework/Asset/AssetUtils.h>
  16. #include <native/utilities/ApplicationManagerAPI.h>
  17. namespace AZ
  18. {
  19. namespace IO
  20. {
  21. class GenericStream;
  22. }
  23. }
  24. namespace AssetProcessor
  25. {
  26. class AssetDatabaseConnection;
  27. class LineByLineDependencyScanner;
  28. class MissingDependency;
  29. class PotentialDependencies;
  30. class SpecializedDependencyScanner;
  31. typedef AZStd::set<MissingDependency> MissingDependencies;
  32. enum class ScannerMatchType
  33. {
  34. // The scanner to run only matches based on the file extension, such as a "json" scanner will only
  35. // scan files with the .json extension.
  36. ExtensionOnlyFirstMatch,
  37. // The scanners open each file and inspect the contents to see if they look like the format.
  38. // The first scanner found that matches the file will be used.
  39. // Example: If a file named "Medium.difficulty" is in XML format, the XML scanner will catch this and scan it.
  40. FileContentsFirstMatch,
  41. // All scanners that can scan the given file are used to scan it. Time consuming but thorough.
  42. Deep
  43. };
  44. class MissingDependencyScannerRequests
  45. : public AZ::EBusTraits
  46. {
  47. public:
  48. //////////////////////////////////////////////////////////////////////////
  49. // Bus configuration
  50. static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
  51. static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
  52. using MutexType = AZStd::mutex;
  53. /**
  54. * Scans the given file for a missing dependency. Note that the database connection is
  55. * not the AzToolsFramework version, it is the AssetProcessor version. This command needs
  56. * write access to the database.
  57. */
  58. using scanFileCallback = AZStd::function<void(AZStd::string relativeDependencyFilePath)>;
  59. virtual void ScanFile(
  60. const AZStd::string& fullPath,
  61. int maxScanIteration,
  62. AZ::s64 productPK,
  63. const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencies,
  64. AZStd::shared_ptr<AssetDatabaseConnection> databaseConnection,
  65. bool queueDbCommandsOnMainThread,
  66. scanFileCallback callback) = 0;
  67. };
  68. using MissingDependencyScannerRequestBus = AZ::EBus<MissingDependencyScannerRequests>;
  69. class MissingDependencyScanner
  70. : public MissingDependencyScannerRequestBus::Handler
  71. , AssetProcessor::ApplicationManagerNotifications::Bus::Handler
  72. {
  73. public:
  74. MissingDependencyScanner();
  75. ~MissingDependencyScanner() override;
  76. // ApplicationManagerNotifications::Bus::Handler
  77. void ApplicationShutdownRequested() override;
  78. //! Scans the file at the fullPath for anything that looks like a missing dependency.
  79. //! Reporting is handled internally, no results are returned.
  80. //! Anything that matches a result in the given dependency list will not be reported as a missing dependency.
  81. //! The databaseConnection is used to query the database to transform relative paths into source or
  82. //! product assets that match those paths, as well as looking up products for UUIDs found in files.
  83. //! The matchtype is used to determine how to scan the given file, see the ScannerMatchType enum for more information.
  84. //! A specific scanner can be forced to be used, this will supercede the match type.
  85. void ScanFile(
  86. const AZStd::string& fullPath,
  87. int maxScanIteration,
  88. AZ::s64 productPK,
  89. const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencies,
  90. AZStd::shared_ptr<AssetDatabaseConnection> databaseConnection,
  91. bool queueDbCommandsOnMainThread,
  92. scanFileCallback callback) override;
  93. void ScanFile(const AZStd::string& fullPath,
  94. int maxScanIteration,
  95. AZStd::shared_ptr<AssetDatabaseConnection> databaseConnection,
  96. const AZStd::string& dependencyTokenName,
  97. bool queueDbCommandsOnMainThread,
  98. scanFileCallback callback);
  99. void ScanFile(
  100. const AZStd::string& fullPath,
  101. int maxScanIteration,
  102. AZ::s64 productPK,
  103. const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencies,
  104. AZStd::shared_ptr<AssetDatabaseConnection> databaseConnection,
  105. AZStd::string dependencyTokenName,
  106. ScannerMatchType matchType,
  107. AZ::Crc32* forceScanner,
  108. bool queueDbCommandsOnMainThread,
  109. scanFileCallback callback);
  110. static const int DefaultMaxScanIteration;
  111. void RegisterSpecializedScanner(AZStd::shared_ptr<SpecializedDependencyScanner> scanner);
  112. bool PopulateRulesForScanFolder(const AZStd::string& scanFolderPath, const AZStd::vector<AzFramework::GemInfo>& gemInfoList, AZStd::string& dependencyTokenName);
  113. protected:
  114. bool RunScan(
  115. const AZStd::string& fullPath,
  116. int maxScanIteration,
  117. AZ::IO::GenericStream& fileStream,
  118. PotentialDependencies& potentialDependencies,
  119. ScannerMatchType matchType,
  120. AZ::Crc32* forceScanner);
  121. void PopulateMissingDependencies(
  122. AZ::s64 productPK,
  123. AZStd::shared_ptr<AssetDatabaseConnection> databaseConnection,
  124. const AzToolsFramework::AssetDatabase::ProductDependencyDatabaseEntryContainer& dependencies,
  125. MissingDependencies& missingDependencies,
  126. const PotentialDependencies& potentialDependencies);
  127. void ReportMissingDependencies(
  128. AZ::s64 productPK,
  129. AZStd::shared_ptr<AssetDatabaseConnection> databaseConnection,
  130. const AZStd::string& dependencyTokenName,
  131. const MissingDependencies& missingDependencies,
  132. scanFileCallback callback);
  133. void SetDependencyScanResultStatus(
  134. AZStd::string status,
  135. AZ::s64 productPK,
  136. const AZStd::string& analysisFingerprint,
  137. AZStd::shared_ptr<AssetDatabaseConnection> databaseConnection,
  138. bool queueDbCommandsOnMainThread,
  139. scanFileCallback callback);
  140. typedef AZStd::unordered_map<AZ::Crc32, AZStd::shared_ptr<SpecializedDependencyScanner>> DependencyScannerMap;
  141. DependencyScannerMap m_specializedScanners;
  142. AZStd::shared_ptr<LineByLineDependencyScanner> m_defaultScanner;
  143. AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> m_dependenciesRulesMap;
  144. AZStd::atomic_bool m_shutdownRequested = false;
  145. };
  146. }