Don't serialize cached dependency data on MetaSound graphs to avoid text desync or out-of-date data when autoupdate is disabled for a given asset.

TODO: Split out FMetasoundFrontendClass to class & dependency struct, where dependency is only the information required to find an item in the registry and potentially a couple non-localized breadcrumbs
#rb phil.popp
#jira none
#rnx
#preflight 61e8f894276892ce10892644
#preflight 61e9f7f91739bb8724e071ec

#ROBOMERGE-AUTHOR: rob.gay
#ROBOMERGE-SOURCE: CL 18684546 in //UE5/Release-5.0/... via CL 18684559 via CL 18684566
#ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v902-18672795)

[CL 18684575 by rob gay in ue5-main branch]
This commit is contained in:
rob gay
2022-01-20 19:19:55 -05:00
parent a9665e342b
commit fe1d4b93a4
7 changed files with 143 additions and 30 deletions
@@ -122,6 +122,11 @@ void FMetasoundAssetBase::RegisterGraphWithFrontend(Metasound::Frontend::FMetaSo
#endif // WITH_EDITORONLY_DATA
}
// Caches commonly used class MetaData that isn't required for finding & building dependencies into local graph.
// Must be completed after auto-update to ensure all non-transient referenced dependency data is up-to-date (ex.
// class version), which is required for most accurately caching current registry metadata.
CacheDependencyRegistryData();
// Registers node by copying document. Updates to document require re-registration.
class FNodeRegistryEntry : public INodeRegistryEntry
{
@@ -331,15 +336,28 @@ void FMetasoundAssetBase::AddDefaultInterfaces()
FModifyRootGraphInterfaces({ }, InitInterfaces).Transform(DocumentHandle);
}
void FMetasoundAssetBase::CacheDependencyRegistryData()
{
if (FMetasoundFrontendDocument* Document = GetDocument().Get())
{
for (FMetasoundFrontendClass& Class : Document->Dependencies)
{
Class.CacheRegistryData();
}
}
}
void FMetasoundAssetBase::ClearDependencyRegistryData()
{
if (FMetasoundFrontendDocument* Document = GetDocument().Get())
{
for (FMetasoundFrontendClass& Class : Document->Dependencies)
{
Class.ClearRegistryData();
}
}
}
bool FMetasoundAssetBase::VersionAsset()
{
using namespace Metasound;
@@ -2,8 +2,10 @@
#include "MetasoundFrontendDocument.h"
#include "Algo/ForEach.h"
#include "Algo/Transform.h"
#include "IAudioParameterInterfaceRegistry.h"
#include "Logging/LogMacros.h"
#include "MetasoundFrontend.h"
#include "MetasoundFrontendRegistries.h"
#include "MetasoundLog.h"
@@ -239,6 +241,74 @@ void FMetasoundFrontendClassMetadata::SetVersion(const FMetasoundFrontendVersion
SetWithChangeID(InVersion, Version, ChangeID);
}
void FMetasoundFrontendClass::CacheRegistryData()
{
using namespace Metasound::Frontend;
const FNodeRegistryKey Key = NodeRegistryKey::CreateKey(Metadata);
FMetasoundFrontendClass Class;
FMetasoundFrontendRegistryContainer* Registry = FMetasoundFrontendRegistryContainer::Get();
if (ensure(Registry))
{
if (Registry->FindFrontendClassFromRegistered(Key, Class))
{
Metadata = Class.Metadata;
using FNameTypeKey = TPair<FName, FName>;
TMap<FNameTypeKey, const FMetasoundFrontendVertexMetadata*> InterfaceMembers;
auto MakePairFromVertex = [](const FMetasoundFrontendClassVertex& InVertex)
{
const FNameTypeKey Key(InVertex.Name, InVertex.TypeName);
return TPair<FNameTypeKey, const FMetasoundFrontendVertexMetadata*> { Key, &InVertex.Metadata };
};
auto CacheRegistryVertexMetadata = [&](FMetasoundFrontendClassVertex& OutVertex)
{
const FNameTypeKey Key(OutVertex.Name, OutVertex.TypeName);
if (const FMetasoundFrontendVertexMetadata* RegVertex = InterfaceMembers.FindRef(Key))
{
OutVertex.Metadata = *RegVertex;
}
};
Algo::Transform(Class.Interface.Inputs, InterfaceMembers, [&](const FMetasoundFrontendClassInput& Input) { return MakePairFromVertex(Input); });
Algo::ForEach(Interface.Inputs, [&](FMetasoundFrontendClassInput& Input) { CacheRegistryVertexMetadata(Input); });
InterfaceMembers.Reset();
Algo::Transform(Class.Interface.Outputs, InterfaceMembers, [&](const FMetasoundFrontendClassOutput& Output) { return MakePairFromVertex(Output); });
Algo::ForEach(Interface.Outputs, [&](FMetasoundFrontendClassOutput& Output) { CacheRegistryVertexMetadata(Output); });
}
else
{
UE_LOG(LogMetaSound, Error, TEXT("Failed to load document dependency class metadata: Missing dependency with key '%s'"), *Key);
}
Interface.InputStyle = Class.Interface.InputStyle;
Interface.OutputStyle = Class.Interface.OutputStyle;
Style = Class.Style;
}
}
void FMetasoundFrontendClass::ClearRegistryData()
{
Metadata.DisplayName = { };
Metadata.Description = { };
Metadata.PromptIfMissing = { };
Metadata.Author = { };
Metadata.Keywords.Reset();
Metadata.CategoryHierarchy.Reset();
Algo::ForEach(Interface.Inputs, [](FMetasoundFrontendClassInput& Input) { Input.Metadata = { }; });
Algo::ForEach(Interface.Outputs, [](FMetasoundFrontendClassOutput& Output) { Output.Metadata = { }; });
Interface.InputStyle = { };
Interface.OutputStyle = { };
Style = { };
}
FMetasoundFrontendClassMetadata FMetasoundFrontendClassMetadata::GenerateClassDescription(const Metasound::FNodeClassMetadata& InNodeClassMetadata, EMetasoundFrontendClassType InType)
{
FMetasoundFrontendClassMetadata NewMetadata;
@@ -470,7 +470,7 @@ namespace Metasound
PresetReferencedMetaSoundAsset = IMetaSoundAssetManager::GetChecked().TryLoadAssetFromKey(RegistryKey);
if (!PresetReferencedMetaSoundAsset)
{
UE_LOG(LogMetaSound, Error, TEXT("Auto-Updating preset '%s' failed: Referenced class '%s' missing."), *AssetPath, *ClassMetadata.GetDisplayName().ToString());
UE_LOG(LogMetaSound, Error, TEXT("Auto-Updating preset '%s' failed: Referenced class '%s' missing."), *AssetPath, *ClassMetadata.GetClassName().ToString());
}
return;
}
@@ -484,12 +484,12 @@ namespace Metasound
FMetasoundFrontendVersionNumber UpdateVersion = NodeHandle->FindHighestMinorVersionInRegistry();
if (UpdateVersion.IsValid() && UpdateVersion > ClassMetadata.GetVersion())
{
UE_LOG(LogMetaSound, Display, TEXT("Auto-Updating '%s' node class '%s': Newer version '%s' found."), *AssetPath, *ClassMetadata.GetDisplayName().ToString(), *UpdateVersion.ToString());
UE_LOG(LogMetaSound, Display, TEXT("Auto-Updating '%s' node class '%s': Newer version '%s' found."), *AssetPath, *ClassMetadata.GetClassName().ToString(), *UpdateVersion.ToString());
}
else if (InterfaceUpdates.ContainsChanges())
{
UpdateVersion = ClassMetadata.GetVersion();
UE_LOG(LogMetaSound, Display, TEXT("Auto-Updating '%s' node class '%s (%s)': Interface change detected."), *AssetPath, *ClassMetadata.GetDisplayName().ToString(), *UpdateVersion.ToString());
UE_LOG(LogMetaSound, Display, TEXT("Auto-Updating '%s' node class '%s (%s)': Interface change detected."), *AssetPath, *ClassMetadata.GetClassName().ToString(), *UpdateVersion.ToString());
}
NodesToUpdate.Add(TPair<FNodeHandle, FMetasoundFrontendVersionNumber>(NodeHandle, UpdateVersion));
@@ -122,6 +122,8 @@ public:
const FMetasoundFrontendDocument& GetDocumentChecked() const;
void AddDefaultInterfaces();
void CacheDependencyRegistryData();
void ClearDependencyRegistryData();
bool VersionAsset();
#if WITH_EDITORONLY_DATA
@@ -824,6 +824,9 @@ public:
{
ChangeID = FGuid::NewGuid();
}
// Required to allow caching registry data without modifying the ChangeID
friend struct FMetasoundFrontendClass;
};
@@ -1040,6 +1043,9 @@ public:
// External/Internal should probably be a separate field.
// ChangeID = FGuid::NewGuid();
}
// Required to allow caching registry data without modifying the ChangeID
friend struct FMetasoundFrontendClass;
};
USTRUCT()
@@ -1051,18 +1057,6 @@ struct FMetasoundFrontendClassStyle
FMetasoundFrontendClassStyleDisplay Display;
};
USTRUCT()
struct FMetasoundFrontendEditorData
{
GENERATED_BODY()
UPROPERTY()
FMetasoundFrontendVersion Version;
UPROPERTY()
TArray<uint8> Data;
};
USTRUCT()
struct METASOUNDFRONTEND_API FMetasoundFrontendClass
{
@@ -1079,11 +1073,22 @@ struct METASOUNDFRONTEND_API FMetasoundFrontendClass
UPROPERTY(EditAnywhere, Category = CustomView)
FMetasoundFrontendClassInterface Interface;
UPROPERTY()
FMetasoundFrontendEditorData EditorData;
UPROPERTY()
FMetasoundFrontendClassStyle Style;
/*
* Caches metadata found in the registry on the class
* that is not necessary for serialization or core graph
* generation.
*/
void CacheRegistryData();
/*
* Clears cached metadata found in the registry on the class
* that is not necessary for serialization or core graph
* generation.
*/
void ClearRegistryData();
};
USTRUCT()
@@ -1121,9 +1126,6 @@ struct METASOUNDFRONTEND_API FMetasoundFrontendDocument
UPROPERTY(EditAnywhere, Category = Metadata)
FMetasoundFrontendDocumentMetadata Metadata;
UPROPERTY()
FMetasoundFrontendEditorData EditorData;
public:
UPROPERTY(VisibleAnywhere, Category = CustomView)
TSet<FMetasoundFrontendVersion> Interfaces;