2023-06-20 13:12:39 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "MetasoundFrontendDocumentIdGenerator.h"
namespace Metasound
{
namespace Frontend
{
2023-10-16 18:42:49 -04:00
namespace
{
std : : atomic < uint64 > GlobalAtomicMetasoundIdCounter = 1 ; // First ID will be 1. This is because we will make this into an FGuid which cannot be zero.
}
2023-10-11 18:39:54 -04:00
int32 MetaSoundEnableCookDeterministicIDGeneration = 1 ;
2023-08-21 12:25:01 -04:00
FAutoConsoleVariableRef CVarMetaSoundEnableCookDeterministicIDGeneration (
TEXT ( " au.MetaSound.EnableCookDeterministicIDGeneration " ) ,
MetaSoundEnableCookDeterministicIDGeneration ,
2023-10-11 18:39:54 -04:00
TEXT ( " Enable moving MetaSound registration operations like AutoUpdate and some template node transformations from runtime to cook using deterministic ID generation \n " )
TEXT ( " 0: Disabled, !0: Enabled (default) " ) ,
2023-07-24 12:45:51 -04:00
ECVF_Default ) ;
2023-06-20 13:12:39 -04:00
FDocumentIDGenerator : : FScopeDeterminism : : FScopeDeterminism ( bool bInIsDeterministic )
{
FDocumentIDGenerator & IDGen = Get ( ) ;
bOriginalValue = IDGen . GetDeterminism ( ) ;
IDGen . SetDeterminism ( bInIsDeterministic ) ;
}
bool FDocumentIDGenerator : : FScopeDeterminism : : GetDeterminism ( ) const
{
return Get ( ) . GetDeterminism ( ) ;
}
FDocumentIDGenerator : : FScopeDeterminism : : ~ FScopeDeterminism ( )
{
Get ( ) . SetDeterminism ( bOriginalValue ) ;
}
void FDocumentIDGenerator : : SetDeterminism ( bool bInIsDeterministic )
{
bIsDeterministic = bInIsDeterministic ;
}
bool FDocumentIDGenerator : : GetDeterminism ( ) const
{
return bIsDeterministic ;
}
FDocumentIDGenerator & FDocumentIDGenerator : : Get ( )
{
thread_local FDocumentIDGenerator IDGenerator ;
return IDGenerator ;
}
FGuid FDocumentIDGenerator : : CreateNodeID ( const FMetasoundFrontendDocument & InDocument ) const
{
return CreateIDFromDocument ( InDocument ) ;
}
FGuid FDocumentIDGenerator : : CreateVertexID ( const FMetasoundFrontendDocument & InDocument ) const
{
return CreateIDFromDocument ( InDocument ) ;
}
FGuid FDocumentIDGenerator : : CreateClassID ( const FMetasoundFrontendDocument & InDocument ) const
{
return CreateIDFromDocument ( InDocument ) ;
}
FGuid FDocumentIDGenerator : : CreateIDFromDocument ( const FMetasoundFrontendDocument & InDocument ) const
{
if ( bIsDeterministic )
{
const uint32 Value = InDocument . GetNextIdCounter ( ) ;
const FGuid CounterGuid = FGuid ( Value < < 6 , Value < < 4 , Value < < 2 , Value ) ;
return FGuid : : Combine ( InDocument . RootGraph . ID , CounterGuid ) ;
}
else
{
return FGuid : : NewGuid ( ) ;
}
}
FClassIDGenerator & FClassIDGenerator : : Get ( )
{
static FClassIDGenerator IDGenerator ;
return IDGenerator ;
}
FGuid FClassIDGenerator : : CreateInputID ( const FMetasoundFrontendClassInput & Input ) const
{
const FGuid ClassInputNamespaceGuid = FGuid ( " {149FEB6E-B9F9-47A6-AD4F-B78655F6EBE8} " ) ;
FString NameToHash = FString : : Printf ( TEXT ( " ClassInput.%s.%s.%s " ) , * Input . Name . ToString ( ) , * Input . TypeName . ToString ( ) , LexToString ( Input . AccessType ) ) ;
return CreateNamespacedIDFromString ( ClassInputNamespaceGuid , NameToHash ) ;
}
FGuid FClassIDGenerator : : CreateInputID ( const Audio : : FParameterInterface : : FInput & Input ) const
{
const FGuid ParameterInterfaceInputNamespaceGuid = FGuid ( " {D9E893C0-92B3-4CB4-8306-4525ABEACADD} " ) ;
FString NameToHash = FString : : Printf ( TEXT ( " ParameterInterfaceInput.%s.%s " ) , * Input . InitValue . ParamName . ToString ( ) , * Input . DataType . ToString ( ) ) ;
return CreateNamespacedIDFromString ( ParameterInterfaceInputNamespaceGuid , NameToHash ) ;
}
FGuid FClassIDGenerator : : CreateOutputID ( const FMetasoundFrontendClassOutput & Output ) const
{
const FGuid ClassOutputNamespaceGuid = FGuid ( " {C7B3ED2C-4407-4B2A-9144-7F1108387EBB} " ) ;
FString NameToHash = FString : : Printf ( TEXT ( " ClassOutput.%s.%s.%s " ) , * Output . Name . ToString ( ) , * Output . TypeName . ToString ( ) , LexToString ( Output . AccessType ) ) ;
return CreateNamespacedIDFromString ( ClassOutputNamespaceGuid , NameToHash ) ;
}
FGuid FClassIDGenerator : : CreateOutputID ( const Audio : : FParameterInterface : : FOutput & Output ) const
{
const FGuid ParameterInterfaceOutputNamespaceGuid = FGuid ( " {6F41342A-2436-4462-81A0-8517887BB729} " ) ;
FString NameToHash = FString : : Printf ( TEXT ( " ParameterInterfaceOutput.%s.%s " ) , * Output . ParamName . ToString ( ) , * Output . DataType . ToString ( ) ) ;
return CreateNamespacedIDFromString ( ParameterInterfaceOutputNamespaceGuid , NameToHash ) ;
}
2023-08-21 12:25:01 -04:00
FGuid FClassIDGenerator : : CreateNamespacedIDFromString ( const FGuid NamespaceGuid , const FString & StringToHash ) const
2023-06-20 13:12:39 -04:00
{
FSHA1 Hasher ;
Hasher . Update ( reinterpret_cast < const uint8 * > ( & NamespaceGuid ) , sizeof ( FGuid ) ) ;
Hasher . UpdateWithString ( * StringToHash , StringToHash . Len ( ) ) ;
FSHAHash HashValue = Hasher . Finalize ( ) ;
const uint32 * HashUint32 = reinterpret_cast < const uint32 * > ( HashValue . Hash ) ;
return FGuid ( HashUint32 [ 0 ] , HashUint32 [ 1 ] , HashUint32 [ 2 ] , HashUint32 [ 3 ] ) ;
}
2023-10-16 18:42:49 -04:00
FGuid CreateLocallyUniqueId ( )
{
uint64 NextId = GlobalAtomicMetasoundIdCounter . fetch_add ( 1 , std : : memory_order_relaxed ) ;
return FGuid ( 0 , 0 , NextId > > 32 , NextId & 0xFFFFFFFF ) ;
}
2023-06-20 13:12:39 -04:00
}
}