2020-07-17 16:43:42 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "MetasoundAssetBase.h"
2020-12-14 15:48:27 -04:00
# include "Algo/AnyOf.h"
2022-03-01 16:31:55 -05:00
# include "Algo/ForEach.h"
2021-06-16 11:21:13 -04:00
# include "Algo/Transform.h"
2021-09-16 14:46:43 -04:00
# include "Containers/Set.h"
2020-07-21 14:34:07 -04:00
# include "HAL/FileManager.h"
2021-11-22 15:55:50 -05:00
# include "IAudioParameterTransmitter.h"
2021-06-08 10:52:31 -04:00
# include "Internationalization/Text.h"
2020-07-17 16:43:42 -04:00
# include "IStructSerializerBackend.h"
2021-07-27 15:36:03 -04:00
# include "Logging/LogMacros.h"
2020-12-14 15:48:27 -04:00
# include "MetasoundArchetype.h"
2021-11-07 23:43:01 -05:00
# include "MetasoundAssetManager.h"
2021-06-23 20:08:21 -04:00
# include "MetasoundFrontendArchetypeRegistry.h"
2021-01-13 10:48:59 -04:00
# include "MetasoundFrontendController.h"
2021-07-12 16:13:03 -04:00
# include "MetasoundFrontendDocument.h"
2021-06-08 10:52:31 -04:00
# include "MetasoundFrontendGraph.h"
2021-07-28 17:12:57 -04:00
# include "MetasoundFrontendInjectReceiveNodes.h"
2021-08-18 15:16:57 -04:00
# include "MetasoundFrontendRegistries.h"
2021-06-08 10:52:31 -04:00
# include "MetasoundFrontendSearchEngine.h"
2021-01-13 10:48:59 -04:00
# include "MetasoundFrontendTransform.h"
2020-12-14 15:48:27 -04:00
# include "MetasoundJsonBackend.h"
2021-01-13 10:48:59 -04:00
# include "MetasoundLog.h"
2021-08-30 14:08:45 -04:00
# include "MetasoundParameterTransmitter.h"
2021-08-11 15:22:01 -04:00
# include "MetasoundTrace.h"
2021-09-13 14:14:37 -04:00
# include "MetasoundVertex.h"
2020-07-17 16:43:42 -04:00
# include "StructSerializer.h"
2021-06-16 11:21:13 -04:00
# include "UObject/MetaData.h"
2020-07-17 16:43:42 -04:00
2021-06-08 10:52:31 -04:00
# define LOCTEXT_NAMESPACE "MetaSound"
2021-06-16 11:21:13 -04:00
namespace Metasound
{
2022-05-10 16:51:39 -04:00
namespace Frontend
2021-07-27 15:36:03 -04:00
{
2022-05-10 16:51:39 -04:00
namespace AssetBasePrivate
2021-07-27 15:36:03 -04:00
{
2022-05-10 16:51:39 -04:00
static float BlockRate = 100.f ;
2021-07-27 15:36:03 -04:00
2022-05-10 16:51:39 -04:00
void DepthFirstTraversal ( const FMetasoundAssetBase & InInitAsset , TFunctionRef < TSet < const FMetasoundAssetBase * > ( const FMetasoundAssetBase & ) > InVisitFunction )
2021-07-27 15:36:03 -04:00
{
2022-05-10 16:51:39 -04:00
// Non recursive depth first traversal.
TArray < const FMetasoundAssetBase * > Stack ( { & InInitAsset } ) ;
TSet < const FMetasoundAssetBase * > Visited ;
2021-07-27 15:36:03 -04:00
2022-05-10 16:51:39 -04:00
while ( ! Stack . IsEmpty ( ) )
{
const FMetasoundAssetBase * CurrentNode = Stack . Pop ( ) ;
if ( ! Visited . Contains ( CurrentNode ) )
{
TArray < const FMetasoundAssetBase * > Children = InVisitFunction ( * CurrentNode ) . Array ( ) ;
Stack . Append ( Children ) ;
Visited . Add ( CurrentNode ) ;
}
2021-07-27 15:36:03 -04:00
}
}
2022-05-10 16:51:39 -04:00
} // namespace AssetBasePrivate
FAutoConsoleVariableRef CVarMetaSoundBlockRate (
TEXT ( " au.MetaSound.BlockRate " ) ,
AssetBasePrivate : : BlockRate ,
TEXT ( " Sets block rate (blocks per second) of MetaSounds. \n " )
TEXT ( " Default: 100.0f, Min: 1.0f, Max: 1000.0f " ) ,
ECVF_Default ) ;
float GetDefaultBlockRate ( )
{
return FMath : : Clamp ( AssetBasePrivate : : BlockRate , 1.0f , 1000.0f ) ;
2021-07-27 15:36:03 -04:00
}
2022-05-10 16:51:39 -04:00
} // namespace Frontend
2021-06-16 11:21:13 -04:00
} // namespace Metasound
2020-07-23 16:39:56 -04:00
const FString FMetasoundAssetBase : : FileExtension ( TEXT ( " .metasound " ) ) ;
2021-11-07 23:43:01 -05:00
void FMetasoundAssetBase : : RegisterGraphWithFrontend ( Metasound : : Frontend : : FMetaSoundAssetRegistrationOptions InRegistrationOptions )
2020-07-23 16:39:56 -04:00
{
2021-06-08 10:52:31 -04:00
using namespace Metasound ;
using namespace Metasound : : Frontend ;
2020-07-23 16:39:56 -04:00
2021-08-11 15:22:01 -04:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( MetaSoundAssetBase : : RegisterGraphWithFrontend ) ;
2021-08-18 15:16:57 -04:00
if ( ! InRegistrationOptions . bForceReregister )
2021-06-08 10:52:31 -04:00
{
2021-08-18 15:16:57 -04:00
if ( IsRegistered ( ) )
{
return ;
}
}
2021-09-16 14:46:43 -04:00
// Triggers the existing runtime data to be out-of-date.
CurrentCachedRuntimeDataChangeID = FGuid : : NewGuid ( ) ;
2021-08-18 15:16:57 -04:00
2021-11-07 23:43:01 -05:00
if ( InRegistrationOptions . bRegisterDependencies )
{
// Must be called in case register is called prior to asset scan being completed
2021-12-10 20:37:31 -05:00
// or in certain cases where asset is being loaded for first time.
2021-11-07 23:43:01 -05:00
IMetaSoundAssetManager : : GetChecked ( ) . AddAssetReferences ( * this ) ;
}
2021-08-18 15:16:57 -04:00
if ( InRegistrationOptions . bRebuildReferencedAssetClassKeys )
{
2022-01-21 15:40:14 -05:00
RebuildReferencedAssetClassKeys ( ) ;
2021-08-18 15:16:57 -04:00
}
if ( InRegistrationOptions . bRegisterDependencies )
{
2021-11-07 23:43:01 -05:00
TArray < FMetasoundAssetBase * > References ;
ensureAlways ( IMetaSoundAssetManager : : GetChecked ( ) . TryLoadReferencedAssets ( * this , References ) ) ;
GetReferencedAssetClassCache ( ) . Reset ( ) ;
2021-08-18 15:16:57 -04:00
for ( FMetasoundAssetBase * Reference : References )
{
if ( InRegistrationOptions . bForceReregister | | ! Reference - > IsRegistered ( ) )
{
// TODO: Check for infinite recursion and error if so
Reference - > RegisterGraphWithFrontend ( InRegistrationOptions ) ;
}
if ( UObject * RefAsset = Reference - > GetOwningAsset ( ) )
{
GetReferencedAssetClassCache ( ) . Add ( RefAsset ) ;
}
}
}
// Auto update must be done after all referenced asset classes are registered
if ( InRegistrationOptions . bAutoUpdate )
{
2022-01-18 18:06:06 -05:00
FString OwningAssetName = GetOwningAssetName ( ) ;
2022-03-01 21:25:04 -05:00
const bool bAutoUpdated = FAutoUpdateRootGraph ( MoveTemp ( OwningAssetName ) , InRegistrationOptions . bAutoUpdateLogWarningOnDroppedConnection ) . Transform ( GetDocumentHandle ( ) ) ;
2022-02-10 18:36:26 -05:00
# if WITH_EDITOR
2022-02-02 02:19:16 -05:00
if ( bAutoUpdated | | InRegistrationOptions . bForceViewSynchronization )
{
SetSynchronizationRequired ( ) ;
}
2022-02-10 18:36:26 -05:00
# endif // WITH_EDITOR
2022-02-02 02:19:16 -05:00
}
else
{
2022-02-10 18:36:26 -05:00
# if WITH_EDITOR
2022-02-02 02:19:16 -05:00
if ( InRegistrationOptions . bForceViewSynchronization )
2022-01-18 18:06:06 -05:00
{
2021-11-18 14:37:34 -05:00
SetSynchronizationRequired ( ) ;
}
2022-02-10 18:36:26 -05:00
# endif // WITH_EDITOR
2021-06-08 10:52:31 -04:00
}
2022-02-10 18:36:26 -05:00
# if WITH_EDITOR
2022-01-20 19:19:55 -05:00
// 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.
2022-01-26 18:11:52 -05:00
CacheRegistryMetadata ( ) ;
2022-02-10 18:36:26 -05:00
# endif // WITH_EDITOR
2022-01-20 19:19:55 -05:00
2021-06-14 16:46:19 -04:00
// Registers node by copying document. Updates to document require re-registration.
class FNodeRegistryEntry : public INodeRegistryEntry
2021-06-08 10:52:31 -04:00
{
2021-06-14 16:46:19 -04:00
public :
2021-06-16 11:21:13 -04:00
FNodeRegistryEntry ( const FString & InName , const FMetasoundFrontendDocument & InDocument , FName InAssetPath )
2021-06-14 16:46:19 -04:00
: Name ( InName )
, Document ( InDocument )
2021-06-08 10:52:31 -04:00
{
2021-06-14 16:46:19 -04:00
// Copy frontend class to preserve original document.
FrontendClass = Document . RootGraph ;
2021-07-27 15:36:03 -04:00
FrontendClass . Metadata . SetType ( EMetasoundFrontendClassType : : External ) ;
2021-06-16 11:21:13 -04:00
ClassInfo = FNodeClassInfo ( Document . RootGraph , InAssetPath ) ;
2021-06-08 10:52:31 -04:00
}
2021-06-14 16:46:19 -04:00
virtual ~ FNodeRegistryEntry ( ) = default ;
virtual const FNodeClassInfo & GetClassInfo ( ) const override
{
return ClassInfo ;
}
2021-09-07 17:07:54 -04:00
virtual TUniquePtr < INode > CreateNode ( const FNodeInitData & ) const override
2021-06-14 16:46:19 -04:00
{
2022-03-04 04:25:00 -05:00
return FFrontendGraphBuilder ( ) . CreateGraph ( Document , Name ) ;
2021-06-14 16:46:19 -04:00
}
virtual TUniquePtr < INode > CreateNode ( FDefaultLiteralNodeConstructorParams & & ) const override
{
return nullptr ;
}
2021-09-07 17:07:54 -04:00
virtual TUniquePtr < INode > CreateNode ( FDefaultNamedVertexNodeConstructorParams & & ) const override
2021-06-14 16:46:19 -04:00
{
2021-09-07 17:07:54 -04:00
return nullptr ;
2021-06-14 16:46:19 -04:00
}
2021-09-07 17:07:54 -04:00
virtual TUniquePtr < INode > CreateNode ( FDefaultNamedVertexWithLiteralNodeConstructorParams & & ) const override
{
return nullptr ;
}
2021-06-14 16:46:19 -04:00
virtual const FMetasoundFrontendClass & GetFrontendClass ( ) const override
{
return FrontendClass ;
}
virtual TUniquePtr < INodeRegistryEntry > Clone ( ) const override
{
2021-06-16 11:21:13 -04:00
return MakeUnique < FNodeRegistryEntry > ( Name , Document , ClassInfo . AssetPath ) ;
2021-06-14 16:46:19 -04:00
}
2021-07-27 15:36:03 -04:00
virtual bool IsNative ( ) const override
{
return false ;
}
2021-06-14 16:46:19 -04:00
private :
FString Name ;
FMetasoundFrontendDocument Document ;
FMetasoundFrontendClass FrontendClass ;
FNodeClassInfo ClassInfo ;
2021-06-08 10:52:31 -04:00
} ;
2021-07-27 15:36:03 -04:00
UnregisterGraphWithFrontend ( ) ;
2021-06-08 10:52:31 -04:00
2021-08-18 15:16:57 -04:00
FString AssetName ;
FString AssetPath ;
const UObject * OwningAsset = GetOwningAsset ( ) ;
if ( ensure ( OwningAsset ) )
{
AssetName = OwningAsset - > GetName ( ) ;
AssetPath = OwningAsset - > GetPathName ( ) ;
}
2021-07-27 15:36:03 -04:00
FNodeClassInfo AssetClassInfo = GetAssetClassInfo ( ) ;
2021-08-18 15:16:57 -04:00
const FMetasoundFrontendDocument * Doc = GetDocument ( ) . Get ( ) ;
if ( Doc )
2021-06-16 11:21:13 -04:00
{
2021-07-27 15:36:03 -04:00
RegistryKey = FMetasoundFrontendRegistryContainer : : Get ( ) - > RegisterNode ( MakeUnique < FNodeRegistryEntry > ( AssetName , * Doc , AssetClassInfo . AssetPath ) ) ;
}
2021-06-16 11:21:13 -04:00
2022-04-25 16:59:41 -04:00
if ( NodeRegistryKey : : IsValid ( RegistryKey ) & & FMetasoundFrontendRegistryContainer : : Get ( ) - > IsNodeRegistered ( RegistryKey ) )
2021-06-16 11:21:13 -04:00
{
# if WITH_EDITORONLY_DATA
// Refresh Asset Registry Info if successfully registered with Frontend
2021-07-27 15:36:03 -04:00
const FMetasoundFrontendGraphClass & DocumentClassGraph = GetDocumentHandle ( ) - > GetRootGraphClass ( ) ;
const FMetasoundFrontendClassMetadata & DocumentClassMetadata = DocumentClassGraph . Metadata ;
AssetClassInfo . AssetClassID = FGuid ( DocumentClassMetadata . GetClassName ( ) . Name . ToString ( ) ) ;
FNodeClassName ClassName = DocumentClassMetadata . GetClassName ( ) . ToNodeClassName ( ) ;
2021-06-16 11:21:13 -04:00
FMetasoundFrontendClass GraphClass ;
2021-07-27 15:36:03 -04:00
AssetClassInfo . Version = DocumentClassMetadata . GetVersion ( ) ;
2021-06-16 11:21:13 -04:00
2021-07-27 15:36:03 -04:00
AssetClassInfo . InputTypes . Reset ( ) ;
Algo : : Transform ( GraphClass . Interface . Inputs , AssetClassInfo . InputTypes , [ ] ( const FMetasoundFrontendClassInput & Input ) { return Input . TypeName ; } ) ;
2021-06-16 11:21:13 -04:00
2021-07-27 15:36:03 -04:00
AssetClassInfo . OutputTypes . Reset ( ) ;
Algo : : Transform ( GraphClass . Interface . Outputs , AssetClassInfo . OutputTypes , [ ] ( const FMetasoundFrontendClassOutput & Output ) { return Output . TypeName ; } ) ;
2021-06-16 11:21:13 -04:00
2021-07-27 15:36:03 -04:00
SetRegistryAssetClassInfo ( MoveTemp ( AssetClassInfo ) ) ;
2021-06-16 11:21:13 -04:00
# endif // WITH_EDITORONLY_DATA
}
else
2021-06-08 10:52:31 -04:00
{
2021-08-18 15:16:57 -04:00
FString ClassName ;
if ( OwningAsset )
{
if ( UClass * Class = OwningAsset - > GetClass ( ) )
{
ClassName = Class - > GetName ( ) ;
}
}
UE_LOG ( LogMetaSound , Error , TEXT ( " Registration failed for MetaSound node class '%s' of UObject class '%s' " ) , * AssetName , * ClassName ) ;
2021-06-08 10:52:31 -04:00
}
2020-07-23 16:39:56 -04:00
}
2021-07-27 15:36:03 -04:00
void FMetasoundAssetBase : : UnregisterGraphWithFrontend ( )
{
using namespace Metasound : : Frontend ;
2021-08-11 15:22:01 -04:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( MetaSoundAssetBase : : UnregisterGraphWithFrontend ) ;
2021-07-27 15:36:03 -04:00
if ( ! NodeRegistryKey : : IsValid ( RegistryKey ) )
{
return ;
}
const UObject * OwningAsset = GetOwningAsset ( ) ;
if ( ! ensureAlways ( OwningAsset ) )
{
return ;
}
ensureAlways ( FMetasoundFrontendRegistryContainer : : Get ( ) - > UnregisterNode ( RegistryKey ) ) ;
RegistryKey = FNodeRegistryKey ( ) ;
}
2021-01-13 10:48:59 -04:00
void FMetasoundAssetBase : : SetMetadata ( FMetasoundFrontendClassMetadata & InMetadata )
2020-07-17 16:43:42 -04:00
{
2021-01-13 10:48:59 -04:00
FMetasoundFrontendDocument & Doc = GetDocumentChecked ( ) ;
Doc . RootGraph . Metadata = InMetadata ;
2021-07-27 15:36:03 -04:00
if ( Doc . RootGraph . Metadata . GetType ( ) ! = EMetasoundFrontendClassType : : Graph )
2021-01-13 10:48:59 -04:00
{
2021-04-02 03:03:27 -04:00
UE_LOG ( LogMetaSound , Display , TEXT ( " Forcing class type to EMetasoundFrontendClassType::Graph on root graph metadata " ) ) ;
2021-07-27 15:36:03 -04:00
Doc . RootGraph . Metadata . SetType ( EMetasoundFrontendClassType : : Graph ) ;
2021-01-13 10:48:59 -04:00
}
2020-07-17 16:43:42 -04:00
}
2021-11-22 15:55:50 -05:00
bool FMetasoundAssetBase : : GetDeclaredInterfaces ( TArray < const Metasound : : Frontend : : IInterfaceRegistryEntry * > & OutInterfaces ) const
2021-07-28 17:12:57 -04:00
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
2021-11-22 15:55:50 -05:00
if ( const FMetasoundFrontendDocument * Document = GetDocument ( ) . Get ( ) )
2021-07-28 17:12:57 -04:00
{
2021-11-22 15:55:50 -05:00
bool bInterfacesFound = true ;
2021-07-28 17:12:57 -04:00
2021-12-10 20:37:31 -05:00
Algo : : Transform ( Document - > Interfaces , OutInterfaces , [ & ] ( const FMetasoundFrontendVersion & Version )
2021-07-28 17:12:57 -04:00
{
2021-11-22 15:55:50 -05:00
const FInterfaceRegistryKey InterfaceKey = GetInterfaceRegistryKey ( Version ) ;
const IInterfaceRegistryEntry * RegistryEntry = IInterfaceRegistry : : Get ( ) . FindInterfaceRegistryEntry ( InterfaceKey ) ;
if ( ! RegistryEntry )
{
bInterfacesFound = false ;
UE_LOG ( LogMetaSound , Warning , TEXT ( " No registered interface matching interface version on document [InterfaceVersion:%s] " ) , * Version . ToString ( ) ) ;
}
return RegistryEntry ;
} ) ;
return bInterfacesFound ;
2021-07-28 17:12:57 -04:00
}
2021-11-22 15:55:50 -05:00
return false ;
}
2021-12-10 20:37:31 -05:00
bool FMetasoundAssetBase : : IsInterfaceDeclared ( const FMetasoundFrontendVersion & InVersion ) const
2021-11-22 15:55:50 -05:00
{
2021-12-10 20:37:31 -05:00
return GetDocumentChecked ( ) . Interfaces . Contains ( InVersion ) ;
2021-07-28 17:12:57 -04:00
}
2021-06-08 10:52:31 -04:00
void FMetasoundAssetBase : : SetDocument ( const FMetasoundFrontendDocument & InDocument )
2020-12-14 15:48:27 -04:00
{
2021-01-13 10:48:59 -04:00
FMetasoundFrontendDocument & Document = GetDocumentChecked ( ) ;
2020-07-23 20:32:26 -04:00
Document = InDocument ;
2021-06-23 20:08:21 -04:00
MarkMetasoundDocumentDirty ( ) ;
2020-07-23 20:32:26 -04:00
}
2021-11-22 15:55:50 -05:00
void FMetasoundAssetBase : : AddDefaultInterfaces ( )
2020-07-23 20:32:26 -04:00
{
2021-11-22 15:55:50 -05:00
using namespace Metasound : : Frontend ;
2021-02-01 15:59:27 -04:00
2021-11-22 15:55:50 -05:00
UObject * OwningAsset = GetOwningAsset ( ) ;
check ( OwningAsset ) ;
2021-06-23 20:08:21 -04:00
2021-11-22 15:55:50 -05:00
UClass * AssetClass = OwningAsset - > GetClass ( ) ;
check ( AssetClass ) ;
FDocumentHandle DocumentHandle = GetDocumentHandle ( ) ;
TArray < FMetasoundFrontendInterface > InitInterfaces = ISearchEngine : : Get ( ) . FindUClassDefaultInterfaces ( AssetClass - > GetFName ( ) ) ;
FModifyRootGraphInterfaces ( { } , InitInterfaces ) . Transform ( DocumentHandle ) ;
2021-06-23 20:08:21 -04:00
}
2021-08-18 15:16:57 -04:00
bool FMetasoundAssetBase : : VersionAsset ( )
2021-06-23 20:08:21 -04:00
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
2021-08-11 15:22:01 -04:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( MetaSoundAssetBase : : VersionAsset ) ;
2021-06-23 20:08:21 -04:00
FName AssetName ;
FString AssetPath ;
if ( const UObject * OwningAsset = GetOwningAsset ( ) )
{
AssetName = FName ( OwningAsset - > GetName ( ) ) ;
AssetPath = OwningAsset - > GetPathName ( ) ;
}
2021-11-22 15:55:50 -05:00
FMetasoundFrontendDocument * Doc = GetDocument ( ) . Get ( ) ;
if ( ! ensure ( Doc ) )
2021-06-23 20:08:21 -04:00
{
2021-11-22 15:55:50 -05:00
return false ;
}
2021-12-10 20:37:31 -05:00
bool bDidEdit = Doc - > VersionInterfaces ( ) ;
2021-11-22 15:55:50 -05:00
// Version Document Model
2021-12-10 20:37:31 -05:00
FDocumentHandle DocHandle = GetDocumentHandle ( ) ;
2021-11-22 15:55:50 -05:00
{
bDidEdit | = FVersionDocument ( AssetName , AssetPath ) . Transform ( DocHandle ) ;
}
2021-12-16 19:59:03 -05:00
// Version Interfaces. Has to be re-run until no pass reports an update in case
// versions fork (ex. an interface splits into two newly named interfaces).
2021-11-22 15:55:50 -05:00
{
bool bInterfaceUpdated = false ;
2021-12-16 19:59:03 -05:00
bool bPassUpdated = true ;
while ( bPassUpdated )
2021-08-18 15:16:57 -04:00
{
2021-12-16 19:59:03 -05:00
bPassUpdated = false ;
const TArray < FMetasoundFrontendVersion > Versions = Doc - > Interfaces . Array ( ) ;
for ( const FMetasoundFrontendVersion & Version : Versions )
{
bPassUpdated | = FUpdateRootGraphInterface ( Version ) . Transform ( DocHandle ) ;
}
bInterfaceUpdated | = bPassUpdated ;
2021-08-18 15:16:57 -04:00
}
2021-12-16 19:59:03 -05:00
2021-11-22 15:55:50 -05:00
if ( bInterfaceUpdated )
{
ConformObjectDataToInterfaces ( ) ;
}
bDidEdit | = bInterfaceUpdated ;
2021-06-23 20:08:21 -04:00
}
2021-07-27 15:36:03 -04:00
return bDidEdit ;
2021-02-01 15:59:27 -04:00
}
2022-02-10 18:36:26 -05:00
# if WITH_EDITOR
2022-01-26 18:11:52 -05:00
void FMetasoundAssetBase : : CacheRegistryMetadata ( )
{
using namespace Metasound : : Frontend ;
FMetasoundFrontendDocument * Document = GetDocument ( ) . Get ( ) ;
if ( ! ensure ( Document ) )
{
return ;
}
using FNameDataTypePair = TPair < FName , FName > ;
const TSet < FMetasoundFrontendVersion > & InterfaceVersions = Document - > Interfaces ;
FMetasoundFrontendClassInterface & RootGraphClassInterface = Document - > RootGraph . Interface ;
// 1. Gather inputs/outputs managed by interfaces
TMap < FNameDataTypePair , FMetasoundFrontendClassInput * > Inputs ;
for ( FMetasoundFrontendClassInput & Input : RootGraphClassInterface . Inputs )
{
FNameDataTypePair NameDataTypePair = FNameDataTypePair ( Input . Name , Input . TypeName ) ;
Inputs . Add ( MoveTemp ( NameDataTypePair ) , & Input ) ;
}
TMap < FNameDataTypePair , FMetasoundFrontendClassOutput * > Outputs ;
for ( FMetasoundFrontendClassOutput & Output : RootGraphClassInterface . Outputs )
{
FNameDataTypePair NameDataTypePair = FNameDataTypePair ( Output . Name , Output . TypeName ) ;
Outputs . Add ( MoveTemp ( NameDataTypePair ) , & Output ) ;
}
// 2. Copy metadata for inputs/outputs managed by interfaces, removing them from maps generated
2022-03-01 16:31:55 -05:00
auto CacheInterfaceMetadata = [ ] ( const FMetasoundFrontendVertexMetadata & InRegistryMetadata , FMetasoundFrontendVertexMetadata & OutMetadata )
{
const int32 CachedSortOrderIndex = OutMetadata . SortOrderIndex ;
OutMetadata = InRegistryMetadata ;
OutMetadata . SortOrderIndex = CachedSortOrderIndex ;
} ;
2022-01-26 18:11:52 -05:00
for ( const FMetasoundFrontendVersion & Version : InterfaceVersions )
{
const FInterfaceRegistryKey InterfaceKey = GetInterfaceRegistryKey ( Version ) ;
const IInterfaceRegistryEntry * Entry = IInterfaceRegistry : : Get ( ) . FindInterfaceRegistryEntry ( InterfaceKey ) ;
if ( ensure ( Entry ) )
{
for ( const FMetasoundFrontendClassInput & InterfaceInput : Entry - > GetInterface ( ) . Inputs )
{
const FNameDataTypePair NameDataTypePair = FNameDataTypePair ( InterfaceInput . Name , InterfaceInput . TypeName ) ;
if ( FMetasoundFrontendClassInput * Input = Inputs . FindRef ( NameDataTypePair ) )
{
2022-03-01 16:31:55 -05:00
CacheInterfaceMetadata ( InterfaceInput . Metadata , Input - > Metadata ) ;
2022-01-26 18:11:52 -05:00
Inputs . Remove ( NameDataTypePair ) ;
}
}
for ( const FMetasoundFrontendClassOutput & InterfaceOutput : Entry - > GetInterface ( ) . Outputs )
{
const FNameDataTypePair NameDataTypePair = FNameDataTypePair ( InterfaceOutput . Name , InterfaceOutput . TypeName ) ;
if ( FMetasoundFrontendClassOutput * Output = Outputs . FindRef ( NameDataTypePair ) )
{
2022-03-01 16:31:55 -05:00
CacheInterfaceMetadata ( InterfaceOutput . Metadata , Output - > Metadata ) ;
2022-01-26 18:11:52 -05:00
Outputs . Remove ( NameDataTypePair ) ;
}
}
}
}
// 3. Iterate remaining inputs/outputs not managed by interfaces and set to serialize text
// (in case they were orphaned by an interface no longer being implemented).
for ( TPair < FNameDataTypePair , FMetasoundFrontendClassInput * > & Pair : Inputs )
{
Pair . Value - > Metadata . SetSerializeText ( true ) ;
}
for ( TPair < FNameDataTypePair , FMetasoundFrontendClassOutput * > & Pair : Outputs )
{
Pair . Value - > Metadata . SetSerializeText ( true ) ;
}
2022-03-01 16:31:55 -05:00
// 4. Refresh style as order of members could've changed
{
FMetasoundFrontendInterfaceStyle InputStyle ;
Algo : : ForEach ( RootGraphClassInterface . Inputs , [ & InputStyle ] ( const FMetasoundFrontendClassInput & Input )
{
InputStyle . DefaultSortOrder . Add ( Input . Metadata . SortOrderIndex ) ;
} ) ;
RootGraphClassInterface . SetInputStyle ( InputStyle ) ;
}
{
FMetasoundFrontendInterfaceStyle OutputStyle ;
Algo : : ForEach ( RootGraphClassInterface . Outputs , [ & OutputStyle ] ( const FMetasoundFrontendClassOutput & Output )
{
OutputStyle . DefaultSortOrder . Add ( Output . Metadata . SortOrderIndex ) ;
} ) ;
RootGraphClassInterface . SetOutputStyle ( OutputStyle ) ;
}
// 5. Cache registry data on document dependencies
2022-01-27 01:31:46 -05:00
for ( FMetasoundFrontendClass & Dependency : Document - > Dependencies )
2022-01-26 18:11:52 -05:00
{
2022-01-27 01:31:46 -05:00
if ( ! FMetasoundFrontendClass : : CacheGraphDependencyMetadataFromRegistry ( Dependency ) )
2022-01-26 18:11:52 -05:00
{
UE_LOG ( LogMetaSound , Warning ,
TEXT ( " '%s' failed to cache dependency registry data: Registry missing class with key '%s' " ) ,
* GetOwningAssetName ( ) ,
2022-01-27 01:31:46 -05:00
* Dependency . Metadata . GetClassName ( ) . ToString ( ) ) ;
2022-01-26 18:11:52 -05:00
UE_LOG ( LogMetaSound , Warning ,
TEXT ( " Asset '%s' may fail to build runtime graph unless re-registered after dependency with given key is loaded. " ) ,
* GetOwningAssetName ( ) ) ;
}
}
}
2021-12-13 18:15:01 -05:00
bool FMetasoundAssetBase : : GetSynchronizationRequired ( ) const
2021-11-18 14:37:34 -05:00
{
return bSynchronizationRequired ;
}
2021-12-13 18:15:01 -05:00
bool FMetasoundAssetBase : : GetSynchronizationUpdateDetails ( ) const
2021-11-22 15:55:50 -05:00
{
2021-12-13 18:15:01 -05:00
return bSynchronizationUpdateDetails ;
2021-11-22 15:55:50 -05:00
}
2021-11-18 14:37:34 -05:00
void FMetasoundAssetBase : : SetSynchronizationRequired ( )
{
bSynchronizationRequired = true ;
}
2021-12-13 18:15:01 -05:00
void FMetasoundAssetBase : : SetUpdateDetailsOnSynchronization ( )
2021-11-22 15:55:50 -05:00
{
2021-12-13 18:15:01 -05:00
bSynchronizationUpdateDetails = true ;
bSynchronizationRequired = true ;
2021-11-22 15:55:50 -05:00
}
2021-11-18 14:37:34 -05:00
void FMetasoundAssetBase : : ResetSynchronizationState ( )
{
2021-12-13 18:15:01 -05:00
bSynchronizationUpdateDetails = false ;
2021-11-18 14:37:34 -05:00
bSynchronizationRequired = false ;
}
2022-02-10 18:36:26 -05:00
# endif // WITH_EDITOR
2021-11-18 14:37:34 -05:00
2022-03-10 22:07:08 -05:00
TSharedPtr < Metasound : : IGraph , ESPMode : : ThreadSafe > FMetasoundAssetBase : : BuildMetasoundDocument ( const TArray < FMetasoundFrontendClassInput > & InTransmittableInputs ) const
2021-06-08 10:52:31 -04:00
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
2021-08-11 15:22:01 -04:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( MetaSoundAssetBase : : BuildMetasoundDocument ) ;
2022-03-04 04:25:00 -05:00
// Create graph which can spawn instances.
TUniquePtr < FFrontendGraph > FrontendGraph = FFrontendGraphBuilder : : CreateGraph ( GetDocumentChecked ( ) , GetOwningAssetName ( ) ) ;
2021-07-28 17:12:57 -04:00
if ( FrontendGraph . IsValid ( ) )
{
2021-11-22 15:55:50 -05:00
TSet < FVertexName > TransmittableInputNames ;
2022-03-10 22:07:08 -05:00
Algo : : Transform ( InTransmittableInputs , TransmittableInputNames , [ ] ( const FMetasoundFrontendClassInput & Input ) { return Input . Name ; } ) ;
2021-11-22 15:55:50 -05:00
bool bSuccessfullyInjectedReceiveNodes = InjectReceiveNodes ( * FrontendGraph , FMetaSoundParameterTransmitter : : CreateSendAddressFromEnvironment , TransmittableInputNames ) ;
2021-07-28 17:12:57 -04:00
if ( ! bSuccessfullyInjectedReceiveNodes )
2021-06-08 10:52:31 -04:00
{
2021-07-28 17:12:57 -04:00
UE_LOG ( LogMetaSound , Error , TEXT ( " Error while injecting async communication hooks. Instance communication may not function properly [Name:%s]. " ) , * GetOwningAssetName ( ) ) ;
2021-06-08 10:52:31 -04:00
}
}
2022-03-04 04:25:00 -05:00
else
{
UE_LOG ( LogMetaSound , Error , TEXT ( " Failed to build MetaSound graph in asset '%s' " ) , * GetOwningAssetName ( ) ) ;
}
2021-06-08 10:52:31 -04:00
2021-09-16 14:46:43 -04:00
TSharedPtr < Metasound : : IGraph , ESPMode : : ThreadSafe > SharedGraph ( FrontendGraph . Release ( ) ) ;
return SharedGraph ;
2021-06-08 10:52:31 -04:00
}
2021-08-18 15:16:57 -04:00
bool FMetasoundAssetBase : : IsRegistered ( ) const
2021-07-27 15:36:03 -04:00
{
2021-08-18 15:16:57 -04:00
using namespace Metasound : : Frontend ;
if ( ! NodeRegistryKey : : IsValid ( RegistryKey ) )
{
return false ;
}
return FMetasoundFrontendRegistryContainer : : Get ( ) - > IsNodeRegistered ( RegistryKey ) ;
2021-07-27 15:36:03 -04:00
}
2021-11-18 14:37:34 -05:00
bool FMetasoundAssetBase : : IsReferencedAsset ( const FMetasoundAssetBase & InAsset ) const
{
using namespace Metasound : : Frontend ;
bool bIsReferenced = false ;
2022-05-10 16:51:39 -04:00
AssetBasePrivate : : DepthFirstTraversal ( * this , [ & ] ( const FMetasoundAssetBase & ChildAsset )
2021-11-18 14:37:34 -05:00
{
TSet < const FMetasoundAssetBase * > Children ;
if ( & ChildAsset = = & InAsset )
{
bIsReferenced = true ;
return Children ;
}
TArray < FMetasoundAssetBase * > ChildRefs ;
ensureAlways ( IMetaSoundAssetManager : : GetChecked ( ) . TryLoadReferencedAssets ( ChildAsset , ChildRefs ) ) ;
Algo : : Transform ( ChildRefs , Children , [ ] ( FMetasoundAssetBase * Child ) { return Child ; } ) ;
return Children ;
} ) ;
return bIsReferenced ;
}
2021-08-18 15:16:57 -04:00
bool FMetasoundAssetBase : : AddingReferenceCausesLoop ( const FSoftObjectPath & InReferencePath ) const
2021-07-27 15:36:03 -04:00
{
2021-11-07 23:43:01 -05:00
using namespace Metasound : : Frontend ;
2021-08-18 15:16:57 -04:00
const FMetasoundAssetBase * ReferenceAsset = IMetaSoundAssetManager : : GetChecked ( ) . TryLoadAsset ( InReferencePath ) ;
2021-07-27 15:36:03 -04:00
if ( ! ensureAlways ( ReferenceAsset ) )
{
return false ;
}
bool bCausesLoop = false ;
const FMetasoundAssetBase * Parent = this ;
2022-05-10 16:51:39 -04:00
AssetBasePrivate : : DepthFirstTraversal ( * ReferenceAsset , [ & ] ( const FMetasoundAssetBase & ChildAsset )
2021-07-27 15:36:03 -04:00
{
TSet < const FMetasoundAssetBase * > Children ;
if ( Parent = = & ChildAsset )
{
bCausesLoop = true ;
return Children ;
}
2021-11-07 23:43:01 -05:00
TArray < FMetasoundAssetBase * > ChildRefs ;
2021-11-18 14:37:34 -05:00
ensureAlways ( IMetaSoundAssetManager : : GetChecked ( ) . TryLoadReferencedAssets ( ChildAsset , ChildRefs ) ) ;
Algo : : Transform ( ChildRefs , Children , [ ] ( FMetasoundAssetBase * Child ) { return Child ; } ) ;
2021-07-27 15:36:03 -04:00
return Children ;
} ) ;
return bCausesLoop ;
}
2021-09-13 14:14:37 -04:00
Metasound : : FSendAddress FMetasoundAssetBase : : CreateSendAddress ( uint64 InInstanceID , const Metasound : : FVertexName & InVertexName , const FName & InDataTypeName ) const
2021-07-28 17:12:57 -04:00
2021-06-08 10:52:31 -04:00
{
2021-10-12 21:21:22 -04:00
return Metasound : : FSendAddress ( InVertexName , InDataTypeName , InInstanceID ) ;
2021-06-08 10:52:31 -04:00
}
2021-06-16 11:21:13 -04:00
void FMetasoundAssetBase : : ConvertFromPreset ( )
{
using namespace Metasound : : Frontend ;
FGraphHandle GraphHandle = GetRootGraphHandle ( ) ;
2022-02-10 15:07:39 -05:00
# if WITH_EDITOR
2021-06-16 11:21:13 -04:00
FMetasoundFrontendGraphStyle Style = GraphHandle - > GetGraphStyle ( ) ;
Style . bIsGraphEditable = true ;
GraphHandle - > SetGraphStyle ( Style ) ;
2022-02-10 15:07:39 -05:00
# endif // WITH_EDITOR
2021-07-27 15:36:03 -04:00
2022-02-09 12:52:07 -05:00
FMetasoundFrontendGraphClassPresetOptions PresetOptions = GraphHandle - > GetGraphPresetOptions ( ) ;
PresetOptions . bIsPreset = false ;
GraphHandle - > SetGraphPresetOptions ( PresetOptions ) ;
2021-06-16 11:21:13 -04:00
}
2021-06-08 10:52:31 -04:00
TArray < FMetasoundAssetBase : : FSendInfoAndVertexName > FMetasoundAssetBase : : GetSendInfos ( uint64 InInstanceID ) const
{
2021-07-28 17:12:57 -04:00
using namespace Metasound ;
2021-06-08 10:52:31 -04:00
using namespace Metasound : : Frontend ;
2021-08-30 14:08:45 -04:00
using FSendInfo = FMetaSoundParameterTransmitter : : FSendInfo ;
2021-06-08 10:52:31 -04:00
2021-09-16 14:46:43 -04:00
check ( IsInGameThread ( ) | | IsInAudioThread ( ) ) ;
const FRuntimeData & RuntimeData = GetRuntimeData ( ) ;
2022-03-10 22:07:08 -05:00
checkf ( CurrentCachedRuntimeDataChangeID = = RuntimeData . ChangeID , TEXT ( " Asset must have up-to-date cached RuntimeData prior to calling GetSendInfos " ) ) ;
2021-09-16 14:46:43 -04:00
2021-06-08 10:52:31 -04:00
TArray < FSendInfoAndVertexName > SendInfos ;
2021-09-16 14:46:43 -04:00
for ( const FMetasoundFrontendClassInput & Vertex : RuntimeData . TransmittableInputs )
2021-06-08 10:52:31 -04:00
{
2021-09-16 14:46:43 -04:00
FSendInfoAndVertexName Info ;
2021-06-08 10:52:31 -04:00
2021-09-16 14:46:43 -04:00
Info . SendInfo . Address = FMetaSoundParameterTransmitter : : CreateSendAddressFromInstanceID ( InInstanceID , Vertex . Name , Vertex . TypeName ) ;
Info . SendInfo . ParameterName = Vertex . Name ;
Info . SendInfo . TypeName = Vertex . TypeName ;
Info . VertexName = Vertex . Name ;
2021-06-08 10:52:31 -04:00
2021-09-16 14:46:43 -04:00
SendInfos . Add ( Info ) ;
2021-06-08 10:52:31 -04:00
}
return SendInfos ;
}
2021-08-30 14:08:45 -04:00
Metasound : : Frontend : : FNodeHandle FMetasoundAssetBase : : AddInputPinForSendAddress ( const Metasound : : FMetaSoundParameterTransmitter : : FSendInfo & InSendInfo , Metasound : : Frontend : : FGraphHandle InGraph ) const
2021-06-08 10:52:31 -04:00
{
FMetasoundFrontendClassInput Description ;
FGuid VertexID = FGuid : : NewGuid ( ) ;
2021-10-12 21:21:22 -04:00
Description . Name = InSendInfo . Address . GetChannelName ( ) ;
2021-06-08 10:52:31 -04:00
Description . TypeName = Metasound : : GetMetasoundDataTypeName < Metasound : : FSendAddress > ( ) ;
Description . VertexID = VertexID ;
2021-10-12 21:21:22 -04:00
Description . DefaultLiteral . Set ( InSendInfo . Address . GetChannelName ( ) . ToString ( ) ) ;
2021-06-08 10:52:31 -04:00
2022-02-10 15:07:39 -05:00
# if WITH_EDITOR
Description . Metadata . SetDescription ( FText : : GetEmpty ( ) ) ;
# endif // WITH_EDITOR
2021-06-08 10:52:31 -04:00
return InGraph - > AddInputVertex ( Description ) ;
}
2022-02-10 18:36:26 -05:00
# if WITH_EDITOR
2021-06-08 10:52:31 -04:00
FText FMetasoundAssetBase : : GetDisplayName ( FString & & InTypeName ) const
{
using namespace Metasound : : Frontend ;
FConstGraphHandle GraphHandle = GetRootGraphHandle ( ) ;
const bool bIsPreset = ! GraphHandle - > GetGraphStyle ( ) . bIsGraphEditable ;
if ( ! bIsPreset )
{
return FText : : FromString ( MoveTemp ( InTypeName ) ) ;
}
return FText : : Format ( LOCTEXT ( " PresetDisplayNameFormat " , " {0} (Preset) " ) , FText : : FromString ( MoveTemp ( InTypeName ) ) ) ;
}
2022-02-10 18:36:26 -05:00
# endif // WITH_EDITOR
2021-06-08 10:52:31 -04:00
2021-02-01 15:59:27 -04:00
bool FMetasoundAssetBase : : MarkMetasoundDocumentDirty ( ) const
{
if ( const UObject * OwningAsset = GetOwningAsset ( ) )
{
return ensure ( OwningAsset - > MarkPackageDirty ( ) ) ;
}
return false ;
2020-07-23 20:32:26 -04:00
}
2021-01-13 10:48:59 -04:00
Metasound : : Frontend : : FDocumentHandle FMetasoundAssetBase : : GetDocumentHandle ( )
{
return Metasound : : Frontend : : IDocumentController : : CreateDocumentHandle ( GetDocument ( ) ) ;
}
2020-07-17 16:43:42 -04:00
2021-01-13 19:18:22 -04:00
Metasound : : Frontend : : FConstDocumentHandle FMetasoundAssetBase : : GetDocumentHandle ( ) const
{
return Metasound : : Frontend : : IDocumentController : : CreateDocumentHandle ( GetDocument ( ) ) ;
}
2020-12-14 15:48:27 -04:00
Metasound : : Frontend : : FGraphHandle FMetasoundAssetBase : : GetRootGraphHandle ( )
2020-07-17 16:43:42 -04:00
{
2021-01-13 10:48:59 -04:00
return GetDocumentHandle ( ) - > GetRootGraph ( ) ;
2020-07-17 16:43:42 -04:00
}
2021-01-13 19:18:22 -04:00
Metasound : : Frontend : : FConstGraphHandle FMetasoundAssetBase : : GetRootGraphHandle ( ) const
{
return GetDocumentHandle ( ) - > GetRootGraph ( ) ;
}
2020-08-05 12:47:19 -04:00
bool FMetasoundAssetBase : : ImportFromJSON ( const FString & InJSON )
2020-07-23 16:39:56 -04:00
{
2021-08-11 15:22:01 -04:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( MetaSoundAssetBase : : ImportFromJSON ) ;
2021-07-12 16:13:03 -04:00
FMetasoundFrontendDocument * Document = GetDocument ( ) . Get ( ) ;
if ( ensure ( nullptr ! = Document ) )
2020-12-14 15:48:27 -04:00
{
2021-02-01 15:59:27 -04:00
bool bSuccess = Metasound : : Frontend : : ImportJSONToMetasound ( InJSON , * Document ) ;
if ( bSuccess )
{
ensure ( MarkMetasoundDocumentDirty ( ) ) ;
}
return bSuccess ;
2020-12-14 15:48:27 -04:00
}
return false ;
2020-07-23 16:39:56 -04:00
}
2020-08-05 12:47:19 -04:00
bool FMetasoundAssetBase : : ImportFromJSONAsset ( const FString & InAbsolutePath )
2020-07-17 16:43:42 -04:00
{
2021-08-11 15:22:01 -04:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( MetaSoundAssetBase : : ImportFromJSONAsset ) ;
2021-07-12 16:13:03 -04:00
Metasound : : Frontend : : FDocumentAccessPtr DocumentPtr = GetDocument ( ) ;
if ( FMetasoundFrontendDocument * Document = DocumentPtr . Get ( ) )
2020-12-14 15:48:27 -04:00
{
2021-02-01 15:59:27 -04:00
bool bSuccess = Metasound : : Frontend : : ImportJSONAssetToMetasound ( InAbsolutePath , * Document ) ;
if ( bSuccess )
{
ensure ( MarkMetasoundDocumentDirty ( ) ) ;
}
return bSuccess ;
2020-12-14 15:48:27 -04:00
}
return false ;
}
2021-01-13 10:48:59 -04:00
FMetasoundFrontendDocument & FMetasoundAssetBase : : GetDocumentChecked ( )
2020-12-14 15:48:27 -04:00
{
2021-07-12 16:13:03 -04:00
FMetasoundFrontendDocument * Document = GetDocument ( ) . Get ( ) ;
check ( nullptr ! = Document ) ;
return * Document ;
2020-12-14 15:48:27 -04:00
}
2021-01-13 10:48:59 -04:00
const FMetasoundFrontendDocument & FMetasoundAssetBase : : GetDocumentChecked ( ) const
2020-12-14 15:48:27 -04:00
{
2021-07-12 16:13:03 -04:00
const FMetasoundFrontendDocument * Document = GetDocument ( ) . Get ( ) ;
2020-12-14 15:48:27 -04:00
2021-07-12 16:13:03 -04:00
check ( nullptr ! = Document ) ;
return * Document ;
2020-08-05 12:47:19 -04:00
}
2021-07-28 17:12:57 -04:00
FString FMetasoundAssetBase : : GetOwningAssetName ( ) const
{
if ( const UObject * OwningAsset = GetOwningAsset ( ) )
{
2022-01-27 00:45:28 -05:00
return OwningAsset - > GetPathName ( ) ;
2021-07-28 17:12:57 -04:00
}
return FString ( ) ;
}
2022-03-10 22:07:08 -05:00
TArray < FMetasoundFrontendClassInput > FMetasoundAssetBase : : GetTransmittableClassInputs ( ) const
2021-09-16 14:46:43 -04:00
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
2021-11-22 15:55:50 -05:00
2022-03-10 22:07:08 -05:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( FMetasoundAssetBase : : GetTransmittableClassInputs ) ;
2021-09-16 14:46:43 -04:00
check ( IsInGameThread ( ) | | IsInAudioThread ( ) ) ;
2022-03-10 22:07:08 -05:00
TArray < FMetasoundFrontendClassInput > Inputs ;
2021-09-16 14:46:43 -04:00
2021-11-22 15:55:50 -05:00
const FMetasoundFrontendDocument & Doc = GetDocumentChecked ( ) ;
auto GetInputName = [ ] ( const FMetasoundFrontendClassInput & InInput ) { return InInput . Name ; } ;
2021-09-16 14:46:43 -04:00
2021-11-22 15:55:50 -05:00
// Do not transmit vertices defined in interface marked as non-transmittable
TArray < const IInterfaceRegistryEntry * > Interfaces ;
TSet < FVertexName > NonTransmittableInputs ;
GetDeclaredInterfaces ( Interfaces ) ;
for ( const IInterfaceRegistryEntry * InterfaceEntry : Interfaces )
2021-09-16 14:46:43 -04:00
{
2021-11-22 15:55:50 -05:00
if ( InterfaceEntry )
2021-09-16 14:46:43 -04:00
{
2021-11-22 15:55:50 -05:00
if ( InterfaceEntry - > GetRouterName ( ) ! = Audio : : IParameterTransmitter : : RouterName )
2021-09-16 14:46:43 -04:00
{
2021-11-22 15:55:50 -05:00
const FMetasoundFrontendInterface & Interface = InterfaceEntry - > GetInterface ( ) ;
Algo : : Transform ( Interface . Inputs , NonTransmittableInputs , GetInputName ) ;
2021-09-16 14:46:43 -04:00
}
}
}
2021-11-22 15:55:50 -05:00
// Do not transmit vertices which are not transmittable. Async communication
// is not supported without transmission.
IDataTypeRegistry & Registry = IDataTypeRegistry : : Get ( ) ;
auto IsTransmittable = [ & Registry , & NonTransmittableInputs ] ( const FMetasoundFrontendClassVertex & InVertex )
{
2022-07-18 17:14:25 -04:00
// Don't transmit constructor inputs
if ( InVertex . AccessType = = EMetasoundFrontendVertexAccessType : : Reference )
2021-11-22 15:55:50 -05:00
{
2022-07-18 17:14:25 -04:00
if ( ! NonTransmittableInputs . Contains ( InVertex . Name ) )
2021-11-22 15:55:50 -05:00
{
2022-07-18 17:14:25 -04:00
FDataTypeRegistryInfo Info ;
if ( Registry . GetDataTypeInfo ( InVertex . TypeName , Info ) )
{
return Info . bIsTransmittable ;
}
2021-11-22 15:55:50 -05:00
}
}
return false ;
} ;
2022-03-10 22:07:08 -05:00
Algo : : TransformIf ( Doc . RootGraph . Interface . Inputs , Inputs , IsTransmittable , [ ] ( const FMetasoundFrontendClassInput & Input ) { return Input ; } ) ;
2021-11-22 15:55:50 -05:00
2021-09-16 14:46:43 -04:00
return Inputs ;
}
2022-01-21 15:40:14 -05:00
void FMetasoundAssetBase : : RebuildReferencedAssetClassKeys ( )
{
using namespace Metasound : : Frontend ;
TSet < FNodeRegistryKey > ReferencedKeys = IMetaSoundAssetManager : : GetChecked ( ) . GetReferencedKeys ( * this ) ;
SetReferencedAssetClassKeys ( MoveTemp ( ReferencedKeys ) ) ;
}
2022-03-10 22:07:08 -05:00
const FMetasoundAssetBase : : FRuntimeData & FMetasoundAssetBase : : CacheRuntimeData ( )
2021-09-16 14:46:43 -04:00
{
2022-03-10 22:07:08 -05:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( MetaSoundAssetBase : : CacheRuntimeData ) ;
2021-09-16 14:46:43 -04:00
// Check if a ChangeID has been generated before.
if ( ! CurrentCachedRuntimeDataChangeID . IsValid ( ) )
{
CurrentCachedRuntimeDataChangeID = FGuid : : NewGuid ( ) ;
}
// Check if CachedRuntimeData is out-of-date.
if ( CachedRuntimeData . ChangeID ! = CurrentCachedRuntimeDataChangeID )
{
// Update CachedRuntimeData.
2022-03-10 22:07:08 -05:00
TArray < FMetasoundFrontendClassInput > ClassInputs = GetTransmittableClassInputs ( ) ;
TSharedPtr < Metasound : : IGraph , ESPMode : : ThreadSafe > Graph = BuildMetasoundDocument ( ClassInputs ) ;
2021-11-22 15:55:50 -05:00
2022-03-10 22:07:08 -05:00
CachedRuntimeData =
{
CurrentCachedRuntimeDataChangeID ,
MoveTemp ( ClassInputs ) ,
MoveTemp ( Graph )
} ;
2021-09-16 14:46:43 -04:00
}
return CachedRuntimeData ;
}
2022-03-10 22:07:08 -05:00
const FMetasoundAssetBase : : FRuntimeData & FMetasoundAssetBase : : GetRuntimeData ( ) const
{
ensureMsgf ( CurrentCachedRuntimeDataChangeID = = CachedRuntimeData . ChangeID , TEXT ( " Accessing out-of-date runtime data: MetaSound asset '%s'. " ) , * GetOwningAssetName ( ) ) ;
return CachedRuntimeData ;
}
2021-06-08 10:52:31 -04:00
# undef LOCTEXT_NAMESPACE // "MetaSound"