2023-03-13 17:23:05 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "Interfaces/MetasoundFrontendInterfaceRegistry.h"
2024-05-28 18:51:03 -04:00
# include "AudioParameter.h"
2023-03-13 17:23:05 -04:00
# include "HAL/PlatformTime.h"
# include "Interfaces/MetasoundFrontendInterfaceBindingRegistry.h"
# include "MetasoundFrontendInterfaceRegistryPrivate.h"
# include "MetasoundFrontendRegistryTransaction.h"
# include "MetasoundTrace.h"
2024-05-28 18:51:03 -04:00
# ifndef UE_METASOUND_ENABLE_INTERFACE_VALIDATION
# define UE_METASOUND_ENABLE_INTERFACE_VALIDATION 0
# endif // !define UE_METASOUND_ENABLE_INTERFACE_VALIDATION
2023-03-13 17:23:05 -04:00
namespace Metasound : : Frontend
{
FInterfaceRegistry : : FInterfaceRegistry ( )
: TransactionBuffer ( MakeShared < TTransactionBuffer < FInterfaceRegistryTransaction > > ( ) )
{
}
2023-04-04 19:14:26 -04:00
bool FInterfaceRegistry : : RegisterInterface ( TUniquePtr < IInterfaceRegistryEntry > & & InEntry )
2023-03-13 17:23:05 -04:00
{
METASOUND_LLM_SCOPE ;
FInterfaceRegistryTransaction : : FTimeType TransactionTime = FPlatformTime : : Cycles64 ( ) ;
if ( InEntry . IsValid ( ) )
{
2024-05-28 18:51:03 -04:00
const FInterfaceRegistryKey Key = GetInterfaceRegistryKey ( InEntry - > GetInterface ( ) ) ;
2023-03-13 17:23:05 -04:00
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 ) ) ;
}
2024-05-28 18:51:03 -04:00
# 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
2023-03-13 17:23:05 -04:00
FInterfaceRegistryTransaction Transaction { FInterfaceRegistryTransaction : : ETransactionType : : InterfaceRegistration , Key , InEntry - > GetInterface ( ) . Version , TransactionTime } ;
TransactionBuffer - > AddTransaction ( MoveTemp ( Transaction ) ) ;
2023-03-17 07:06:23 -04:00
Entries . Add ( Key , MoveTemp ( InEntry ) ) ;
2023-04-04 19:14:26 -04:00
return true ;
2023-03-13 17:23:05 -04:00
}
}
2023-04-04 19:14:26 -04:00
return false ;
2023-03-13 17:23:05 -04:00
}
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 ;
}
2024-05-28 18:51:03 -04:00
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 ;
}
2023-03-13 17:23:05 -04:00
IInterfaceRegistry & IInterfaceRegistry : : Get ( )
{
return FInterfaceRegistry : : Get ( ) ;
}
} // namespace Metasound::Frontend