AssetUtils.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
  9. #include <AzCore/Asset/AssetManagerBus.h>
  10. #include <AzFramework/Asset/AssetSystemBus.h>
  11. namespace AZ
  12. {
  13. namespace RPI
  14. {
  15. namespace AssetUtils
  16. {
  17. void AssetUtilsInternal::ReportIssue(TraceLevel traceLevel, [[maybe_unused]] const char* message)
  18. {
  19. switch (traceLevel)
  20. {
  21. case TraceLevel::None:
  22. break;
  23. case TraceLevel::Warning:
  24. AZ_Warning("AssetUtils", false, "%s", message);
  25. break;
  26. case TraceLevel::Error:
  27. AZ_Error("AssetUtils", false, "%s", message);
  28. break;
  29. case TraceLevel::Assert:
  30. AZ_Assert(false, "%s", message);
  31. break;
  32. }
  33. }
  34. bool TryToCompileAsset(const AZStd::string& assetFilePath, TraceLevel reporting)
  35. {
  36. AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown;
  37. AzFramework::AssetSystemRequestBus::BroadcastResult(
  38. status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilePath);
  39. if ((status != AzFramework::AssetSystem::AssetStatus_Compiled) && (status != AzFramework::AssetSystem::AssetStatus_Unknown))
  40. {
  41. AssetUtilsInternal::ReportIssue(
  42. reporting,
  43. AZStd::string::format(
  44. "Could not compile asset '%s', status = %u.", assetFilePath.c_str(), static_cast<uint32_t>(status))
  45. .c_str());
  46. return false;
  47. }
  48. return true;
  49. }
  50. bool TryToCompileAsset(const AZ::Data::AssetId& assetId, TraceLevel reporting)
  51. {
  52. AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown;
  53. AzFramework::AssetSystemRequestBus::BroadcastResult(status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSyncById, assetId);
  54. if ((status != AzFramework::AssetSystem::AssetStatus_Compiled) && (status != AzFramework::AssetSystem::AssetStatus_Unknown))
  55. {
  56. AssetUtilsInternal::ReportIssue(
  57. reporting,
  58. AZStd::string::format(
  59. "TryToCompileAsset::Could not compile asset '%s', status = %u.",
  60. assetId.ToString<AZStd::string>().c_str(),
  61. static_cast<uint32_t>(status)).c_str());
  62. return false;
  63. }
  64. return true;
  65. }
  66. Data::AssetId GetAssetIdForProductPath(const char* productPath, TraceLevel reporting, Data::AssetType assetType)
  67. {
  68. // Don't create a new entry in the asset catalog for this asset if it doesn't exist.
  69. // Since we only have a product path and not an asset id, any entry we create will have an incorrect id,
  70. // incorrect size and dependency information, and will point to a file that doesn't exist. Any attempt to use
  71. // that id will fail.
  72. constexpr bool AutoGenerateId = false;
  73. Data::AssetId assetId;
  74. Data::AssetCatalogRequestBus::BroadcastResult(
  75. assetId,
  76. &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath,
  77. productPath,
  78. assetType,
  79. AutoGenerateId);
  80. if (!assetId.IsValid())
  81. {
  82. // Wait for the asset be compiled if possible. Note that if AP is not connected, this will return immmediately (0ms)
  83. // and if AP is connected, but, the asset cannot be found or is in an error state, it returns almost immediately (~0ms)
  84. // the only time it actually blocks is if the asset IS found, IS in the queue, in which case it escalates it to the very top
  85. // of the queue and processes it ASAP before returning.
  86. AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown;
  87. AzFramework::AssetSystemRequestBus::BroadcastResult(status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, productPath);
  88. if (status == AzFramework::AssetSystem::AssetStatus_Compiled)
  89. {
  90. // success, try again.
  91. Data::AssetCatalogRequestBus::BroadcastResult(assetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, productPath, assetType, AutoGenerateId);
  92. }
  93. if (!assetId.IsValid())
  94. {
  95. AZStd::string errorMessage = AZStd::string::format(
  96. "Unable to find product asset '%s'. Has the source asset finished building?", productPath);
  97. AssetUtilsInternal::ReportIssue(reporting, errorMessage.c_str());
  98. }
  99. }
  100. return assetId;
  101. }
  102. // AsyncAssetLoader //
  103. AsyncAssetLoader::AsyncAssetLoader(AssetCallback callback)
  104. : m_callback(callback)
  105. {
  106. }
  107. AsyncAssetLoader::~AsyncAssetLoader()
  108. {
  109. Data::AssetBus::Handler::BusDisconnect();
  110. SystemTickBus::Handler::BusDisconnect();
  111. }
  112. void AsyncAssetLoader::OnAssetReady(Data::Asset<Data::AssetData> asset)
  113. {
  114. Data::AssetBus::Handler::BusDisconnect();
  115. m_asset = asset;
  116. SystemTickBus::Handler::BusConnect();
  117. }
  118. void AsyncAssetLoader::OnAssetError(Data::Asset<Data::AssetData> asset)
  119. {
  120. Data::AssetBus::Handler::BusDisconnect();
  121. m_asset = asset;
  122. SystemTickBus::Handler::BusConnect();
  123. }
  124. void AsyncAssetLoader::HandleCallback(Data::Asset<Data::AssetData> asset)
  125. {
  126. if (m_callback)
  127. {
  128. m_callback(asset);
  129. }
  130. m_callback = {}; // Release the callback to avoid holding references to anything captured in the lambda.
  131. m_asset = {}; // Release the asset in case this AsyncAssetLoader hangs around longer than the asset needs to.
  132. }
  133. // SystemTickBus::Handler overrides..
  134. void AsyncAssetLoader::OnSystemTick()
  135. {
  136. SystemTickBus::Handler::BusDisconnect();
  137. HandleCallback(m_asset);
  138. }
  139. } // namespace AssetUtils
  140. } // namespace RPI
  141. } // namespace AZ