Files
UnrealEngineUWP/Engine/Plugins/Runtime/Metasound/Source/MetasoundFrontend/Private/Interfaces/MetasoundFrontendInterfaceRegistry.cpp
rob gay c97856654f [Backout] - CL33854938
[FYI] bob.tellez
Original CL Desc
-----------------------------------------------------------------
[Backout] - CL33838807
[FYI] Rob.Gay
Original CL Desc
-----------------------------------------------------------------
- Move MetaSound input/output editor validation, GetMemberName/Description, IsInterfaceMember to builder API
- Add warnings on register for interface vertex members (disabled until projects are complaint) to ensure they are following the expected naming convention (i.e. namespace matches that of owning interface)
    - Note this is editor only to avoid spamming cook and failing builds
- Move versioning to use shared builder now that IDocumentBuilderRegistry is available prior to all asset serialize load calls. This ensures that multiple builders are not accessing the same asset when loading and versioning/migrating old editor data
#jira UE-194160
#rb phil.popp
#rnx

[CL 33957350 by rob gay in ue5-main branch]
2024-05-28 18:51:03 -04:00

172 lines
5.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Interfaces/MetasoundFrontendInterfaceRegistry.h"
#include "AudioParameter.h"
#include "HAL/PlatformTime.h"
#include "Interfaces/MetasoundFrontendInterfaceBindingRegistry.h"
#include "MetasoundFrontendInterfaceRegistryPrivate.h"
#include "MetasoundFrontendRegistryTransaction.h"
#include "MetasoundTrace.h"
#ifndef UE_METASOUND_ENABLE_INTERFACE_VALIDATION
#define UE_METASOUND_ENABLE_INTERFACE_VALIDATION 0
#endif // !define UE_METASOUND_ENABLE_INTERFACE_VALIDATION
namespace Metasound::Frontend
{
FInterfaceRegistry::FInterfaceRegistry()
: TransactionBuffer(MakeShared<TTransactionBuffer<FInterfaceRegistryTransaction>>())
{
}
bool FInterfaceRegistry::RegisterInterface(TUniquePtr<IInterfaceRegistryEntry>&& InEntry)
{
METASOUND_LLM_SCOPE;
FInterfaceRegistryTransaction::FTimeType TransactionTime = FPlatformTime::Cycles64();
if (InEntry.IsValid())
{
const FInterfaceRegistryKey Key = GetInterfaceRegistryKey(InEntry->GetInterface());
if (IsValidInterfaceRegistryKey(Key))
{
if (const IInterfaceRegistryEntry* Entry = FindInterfaceRegistryEntry(Key))
{
UE_LOG(LogMetaSound, Warning, TEXT("Registration of interface overwriting previously registered interface [RegistryKey: %s]"), *Key);
FInterfaceRegistryTransaction Transaction{FInterfaceRegistryTransaction::ETransactionType::InterfaceUnregistration, Key, Entry->GetInterface().Version, TransactionTime};
TransactionBuffer->AddTransaction(MoveTemp(Transaction));
}
#if UE_METASOUND_ENABLE_INTERFACE_VALIDATION
// Don't run vertex name validation warning for deprecated registry entries. Some of these may be
// versioning schema that have a subsequent version or versions fixing the very problem this log is reporting.
if (!InEntry->IsDeprecated())
{
const FName InterfaceNamespace = InEntry->GetInterface().Version.Name;
auto LogIfMismatch = [this, &InterfaceNamespace](FName VertexName)
{
FName VertexNamespace;
if (!IsInterfaceVertexNameValid(InterfaceNamespace, VertexName, &VertexNamespace))
{
UE_LOG(LogMetaSound, Warning, TEXT("Interface '%s' contains vertex '%s' with mismatched namespace '%s': "
"All interface-defined vertices' must start with matching interface namespace (See AUDIO_PARAMETER_INTERFACE_MEMBER_DEFINE/AUDIO_PARAMETER_INTERFACE_NAMESPACE macro to ensure convention is followed). "
"Failing to fix relationship via interface versioning will fail validation/cook in future builds."), *InterfaceNamespace.ToString(), *VertexName.ToString(), *VertexNamespace.ToString());
}
};
for (const FMetasoundFrontendClassVertex& Vertex : InEntry->GetInterface().Inputs)
{
LogIfMismatch(Vertex.Name);
}
for (const FMetasoundFrontendClassVertex& Vertex : InEntry->GetInterface().Outputs)
{
LogIfMismatch(Vertex.Name);
}
}
#endif // UE_METASOUND_ENABLE_INTERFACE_VALIDATION
FInterfaceRegistryTransaction Transaction{FInterfaceRegistryTransaction::ETransactionType::InterfaceRegistration, Key, InEntry->GetInterface().Version, TransactionTime};
TransactionBuffer->AddTransaction(MoveTemp(Transaction));
Entries.Add(Key, MoveTemp(InEntry));
return true;
}
}
return false;
}
const IInterfaceRegistryEntry* FInterfaceRegistry::FindInterfaceRegistryEntry(const FInterfaceRegistryKey& InKey) const
{
if (const TUniquePtr<IInterfaceRegistryEntry>* Entry = Entries.Find(InKey))
{
return Entry->Get();
}
return nullptr;
}
bool FInterfaceRegistry::FindInterface(const FInterfaceRegistryKey& InKey, FMetasoundFrontendInterface& OutInterface) const
{
if (const IInterfaceRegistryEntry* Entry = FindInterfaceRegistryEntry(InKey))
{
OutInterface = Entry->GetInterface();
return true;
}
return false;
}
TUniquePtr<FInterfaceTransactionStream> FInterfaceRegistry::CreateTransactionStream()
{
return MakeUnique<FInterfaceTransactionStream>(TransactionBuffer);
}
bool IsValidInterfaceRegistryKey(const FInterfaceRegistryKey& InKey)
{
return !InKey.IsEmpty();
}
FInterfaceRegistryKey GetInterfaceRegistryKey(const FMetasoundFrontendVersion& InInterfaceVersion)
{
return FString::Format(TEXT("{0}_{1}.{2}"), { InInterfaceVersion.Name.ToString(), InInterfaceVersion.Number.Major, InInterfaceVersion.Number.Minor });
}
FInterfaceRegistryKey GetInterfaceRegistryKey(const FMetasoundFrontendInterface& InInterface)
{
return GetInterfaceRegistryKey(InInterface.Version);
}
FInterfaceRegistryTransaction::FInterfaceRegistryTransaction(ETransactionType InType, const FInterfaceRegistryKey& InKey, const FMetasoundFrontendVersion& InInterfaceVersion, FInterfaceRegistryTransaction::FTimeType InTimestamp)
: Type(InType)
, Key(InKey)
, InterfaceVersion(InInterfaceVersion)
, Timestamp(InTimestamp)
{
}
FInterfaceRegistryTransaction::ETransactionType FInterfaceRegistryTransaction::GetTransactionType() const
{
return Type;
}
const FMetasoundFrontendVersion& FInterfaceRegistryTransaction::GetInterfaceVersion() const
{
return InterfaceVersion;
}
const FInterfaceRegistryKey& FInterfaceRegistryTransaction::GetInterfaceRegistryKey() const
{
return Key;
}
FInterfaceRegistryTransaction::FTimeType FInterfaceRegistryTransaction::GetTimestamp() const
{
return Timestamp;
}
FInterfaceRegistry& FInterfaceRegistry::Get()
{
static FInterfaceRegistry Registry;
return Registry;
}
bool FInterfaceRegistry::IsInterfaceVertexNameValid(FName InterfaceNamespace, FName FullVertexName, FName* VertexNamespace) const
{
FName Namespace;
FName Name;
Audio::FParameterPath::SplitName(FullVertexName, Namespace, Name);
if (VertexNamespace)
{
*VertexNamespace = Namespace;
}
return InterfaceNamespace == Namespace;
}
IInterfaceRegistry& IInterfaceRegistry::Get()
{
return FInterfaceRegistry::Get();
}
} // namespace Metasound::Frontend