Merge pull request #438 from aws-lumberyard-dev/Spawnable/ProductDependency

AddProductDependency to handle inter-product dependencies in PrefabProcessors
This commit is contained in:
sconel
2021-05-11 15:19:01 -07:00
committed by GitHub
5 changed files with 82 additions and 38 deletions
@@ -84,8 +84,6 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
} }
SpawnableUtils::SortEntitiesByTransformHierarchy(*spawnable); SpawnableUtils::SortEntitiesByTransformHierarchy(*spawnable);
context.GetProcessedObjects().push_back(AZStd::move(object)); context.GetProcessedObjects().push_back(AZStd::move(object));
context.RemovePrefab(prefabName);
} }
else else
{ {
@@ -10,6 +10,8 @@
* *
*/ */
#include <AzFramework/Spawnable/Spawnable.h>
#include <AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h> #include <AzToolsFramework/Prefab/Spawnable/PrefabProcessorContext.h>
namespace AzToolsFramework::Prefab::PrefabConversionUtils namespace AzToolsFramework::Prefab::PrefabConversionUtils
@@ -24,37 +26,14 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
return result.second; 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<void(AZStd::string_view, PrefabDom&)>& callback) void PrefabProcessorContext::ListPrefabs(const AZStd::function<void(AZStd::string_view, PrefabDom&)>& callback)
{ {
m_isIterating = true; m_isIterating = true;
for (auto& it : m_prefabs) 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; 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<void(AZStd::string_view, const PrefabDom&)>& callback) const void PrefabProcessorContext::ListPrefabs(const AZStd::function<void(AZStd::string_view, const PrefabDom&)>& callback) const
@@ -70,6 +49,44 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
return !m_prefabs.empty(); 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() PrefabProcessorContext::ProcessedObjectStoreContainer& PrefabProcessorContext::GetProcessedObjects()
{ {
return m_products; return m_products;
@@ -80,6 +97,16 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
return m_products; 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) void PrefabProcessorContext::SetPlatformTags(AZ::PlatformTagSet tags)
{ {
m_platformTags = AZStd::move(tags); m_platformTags = AZStd::move(tags);
@@ -29,6 +29,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
{ {
public: public:
using ProcessedObjectStoreContainer = AZStd::vector<ProcessedObjectStore>; using ProcessedObjectStoreContainer = AZStd::vector<ProcessedObjectStore>;
using ProductAssetDependencyContainer =
AZStd::unordered_map<AZ::Data::AssetId, AZStd::unordered_set<AZ::Data::AssetId>>;
AZ_CLASS_ALLOCATOR(PrefabProcessorContext, AZ::SystemAllocator, 0); AZ_CLASS_ALLOCATOR(PrefabProcessorContext, AZ::SystemAllocator, 0);
AZ_RTTI(PrefabProcessorContext, "{C7D77E3A-C544-486B-B774-7C82C38FE22F}"); AZ_RTTI(PrefabProcessorContext, "{C7D77E3A-C544-486B-B774-7C82C38FE22F}");
@@ -37,14 +39,21 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
virtual ~PrefabProcessorContext() = default; virtual ~PrefabProcessorContext() = default;
virtual bool AddPrefab(AZStd::string prefabName, PrefabDom prefab); virtual bool AddPrefab(AZStd::string prefabName, PrefabDom prefab);
virtual bool RemovePrefab(AZStd::string_view prefabName);
virtual void ListPrefabs(const AZStd::function<void(AZStd::string_view, PrefabDom&)>& callback); virtual void ListPrefabs(const AZStd::function<void(AZStd::string_view, PrefabDom&)>& callback);
virtual void ListPrefabs(const AZStd::function<void(AZStd::string_view, const PrefabDom&)>& callback) const; virtual void ListPrefabs(const AZStd::function<void(AZStd::string_view, const PrefabDom&)>& callback) const;
virtual bool HasPrefabs() 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 ProcessedObjectStoreContainer& GetProcessedObjects();
virtual const ProcessedObjectStoreContainer& GetProcessedObjects() const; virtual const ProcessedObjectStoreContainer& GetProcessedObjects() const;
virtual ProductAssetDependencyContainer& GetRegisteredProductAssetDependencies();
virtual const ProductAssetDependencyContainer& GetRegisteredProductAssetDependencies() const;
virtual void SetPlatformTags(AZ::PlatformTagSet tags); virtual void SetPlatformTags(AZ::PlatformTagSet tags);
virtual const AZ::PlatformTagSet& GetPlatformTags() const; virtual const AZ::PlatformTagSet& GetPlatformTags() const;
virtual const AZ::Uuid& GetSourceUuid() const; virtual const AZ::Uuid& GetSourceUuid() const;
@@ -57,7 +66,8 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
NamedPrefabContainer m_prefabs; NamedPrefabContainer m_prefabs;
ProcessedObjectStoreContainer m_products; ProcessedObjectStoreContainer m_products;
AZStd::vector<AZStd::string> m_delayedDelete; ProductAssetDependencyContainer m_registeredProductAssetDependencies;
AZ::PlatformTagSet m_platformTags; AZ::PlatformTagSet m_platformTags;
AZ::Uuid m_sourceUuid; AZ::Uuid m_sourceUuid;
bool m_isIterating{ false }; bool m_isIterating{ false };
@@ -176,6 +176,7 @@ namespace AZ::Prefab
bool PrefabBuilderComponent::StoreProducts( bool PrefabBuilderComponent::StoreProducts(
AZ::IO::PathView tempDirPath, AZ::IO::PathView tempDirPath,
const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store, const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store,
const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductAssetDependencyContainer& registeredDependencies,
AZStd::vector<AssetBuilderSDK::JobProduct>& outputProducts) const AZStd::vector<AssetBuilderSDK::JobProduct>& outputProducts) const
{ {
outputProducts.reserve(store.size()); outputProducts.reserve(store.size());
@@ -214,6 +215,18 @@ namespace AZ::Prefab
if (AssetBuilderSDK::OutputObject(&object.GetAsset(), object.GetAssetType(), productPath.String(), object.GetAssetType(), if (AssetBuilderSDK::OutputObject(&object.GetAsset(), object.GetAssetType(), productPath.String(), object.GetAssetType(),
object.GetAsset().GetId().m_subId, product)) 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)); outputProducts.push_back(AZStd::move(product));
} }
@@ -248,20 +261,15 @@ namespace AZ::Prefab
if (context.HasCompletedSuccessfully()) if (context.HasCompletedSuccessfully())
{ {
AZ_TracePrintf("Prefab Builder", "Finalizing products.\n"); 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;
{
return true;
}
else
{
AZ_Error("Prefab Builder", false, "One or more objects couldn't be committed to disk.");
}
} }
else 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 else
@@ -69,6 +69,7 @@ namespace AZ::Prefab
bool StoreProducts( bool StoreProducts(
AZ::IO::PathView tempDirPath, AZ::IO::PathView tempDirPath,
const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store, const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProcessedObjectStoreContainer& store,
const AzToolsFramework::Prefab::PrefabConversionUtils::PrefabProcessorContext::ProductAssetDependencyContainer& registeredDependencies,
AZStd::vector<AssetBuilderSDK::JobProduct>& outputProducts) const; AZStd::vector<AssetBuilderSDK::JobProduct>& outputProducts) const;
void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response); void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response);