diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp index a89b364471..fa8eb3fd65 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.cpp @@ -84,8 +84,6 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils } SpawnableUtils::SortEntitiesByTransformHierarchy(*spawnable); context.GetProcessedObjects().push_back(AZStd::move(object)); - - context.RemovePrefab(prefabName); } else { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp index eb206349d0..38f58503ed 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.cpp @@ -10,6 +10,8 @@ * */ +#include + #include namespace AzToolsFramework::Prefab::PrefabConversionUtils @@ -24,37 +26,14 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return result.second; } - bool PrefabProcessorContext::RemovePrefab(AZStd::string_view prefabName) - { - if (!m_isIterating) - { - return m_prefabs.erase(prefabName) > 0; - } - else - { - m_delayedDelete.emplace_back(prefabName); - } - return false; - } - void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) { m_isIterating = true; for (auto& it : m_prefabs) { - if (AZStd::find(m_delayedDelete.begin(), m_delayedDelete.end(), it.first) == m_delayedDelete.end()) - { - callback(it.first, it.second); - } + callback(it.first, it.second); } m_isIterating = false; - - // Clear out any prefabs that have been deleted. - for (AZStd::string& deleted : m_delayedDelete) - { - m_prefabs.erase(deleted); - } - m_delayedDelete.clear(); } void PrefabProcessorContext::ListPrefabs(const AZStd::function& callback) const @@ -70,6 +49,44 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return !m_prefabs.empty(); } + bool PrefabProcessorContext::RegisterSpawnableProductAssetDependency(AZStd::string prefabName, AZStd::string dependentPrefabName) + { + using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; + + prefabName += AzFramework::Spawnable::DotFileExtension; + uint32_t spawnableSubId = ConversionUtils::BuildSubId(AZStd::move(prefabName)); + + dependentPrefabName += AzFramework::Spawnable::DotFileExtension; + uint32_t spawnablePrefabSubId = ConversionUtils::BuildSubId(AZStd::move(dependentPrefabName)); + + return RegisterSpawnableProductAssetDependency(spawnableSubId, spawnablePrefabSubId); + } + + bool PrefabProcessorContext::RegisterSpawnableProductAssetDependency(AZStd::string prefabName, const AZ::Data::AssetId& dependentAssetId) + { + using ConversionUtils = PrefabConversionUtils::ProcessedObjectStore; + + prefabName += AzFramework::Spawnable::DotFileExtension; + uint32_t spawnableSubId = ConversionUtils::BuildSubId(AZStd::move(prefabName)); + + AZ::Data::AssetId spawnableAssetId(GetSourceUuid(), spawnableSubId); + + return RegisterProductAssetDependency(spawnableAssetId, dependentAssetId); + } + + bool PrefabProcessorContext::RegisterSpawnableProductAssetDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId) + { + AZ::Data::AssetId spawnableAssetId(GetSourceUuid(), spawnableAssetSubId); + AZ::Data::AssetId dependentSpawnableAssetId(GetSourceUuid(), dependentSpawnableAssetSubId); + + return RegisterProductAssetDependency(spawnableAssetId, dependentSpawnableAssetId); + } + + bool PrefabProcessorContext::RegisterProductAssetDependency(const AZ::Data::AssetId& assetId, const AZ::Data::AssetId& dependentAssetId) + { + return m_registeredProductAssetDependencies[assetId].emplace(dependentAssetId).second; + } + PrefabProcessorContext::ProcessedObjectStoreContainer& PrefabProcessorContext::GetProcessedObjects() { return m_products; @@ -80,6 +97,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils return m_products; } + PrefabProcessorContext::ProductAssetDependencyContainer& PrefabProcessorContext::GetRegisteredProductAssetDependencies() + { + return m_registeredProductAssetDependencies; + } + + const PrefabProcessorContext::ProductAssetDependencyContainer& PrefabProcessorContext::GetRegisteredProductAssetDependencies() const + { + return m_registeredProductAssetDependencies; + } + void PrefabProcessorContext::SetPlatformTags(AZ::PlatformTagSet tags) { m_platformTags = AZStd::move(tags); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h index 66368f335b..3dc8c99bf3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h @@ -29,6 +29,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils { public: using ProcessedObjectStoreContainer = AZStd::vector; + using ProductAssetDependencyContainer = + AZStd::unordered_map>; AZ_CLASS_ALLOCATOR(PrefabProcessorContext, AZ::SystemAllocator, 0); AZ_RTTI(PrefabProcessorContext, "{C7D77E3A-C544-486B-B774-7C82C38FE22F}"); @@ -37,14 +39,21 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils virtual ~PrefabProcessorContext() = default; virtual bool AddPrefab(AZStd::string prefabName, PrefabDom prefab); - virtual bool RemovePrefab(AZStd::string_view prefabName); virtual void ListPrefabs(const AZStd::function& callback); virtual void ListPrefabs(const AZStd::function& callback) const; virtual bool HasPrefabs() const; + virtual bool RegisterSpawnableProductAssetDependency(AZStd::string prefabName, AZStd::string dependentPrefabName); + virtual bool RegisterSpawnableProductAssetDependency(AZStd::string prefabName, const AZ::Data::AssetId& dependentAssetId); + virtual bool RegisterSpawnableProductAssetDependency(uint32_t spawnableAssetSubId, uint32_t dependentSpawnableAssetSubId); + virtual bool RegisterProductAssetDependency(const AZ::Data::AssetId& assetId, const AZ::Data::AssetId& dependentAssetId); + virtual ProcessedObjectStoreContainer& GetProcessedObjects(); virtual const ProcessedObjectStoreContainer& GetProcessedObjects() const; + virtual ProductAssetDependencyContainer& GetRegisteredProductAssetDependencies(); + virtual const ProductAssetDependencyContainer& GetRegisteredProductAssetDependencies() const; + virtual void SetPlatformTags(AZ::PlatformTagSet tags); virtual const AZ::PlatformTagSet& GetPlatformTags() const; virtual const AZ::Uuid& GetSourceUuid() const; @@ -57,7 +66,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils NamedPrefabContainer m_prefabs; ProcessedObjectStoreContainer m_products; - AZStd::vector m_delayedDelete; + ProductAssetDependencyContainer m_registeredProductAssetDependencies; + AZ::PlatformTagSet m_platformTags; AZ::Uuid m_sourceUuid; bool m_isIterating{ false }; diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp index 84a4cd5cc6..a95ec60d61 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.cpp @@ -176,6 +176,7 @@ namespace AZ::Prefab bool PrefabBuilderComponent::StoreProducts( AZ::IO::PathView tempDirPath, const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store, + const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductAssetDependencyContainer& registeredDependencies, AZStd::vector& outputProducts) const { outputProducts.reserve(store.size()); @@ -214,6 +215,18 @@ namespace AZ::Prefab if (AssetBuilderSDK::OutputObject(&object.GetAsset(), object.GetAssetType(), productPath.String(), object.GetAssetType(), object.GetAsset().GetId().m_subId, product)) { + auto findRegisteredDependencies = registeredDependencies.find(object.GetAsset().GetId()); + if (findRegisteredDependencies != registeredDependencies.end()) + { + AZStd::transform(findRegisteredDependencies->second.begin(), findRegisteredDependencies->second.end(), + AZStd::back_inserter(product.m_dependencies), + [](const AZ::Data::AssetId& productId) -> AssetBuilderSDK::ProductDependency + { + return AssetBuilderSDK::ProductDependency(productId, + AZ::Data::ProductDependencyInfo::CreateFlags(AZ::Data::AssetLoadBehavior::NoLoad)); + }); + } + outputProducts.push_back(AZStd::move(product)); } @@ -248,20 +261,15 @@ namespace AZ::Prefab if (context.HasCompletedSuccessfully()) { AZ_TracePrintf("Prefab Builder", "Finalizing products.\n"); - if (!context.HasPrefabs()) + + if (StoreProducts(tempDirPath, context.GetProcessedObjects(), + context.GetRegisteredProductAssetDependencies(), jobProducts)) { - if (StoreProducts(tempDirPath, context.GetProcessedObjects(), jobProducts)) - { - return true; - } - else - { - AZ_Error("Prefab Builder", false, "One or more objects couldn't be committed to disk."); - } + return true; } else { - AZ_Error("Prefab Builder", false, "After processing there were still Prefabs left."); + AZ_Error("Prefab Builder", false, "One or more objects couldn't be committed to disk."); } } else diff --git a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h index 7fbd0b4be0..f78e2cb889 100644 --- a/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h +++ b/Gems/Prefab/PrefabBuilder/PrefabBuilderComponent.h @@ -69,6 +69,7 @@ namespace AZ::Prefab bool StoreProducts( AZ::IO::PathView tempDirPath, const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store, + const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductAssetDependencyContainer& registeredDependencies, AZStd::vector& outputProducts) const; void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response);