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"
2021-06-16 11:20:44 -04:00
# include "Algo/Transform.h"
2020-07-21 14:34:07 -04:00
# include "HAL/FileManager.h"
2021-06-08 10:52:31 -04:00
# include "Internationalization/Text.h"
2020-07-17 16:43:42 -04:00
# include "IStructSerializerBackend.h"
2020-12-14 15:48:27 -04:00
# include "MetasoundArchetype.h"
2021-06-23 20:07:53 -04:00
# include "MetasoundFrontendArchetypeRegistry.h"
2021-01-13 10:48:59 -04:00
# include "MetasoundFrontendController.h"
2021-07-12 16:12:36 -04:00
# include "MetasoundFrontendDocument.h"
2021-06-08 10:52:31 -04:00
# include "MetasoundFrontendGraph.h"
# 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-06-08 10:52:31 -04:00
# include "MetasoundReceiveNode.h"
2020-07-17 16:43:42 -04:00
# include "StructSerializer.h"
2021-06-16 11:20:44 -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:20:44 -04:00
namespace Metasound
{
namespace AssetTags
{
const FString ArrayDelim = TEXT ( " , " ) ;
const FName AssetClassID = " AssetClassID " ;
const FName RegistryVersionMajor = " RegistryVersionMajor " ;
const FName RegistryVersionMinor = " RegistryVersionMinor " ;
# if WITH_EDITORONLY_DATA
const FName RegistryInputTypes = " RegistryInputTypes " ;
const FName RegistryOutputTypes = " RegistryOutputTypes " ;
# endif // WITH_EDITORONLY_DATA
} // namespace AssetTags
} // namespace Metasound
2020-07-23 16:39:56 -04:00
const FString FMetasoundAssetBase : : FileExtension ( TEXT ( " .metasound " ) ) ;
2021-06-08 10:52:31 -04:00
void FMetasoundAssetBase : : RegisterGraphWithFrontend ( )
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-06-08 10:52:31 -04:00
FConstDocumentAccessPtr DocumentPtr = GetDocument ( ) ;
FString AssetName ;
2021-06-16 11:20:44 -04:00
FString AssetPath ;
2021-06-08 10:52:31 -04:00
if ( const UObject * OwningAsset = GetOwningAsset ( ) )
{
AssetName = OwningAsset - > GetName ( ) ;
2021-06-16 11:20:44 -04:00
AssetPath = OwningAsset - > GetPathName ( ) ;
2021-06-08 10:52:31 -04:00
}
2021-06-14 16:45:51 -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:45:51 -04:00
public :
2021-06-16 11:20:44 -04:00
FNodeRegistryEntry ( const FString & InName , const FMetasoundFrontendDocument & InDocument , FName InAssetPath )
2021-06-14 16:45:51 -04:00
: Name ( InName )
, Document ( InDocument )
2021-06-08 10:52:31 -04:00
{
2021-06-14 16:45:51 -04:00
// Copy frontend class to preserve original document.
FrontendClass = Document . RootGraph ;
2021-06-08 10:52:31 -04:00
FrontendClass . Metadata . Type = EMetasoundFrontendClassType : : External ;
2021-06-16 11:20:44 -04:00
ClassInfo = FNodeClassInfo ( Document . RootGraph , InAssetPath ) ;
2021-06-08 10:52:31 -04:00
}
2021-06-14 16:45:51 -04:00
virtual ~ FNodeRegistryEntry ( ) = default ;
virtual const FNodeClassInfo & GetClassInfo ( ) const override
{
return ClassInfo ;
}
virtual TUniquePtr < INode > CreateNode ( FDefaultNodeConstructorParams & & ) const override
{
return nullptr ;
}
virtual TUniquePtr < INode > CreateNode ( FDefaultLiteralNodeConstructorParams & & ) const override
{
return nullptr ;
}
virtual TUniquePtr < INode > CreateNode ( const FNodeInitData & ) const override
{
return FFrontendGraphBuilder ( ) . CreateGraph ( Document ) ;
}
virtual const FMetasoundFrontendClass & GetFrontendClass ( ) const override
{
return FrontendClass ;
}
virtual TUniquePtr < INodeRegistryEntry > Clone ( ) const override
{
2021-06-16 11:20:44 -04:00
return MakeUnique < FNodeRegistryEntry > ( Name , Document , ClassInfo . AssetPath ) ;
2021-06-14 16:45:51 -04:00
}
private :
FString Name ;
FMetasoundFrontendDocument Document ;
FMetasoundFrontendClass FrontendClass ;
FNodeClassInfo ClassInfo ;
2021-06-08 10:52:31 -04:00
} ;
2021-06-16 11:20:44 -04:00
FNodeClassInfo ClassInfo = GetAssetClassInfo ( ) ;
2021-07-12 16:12:36 -04:00
FNodeRegistryKey RegistryKey = NodeRegistryKey : : CreateKey ( ClassInfo ) ;
2021-06-14 16:45:51 -04:00
2021-07-12 16:12:36 -04:00
if ( NodeRegistryKey : : IsValid ( RegistryKey ) )
2021-06-08 10:52:31 -04:00
{
2021-06-09 18:17:31 -04:00
// Unregister prior version if it exists.
2021-06-16 11:20:44 -04:00
if ( bHasRegistered )
{
ensure ( FMetasoundFrontendRegistryContainer : : Get ( ) - > UnregisterNode ( RegistryKey ) ) ;
}
2021-06-08 10:52:31 -04:00
}
2021-06-16 11:20:44 -04:00
if ( const FMetasoundFrontendDocument * Doc = DocumentPtr . Get ( ) )
{
RegistryKey = FMetasoundFrontendRegistryContainer : : Get ( ) - > RegisterNode ( MakeUnique < FNodeRegistryEntry > ( AssetName , * Doc , ClassInfo . AssetPath ) ) ;
}
2021-07-12 16:12:36 -04:00
if ( NodeRegistryKey : : IsValid ( RegistryKey ) )
2021-06-16 11:20:44 -04:00
{
bHasRegistered = true ;
# if WITH_EDITORONLY_DATA
// Refresh Asset Registry Info if successfully registered with Frontend
FConstGraphHandle GraphHandle = GetDocumentHandle ( ) - > GetRootGraph ( ) ;
const FMetasoundFrontendClassMetadata & ClassFrontendMetadata = GraphHandle - > GetGraphMetadata ( ) ;
ClassInfo . AssetClassID = FGuid ( ClassFrontendMetadata . ClassName . Name . ToString ( ) ) ;
FNodeClassName ClassName = ClassFrontendMetadata . ClassName . ToNodeClassName ( ) ;
FMetasoundFrontendClass GraphClass ;
ensure ( ISearchEngine : : Get ( ) . FindClassWithMajorVersion ( ClassName , ClassFrontendMetadata . Version . Major , GraphClass ) ) ;
ClassInfo . Version = ClassFrontendMetadata . Version ;
ClassInfo . InputTypes . Reset ( ) ;
Algo : : Transform ( GraphClass . Interface . Inputs , ClassInfo . InputTypes , [ ] ( const FMetasoundFrontendClassInput & Input ) { return Input . TypeName ; } ) ;
ClassInfo . OutputTypes . Reset ( ) ;
Algo : : Transform ( GraphClass . Interface . Outputs , ClassInfo . OutputTypes , [ ] ( const FMetasoundFrontendClassOutput & Output ) { return Output . TypeName ; } ) ;
SetRegistryAssetClassInfo ( MoveTemp ( ClassInfo ) ) ;
# endif // WITH_EDITORONLY_DATA
}
else
2021-06-08 10:52:31 -04:00
{
UE_LOG ( LogMetaSound , Error , TEXT ( " Failed to register node for MetaSoundSource [Name:%s] " ) , * AssetName ) ;
}
2020-07-23 16:39:56 -04:00
}
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 ;
if ( Doc . RootGraph . Metadata . Type ! = EMetasoundFrontendClassType : : Graph )
{
2021-04-02 03:03:27 -04:00
UE_LOG ( LogMetaSound , Display , TEXT ( " Forcing class type to EMetasoundFrontendClassType::Graph on root graph metadata " ) ) ;
2021-01-13 10:48:59 -04:00
Doc . RootGraph . Metadata . Type = EMetasoundFrontendClassType : : Graph ;
}
2021-02-01 15:59:27 -04:00
MarkMetasoundDocumentDirty ( ) ;
2020-07-17 16:43:42 -04:00
}
2021-06-23 20:07:53 -04:00
bool FMetasoundAssetBase : : IsArchetypeSupported ( const FMetasoundFrontendVersion & InArchetypeVersion ) const
2020-12-14 15:48:27 -04:00
{
2021-06-23 20:07:53 -04:00
return GetSupportedArchetypeVersions ( ) . Contains ( InArchetypeVersion ) ;
2020-12-14 15:48:27 -04:00
}
2021-06-23 20:07:53 -04:00
FMetasoundFrontendVersion FMetasoundAssetBase : : GetPreferredArchetypeVersion ( const FMetasoundFrontendDocument & InDocument ) const
2020-12-14 15:48:27 -04:00
{
2021-06-23 20:07:53 -04:00
using namespace Metasound : : Frontend ;
2021-06-08 10:52:31 -04:00
// Default to archetype provided in case it is supported.
2021-06-23 20:07:53 -04:00
if ( IsArchetypeSupported ( InDocument . ArchetypeVersion ) )
2020-12-14 15:48:27 -04:00
{
2021-06-23 20:07:53 -04:00
return InDocument . ArchetypeVersion ;
2020-12-14 15:48:27 -04:00
}
2021-06-23 20:07:53 -04:00
// If existing archetype is not supported, check if an updated version is preferred.
auto IsNewVersion = [ & ] ( const FMetasoundFrontendVersion & InVersion )
{
return ( InDocument . ArchetypeVersion . Name = = InVersion . Name ) & & ( InVersion . Number > InDocument . ArchetypeVersion . Number ) ;
} ;
TArray < FMetasoundFrontendVersion > UpdatedVersions = GetSupportedArchetypeVersions ( ) . FilterByPredicate ( IsNewVersion ) ;
if ( UpdatedVersions . Num ( ) > 0 )
{
UpdatedVersions . Sort ( ) ;
return UpdatedVersions . Last ( ) ;
}
2020-12-14 15:48:27 -04:00
// If existing archetype is not supported, get the most similar that still supports the documents environment.
2021-06-23 20:07:53 -04:00
TArray < FMetasoundFrontendArchetype > Archetypes ;
for ( const FMetasoundFrontendVersion & Version : GetSupportedArchetypeVersions ( ) )
{
const FArchetypeRegistryKey Key = GetArchetypeRegistryKey ( Version ) ;
FMetasoundFrontendArchetype Archetype ;
if ( IArchetypeRegistry : : Get ( ) . FindArchetype ( Key , Archetype ) )
{
Archetypes . Add ( MoveTemp ( Archetype ) ) ;
}
}
const FMetasoundFrontendArchetype * SimilarArchetype = Metasound : : Frontend : : FindMostSimilarArchetypeSupportingEnvironment ( InDocument , Archetypes ) ;
2020-12-14 15:48:27 -04:00
if ( nullptr ! = SimilarArchetype )
{
2021-06-23 20:07:53 -04:00
return SimilarArchetype - > Version ;
2020-12-14 15:48:27 -04:00
}
// Nothing found. Return the existing archetype for the FMetasoundAssetBase.
2021-06-23 20:07:53 -04:00
return GetDefaultArchetypeVersion ( ) ;
2020-12-14 15:48:27 -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:07:53 -04:00
MarkMetasoundDocumentDirty ( ) ;
2020-07-23 20:32:26 -04:00
}
2021-06-08 10:52:31 -04:00
void FMetasoundAssetBase : : ConformDocumentToArchetype ( )
2020-07-23 20:32:26 -04:00
{
2021-06-23 20:07:53 -04:00
FMetasoundFrontendDocument & Doc = GetDocumentChecked ( ) ;
2021-02-01 15:59:27 -04:00
2021-06-23 20:07:53 -04:00
FMetasoundFrontendVersion PreferredArchetypeVersion = GetPreferredArchetypeVersion ( Doc ) ;
if ( PreferredArchetypeVersion ! = Doc . ArchetypeVersion )
{
Metasound : : Frontend : : FMatchRootGraphToArchetype Transform ( PreferredArchetypeVersion ) ;
if ( Transform . Transform ( GetDocumentHandle ( ) ) )
{
MarkMetasoundDocumentDirty ( ) ;
}
}
}
2021-06-24 13:29:50 -04:00
bool FMetasoundAssetBase : : VersionAsset ( bool bInMarkDirty )
2021-06-23 20:07:53 -04:00
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
FName AssetName ;
FString AssetPath ;
if ( const UObject * OwningAsset = GetOwningAsset ( ) )
{
AssetName = FName ( OwningAsset - > GetName ( ) ) ;
AssetPath = OwningAsset - > GetPathName ( ) ;
}
FDocumentHandle DocumentHandle = GetDocumentHandle ( ) ;
const bool bDidUpdateDocumentVersion = FVersionDocument ( AssetName , AssetPath ) . Transform ( DocumentHandle ) ;
bool bDidMatchRootGraphToArchetype = false ;
if ( FMetasoundFrontendDocument * Doc = GetDocument ( ) . Get ( ) )
{
FMetasoundFrontendVersion ArchetypeVerison = GetPreferredArchetypeVersion ( * Doc ) ;
bDidMatchRootGraphToArchetype = FMatchRootGraphToArchetype ( ArchetypeVerison ) . Transform ( DocumentHandle ) ;
}
const bool bDidUpdate = bDidUpdateDocumentVersion | | bDidMatchRootGraphToArchetype ;
2021-06-24 13:29:50 -04:00
if ( bInMarkDirty & & bDidUpdate )
2021-06-23 20:07:53 -04:00
{
MarkMetasoundDocumentDirty ( ) ;
}
return bDidUpdate ;
2021-02-01 15:59:27 -04:00
}
2021-06-08 10:52:31 -04:00
bool FMetasoundAssetBase : : CopyDocumentAndInjectReceiveNodes ( uint64 InInstanceID , const FMetasoundFrontendDocument & InSourceDoc , FMetasoundFrontendDocument & OutDestDoc ) const
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
OutDestDoc = InSourceDoc ;
FDocumentHandle Document = IDocumentController : : CreateDocumentHandle ( MakeAccessPtr < FDocumentAccessPtr > ( OutDestDoc . AccessPoint , OutDestDoc ) ) ;
FGraphHandle RootGraph = Document - > GetRootGraph ( ) ;
TArray < FSendInfoAndVertexName > SendInfoAndVertexes = GetSendInfos ( InInstanceID ) ;
// Inject receive nodes for each transmittable input
for ( const FSendInfoAndVertexName & InfoAndVertexName : SendInfoAndVertexes )
{
// Add receive node to graph
FMetasoundFrontendClassMetadata ReceiveNodeMetadata ;
bool bSuccess = GetReceiveNodeMetadataForDataType ( InfoAndVertexName . SendInfo . TypeName , ReceiveNodeMetadata ) ;
if ( ! bSuccess )
{
// TODO: log warning
continue ;
}
FNodeHandle ReceiveNode = RootGraph - > AddNode ( ReceiveNodeMetadata ) ;
// Add receive node address to graph
FNodeHandle AddressNode = AddInputPinForSendAddress ( InfoAndVertexName . SendInfo , RootGraph ) ;
TArray < FOutputHandle > AddressNodeOutputs = AddressNode - > GetOutputs ( ) ;
if ( AddressNodeOutputs . Num ( ) ! = 1 )
{
// TODO: log warning
continue ;
}
FOutputHandle AddressOutput = AddressNodeOutputs [ 0 ] ;
TArray < FInputHandle > ReceiveAddressInput = ReceiveNode - > GetInputsWithVertexName ( Metasound : : FReceiveNodeNames : : GetAddressInputName ( ) ) ;
if ( ReceiveAddressInput . Num ( ) ! = 1 )
{
// TODO: log error
continue ;
}
ensure ( ReceiveAddressInput [ 0 ] - > Connect ( * AddressOutput ) ) ;
// Swap input node connections with receive node connections
FNodeHandle InputNode = RootGraph - > GetInputNodeWithName ( InfoAndVertexName . VertexName ) ;
if ( ! ensure ( InputNode - > GetOutputs ( ) . Num ( ) = = 1 ) )
{
// TODO: handle input node with varying number of outputs or varying output types.
continue ;
}
FOutputHandle InputNodeOutput = InputNode - > GetOutputs ( ) [ 0 ] ;
if ( ensure ( ReceiveNode - > IsValid ( ) ) )
{
TArray < FOutputHandle > ReceiveNodeOutputs = ReceiveNode - > GetOutputs ( ) ;
if ( ! ensure ( ReceiveNodeOutputs . Num ( ) = = 1 ) )
{
// TODO: handle array outputs and receive nodes of varying formats.
continue ;
}
TArray < FInputHandle > ReceiveDefaultInputs = ReceiveNode - > GetInputsWithVertexName ( Metasound : : FReceiveNodeNames : : GetDefaultDataInputName ( ) ) ;
if ( ensure ( ReceiveDefaultInputs . Num ( ) = = 1 ) )
{
FOutputHandle ReceiverNodeOutput = ReceiveNodeOutputs [ 0 ] ;
for ( FInputHandle NodeInput : InputNodeOutput - > GetConnectedInputs ( ) )
{
// Swap connections to receiver node
ensure ( InputNodeOutput - > Disconnect ( * NodeInput ) ) ;
ensure ( ReceiverNodeOutput - > Connect ( * NodeInput ) ) ;
}
ReceiveDefaultInputs [ 0 ] - > Connect ( * InputNodeOutput ) ;
}
}
}
return true ;
}
Metasound : : FSendAddress FMetasoundAssetBase : : CreateSendAddress ( uint64 InInstanceID , const FString & InVertexName , const FName & InDataTypeName ) const
{
using namespace Metasound ;
FSendAddress Address ;
Address . Subsystem = GetSubsystemNameForSendScope ( ETransmissionScope : : Global ) ;
Address . ChannelName = FName ( FString : : Printf ( TEXT ( " %d:%s:%s " ) , InInstanceID , * InVertexName , * InDataTypeName . ToString ( ) ) ) ;
return Address ;
}
2021-06-16 11:20:44 -04:00
void FMetasoundAssetBase : : ConvertFromPreset ( )
{
using namespace Metasound : : Frontend ;
FGraphHandle GraphHandle = GetRootGraphHandle ( ) ;
FMetasoundFrontendGraphStyle Style = GraphHandle - > GetGraphStyle ( ) ;
Style . bIsGraphEditable = true ;
GraphHandle - > SetGraphStyle ( Style ) ;
}
2021-06-08 10:52:31 -04:00
TArray < FMetasoundAssetBase : : FSendInfoAndVertexName > FMetasoundAssetBase : : GetSendInfos ( uint64 InInstanceID ) const
{
using FSendInfo = Metasound : : FMetasoundInstanceTransmitter : : FSendInfo ;
using namespace Metasound : : Frontend ;
TArray < FSendInfoAndVertexName > SendInfos ;
FConstGraphHandle RootGraph = GetRootGraphHandle ( ) ;
TArray < FString > SendVertices = GetTransmittableInputVertexNames ( ) ;
for ( const FString & VertexName : SendVertices )
{
FConstNodeHandle InputNode = RootGraph - > GetInputNodeWithName ( VertexName ) ;
for ( FConstInputHandle InputHandle : InputNode - > GetConstInputs ( ) )
{
FSendInfoAndVertexName Info ;
// TODO: incorporate VertexID into address. But need to ensure that VertexID
// will be maintained after injecting Receive nodes.
Info . SendInfo . Address = CreateSendAddress ( InInstanceID , InputHandle - > GetName ( ) , InputHandle - > GetDataType ( ) ) ;
Info . SendInfo . ParameterName = FName ( InputHandle - > GetDisplayName ( ) . ToString ( ) ) ; // TODO: display name hack. Need to have naming consistent in editor for inputs
//Info.SendInfo.ParameterName = FName(*InputHandle->GetName()); // TODO: this is the expected parameter name.
Info . SendInfo . TypeName = InputHandle - > GetDataType ( ) ;
Info . VertexName = VertexName ;
SendInfos . Add ( Info ) ;
}
}
return SendInfos ;
}
TArray < FString > FMetasoundAssetBase : : GetTransmittableInputVertexNames ( ) const
{
using namespace Metasound ;
2021-06-23 20:07:53 -04:00
using namespace Metasound : : Frontend ;
FConstDocumentHandle Document = GetDocumentHandle ( ) ;
// Find the archetype for the document.
FMetasoundFrontendArchetype Archetype ;
FArchetypeRegistryKey ArchetypeRegistryKey = Frontend : : GetArchetypeRegistryKey ( Document - > GetArchetypeVersion ( ) ) ;
bool bFoundArchetype = IArchetypeRegistry : : Get ( ) . FindArchetype ( ArchetypeRegistryKey , Archetype ) ;
if ( ! bFoundArchetype )
{
UE_LOG ( LogMetaSound , Warning , TEXT ( " No registered archetype matching archetype version on document [ArchetypeVersion:%s] " ) , * Document - > GetArchetypeVersion ( ) . ToString ( ) ) ;
}
2021-06-08 10:52:31 -04:00
// Unused inputs are all input vertices that are not in the archetype.
TArray < FString > ArchetypeInputVertexNames ;
2021-06-23 20:07:53 -04:00
for ( const FMetasoundFrontendClassVertex & Vertex : Archetype . Interface . Inputs )
2021-06-08 10:52:31 -04:00
{
ArchetypeInputVertexNames . Add ( Vertex . Name ) ;
}
2021-06-23 20:07:53 -04:00
Frontend : : FConstGraphHandle RootGraph = Document - > GetRootGraph ( ) ;
2021-06-08 10:52:31 -04:00
TArray < FString > GraphInputVertexNames = RootGraph - > GetInputVertexNames ( ) ;
// Filter graph inputs by archetype inputs.
GraphInputVertexNames = GraphInputVertexNames . FilterByPredicate ( [ & ] ( const FString & InName ) { return ! ArchetypeInputVertexNames . Contains ( InName ) ; } ) ;
auto IsDataTypeTransmittable = [ & ] ( const FString & InVertexName )
{
Frontend : : FConstClassInputAccessPtr ClassInputPtr = RootGraph - > FindClassInputWithName ( InVertexName ) ;
if ( const FMetasoundFrontendClassInput * ClassInput = ClassInputPtr . Get ( ) )
{
2021-06-14 16:45:51 -04:00
Frontend : : FDataTypeRegistryInfo TypeInfo ;
2021-06-08 10:52:31 -04:00
if ( Frontend : : GetTraitsForDataType ( ClassInput - > TypeName , TypeInfo ) )
{
if ( TypeInfo . bIsTransmittable )
{
Frontend : : FConstNodeHandle InputNode = RootGraph - > GetNodeWithID ( ClassInput - > NodeID ) ;
if ( InputNode - > IsValid ( ) )
{
return true ;
}
}
}
}
return false ;
} ;
GraphInputVertexNames = GraphInputVertexNames . FilterByPredicate ( IsDataTypeTransmittable ) ;
return GraphInputVertexNames ;
}
Metasound : : Frontend : : FNodeHandle FMetasoundAssetBase : : AddInputPinForSendAddress ( const Metasound : : FMetasoundInstanceTransmitter : : FSendInfo & InSendInfo , Metasound : : Frontend : : FGraphHandle InGraph ) const
{
FMetasoundFrontendClassInput Description ;
FGuid VertexID = FGuid : : NewGuid ( ) ;
Description . Name = InSendInfo . Address . ChannelName . ToString ( ) ;
Description . TypeName = Metasound : : GetMetasoundDataTypeName < Metasound : : FSendAddress > ( ) ;
Description . Metadata . Description = FText : : GetEmpty ( ) ;
Description . VertexID = VertexID ;
Description . DefaultLiteral . Set ( InSendInfo . Address . ChannelName . ToString ( ) ) ;
return InGraph - > AddInputVertex ( Description ) ;
}
# if WITH_EDITORONLY_DATA
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 ) ) ) ;
}
# endif // WITH_EDITORONLY_DATA
bool FMetasoundAssetBase : : GetReceiveNodeMetadataForDataType ( const FName & InTypeName , FMetasoundFrontendClassMetadata & OutMetadata ) const
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
const FNodeClassName ClassName = FReceiveNodeNames : : GetClassNameForDataType ( InTypeName ) ;
TArray < FMetasoundFrontendClass > ReceiverNodeClasses = ISearchEngine : : Get ( ) . FindClassesWithName ( ClassName , true /* bInSortByVersion */ ) ;
if ( ReceiverNodeClasses . IsEmpty ( ) )
{
return false ;
}
OutMetadata = ReceiverNodeClasses [ 0 ] . Metadata ;
return true ;
}
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-07-12 16:12:36 -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-07-12 16:12:36 -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:12:36 -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:12:36 -04:00
const FMetasoundFrontendDocument * Document = GetDocument ( ) . Get ( ) ;
2020-12-14 15:48:27 -04:00
2021-07-12 16:12:36 -04:00
check ( nullptr ! = Document ) ;
return * Document ;
2020-08-05 12:47:19 -04:00
}
2021-06-08 10:52:31 -04:00
# undef LOCTEXT_NAMESPACE // "MetaSound"