2022-03-01 04:23:55 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "RigVMModel/Nodes/RigVMTemplateNode.h"
2022-05-09 07:34:28 -04:00
# include "RigVMCore/RigVMTemplate.h"
2022-03-14 10:19:31 -04:00
# include "RigVMModel/RigVMController.h"
2022-03-01 04:23:55 -05:00
URigVMTemplateNode : : URigVMTemplateNode ( )
: Super ( )
, TemplateNotation ( NAME_None )
, ResolvedFunctionName ( )
, CachedTemplate ( nullptr )
, CachedFunction ( nullptr )
{
}
2022-04-20 10:28:28 -04:00
void URigVMTemplateNode : : PostLoad ( )
{
Super : : PostLoad ( ) ;
// if there are brackets in the notation remove them
const FString OriginalNotation = TemplateNotation . ToString ( ) ;
const FString SanitizedNotation = OriginalNotation . Replace ( TEXT ( " [] " ) , TEXT ( " " ) ) ;
if ( OriginalNotation ! = SanitizedNotation )
{
TemplateNotation = * SanitizedNotation ;
}
InvalidateCache ( ) ;
}
2022-03-01 04:23:55 -05:00
UScriptStruct * URigVMTemplateNode : : GetScriptStruct ( ) const
{
if ( const FRigVMFunction * Function = GetResolvedFunction ( ) )
{
return Function - > Struct ;
}
return nullptr ;
}
FString URigVMTemplateNode : : GetNodeTitle ( ) const
{
if ( ! IsResolved ( ) )
{
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
{
return Template - > GetName ( ) . ToString ( ) ;
}
}
FString ResolvedNodeTitle = Super : : GetNodeTitle ( ) ;
const int32 BracePos = ResolvedNodeTitle . Find ( TEXT ( " ( " ) ) ;
if ( BracePos ! = INDEX_NONE )
{
ResolvedNodeTitle = ResolvedNodeTitle . Left ( BracePos ) ;
}
return ResolvedNodeTitle ;
}
FName URigVMTemplateNode : : GetMethodName ( ) const
{
if ( const FRigVMFunction * Function = GetResolvedFunction ( ) )
{
return Function - > GetMethodName ( ) ;
}
return NAME_None ;
}
FText URigVMTemplateNode : : GetToolTipText ( ) const
{
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
{
2022-05-09 07:34:28 -04:00
const TArray < int32 > PermutationIndices = GetFilteredPermutationsIndices ( ) ;
2022-03-01 04:23:55 -05:00
return Template - > GetTooltipText ( PermutationIndices ) ;
}
return Super : : GetToolTipText ( ) ;
}
FText URigVMTemplateNode : : GetToolTipTextForPin ( const URigVMPin * InPin ) const
{
const FText SuperToolTip = Super : : GetToolTipTextForPin ( InPin ) ;
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
{
const URigVMPin * RootPin = InPin - > GetRootPin ( ) ;
if ( RootPin - > IsWildCard ( ) )
{
if ( const FRigVMTemplateArgument * Arg = Template - > FindArgument ( RootPin - > GetFName ( ) ) )
{
2022-04-20 05:02:39 -04:00
FString Tooltip ;
2022-05-09 07:34:28 -04:00
const TArray < int32 > PermutationIndices = GetFilteredPermutationsIndices ( ) ;
2022-04-20 05:02:39 -04:00
if ( PermutationIndices . Num ( ) = = GetTemplate ( ) - > NumPermutations ( ) )
{
if ( Arg - > GetTypes ( ) . Num ( ) > 100 )
{
Tooltip = TEXT ( " Supports any type. " ) ;
}
}
if ( Tooltip . IsEmpty ( ) )
{
2022-05-09 07:34:28 -04:00
FString SupportedTypesJoined ;
for ( int32 Index : PermutationIndices )
{
FString Type = Arg - > GetTypes ( ) [ Index ] . CPPType ;
if ( ! FilteredPermutations . Contains ( Index ) )
{
Type + = TEXT ( " : Breaks Connections " ) ;
}
SupportedTypesJoined + = Type + TEXT ( " \n " ) ;
}
2022-04-20 05:02:39 -04:00
Tooltip = TEXT ( " Supported Types: \n \n " ) + SupportedTypesJoined ;
}
2022-03-01 04:23:55 -05:00
if ( ! SuperToolTip . IsEmpty ( ) )
{
Tooltip + = TEXT ( " \n \n " ) + SuperToolTip . ToString ( ) ;
}
return FText : : FromString ( Tooltip ) ;
}
}
}
return SuperToolTip ;
}
FName URigVMTemplateNode : : GetNotation ( ) const
{
return TemplateNotation ;
}
2022-05-09 07:34:28 -04:00
bool URigVMTemplateNode : : IsSingleton ( ) const
{
return GetTemplate ( ) = = nullptr ;
}
2022-03-01 04:23:55 -05:00
bool URigVMTemplateNode : : SupportsType ( const URigVMPin * InPin , const FString & InCPPType , FString * OutCPPType )
{
static const FString WildCardCPPType = RigVMTypeUtils : : GetWildCardCPPType ( ) ;
static const FString WildCardArrayCPPType = RigVMTypeUtils : : ArrayTypeFromBaseType ( WildCardCPPType ) ;
2022-03-14 10:19:31 -04:00
const URigVMPin * RootPin = InPin - > GetRootPin ( ) ;
2022-04-20 10:28:28 -04:00
FString CPPType = InCPPType ;
if ( InPin - > GetParentPin ( ) = = RootPin & & RootPin - > IsArray ( ) )
{
CPPType = RigVMTypeUtils : : ArrayTypeFromBaseType ( CPPType ) ;
}
2022-03-01 04:23:55 -05:00
// we always support the unknown type
2022-04-20 10:28:28 -04:00
if ( ( InCPPType = = WildCardCPPType ) | | ( InCPPType = = WildCardArrayCPPType ) )
2022-03-01 04:23:55 -05:00
{
2022-03-14 10:19:31 -04:00
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
2022-03-01 04:23:55 -05:00
{
2022-03-14 10:19:31 -04:00
if ( const FRigVMTemplateArgument * Argument = Template - > FindArgument ( RootPin - > GetFName ( ) ) )
{
// support this only on non-singleton arguments
if ( Argument - > IsSingleton ( ) )
{
return false ;
}
2022-04-20 10:28:28 -04:00
if ( RigVMTypeUtils : : IsArrayType ( CPPType ) )
{
if ( Argument - > GetArrayType ( ) = = FRigVMTemplateArgument : : EArrayType_SingleValue )
{
return false ;
}
}
else
{
if ( Argument - > GetArrayType ( ) = = FRigVMTemplateArgument : : EArrayType_ArrayValue )
{
return false ;
}
}
2022-03-14 10:19:31 -04:00
if ( OutCPPType )
{
* OutCPPType = InCPPType ;
}
return true ;
}
2022-03-01 04:23:55 -05:00
}
2022-03-14 10:19:31 -04:00
return false ;
2022-03-01 04:23:55 -05:00
}
2022-03-14 10:19:31 -04:00
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
2022-03-01 04:23:55 -05:00
{
const FString CacheKey = RootPin - > GetName ( ) + TEXT ( " | " ) + CPPType ;
if ( const TPair < bool , FRigVMTemplateArgument : : FType > * CachedResult = SupportedTypesCache . Find ( CacheKey ) )
{
if ( OutCPPType )
{
* OutCPPType = CachedResult - > Value . CPPType ;
}
return CachedResult - > Key ;
}
2022-05-18 06:43:26 -04:00
FRigVMTemplateArgument : : FType OutType ;
if ( Template - > ArgumentSupportsType ( RootPin - > GetFName ( ) , CPPType , & OutType ) )
2022-03-01 04:23:55 -05:00
{
2022-05-18 06:43:26 -04:00
if ( OutCPPType )
2022-03-01 04:23:55 -05:00
{
2022-05-18 06:43:26 -04:00
( * OutCPPType ) = OutType . CPPType ;
2022-03-01 04:23:55 -05:00
}
2022-05-18 06:43:26 -04:00
return true ;
2022-03-01 04:23:55 -05:00
}
2022-05-18 06:43:26 -04:00
return false ;
2022-03-14 10:19:31 -04:00
}
2022-03-01 04:23:55 -05:00
if ( RootPin - > GetCPPType ( ) = = CPPType )
{
if ( OutCPPType )
{
* OutCPPType = CPPType ;
}
return true ;
}
return false ;
}
2022-05-09 07:34:28 -04:00
bool URigVMTemplateNode : : FilteredSupportsType ( const URigVMPin * InPin , const FString & InCPPType , FString * OutCPPType , bool bAllowFloatingPointCasts )
2022-03-14 10:19:31 -04:00
{
2022-05-09 07:34:28 -04:00
if ( OutCPPType )
2022-03-14 10:19:31 -04:00
{
2022-05-09 07:34:28 -04:00
* OutCPPType = FString ( ) ;
}
const URigVMPin * RootPin = InPin ;
bool bIsArrayElement = false ;
2022-05-09 14:13:48 -04:00
bool bIsStructElement = false ;
2022-05-09 07:34:28 -04:00
if ( URigVMPin * ParentPin = InPin - > GetParentPin ( ) )
{
RootPin = ParentPin ;
2022-05-09 14:13:48 -04:00
if ( ParentPin - > IsArray ( ) )
{
bIsArrayElement = true ;
}
else if ( ParentPin - > IsStruct ( ) )
{
bIsStructElement = true ;
}
2022-05-09 07:34:28 -04:00
}
2022-05-09 14:13:48 -04:00
if ( bIsStructElement )
{
return InPin - > GetCPPType ( ) = = InCPPType ;
}
2022-05-09 07:34:28 -04:00
const FRigVMTemplateArgument * Argument = GetTemplate ( ) - > FindArgument ( RootPin - > GetFName ( ) ) ;
if ( Argument = = nullptr )
{
return false ;
}
2022-05-18 06:43:26 -04:00
FString RootCPPType = InCPPType ;
if ( bIsArrayElement )
{
RootCPPType = RigVMTypeUtils : : ArrayTypeFromBaseType ( InCPPType ) ;
}
if ( FilteredPermutations . Num ( ) = = GetTemplate ( ) - > NumPermutations ( ) )
{
return GetTemplate ( ) - > ArgumentSupportsType ( RootPin - > GetFName ( ) , InCPPType ) ;
}
2022-05-09 07:34:28 -04:00
const TArray < FRigVMTemplateArgument : : FType > & Types = Argument - > GetTypes ( ) ;
for ( int32 PermutationIndex : FilteredPermutations )
{
2022-05-18 06:43:26 -04:00
const FRigVMTemplateArgument : : FType & FilteredType = Types [ PermutationIndex ] ;
if ( FilteredType . Matches ( RootCPPType , bAllowFloatingPointCasts ) )
2022-05-09 07:34:28 -04:00
{
return true ;
}
2022-03-14 10:19:31 -04:00
}
return false ;
}
2022-05-09 07:34:28 -04:00
TArray < const FRigVMFunction * > URigVMTemplateNode : : GetResolvedPermutations ( ) const
2022-03-01 04:23:55 -05:00
{
2022-05-09 07:34:28 -04:00
TArray < int32 > Indices = GetFilteredPermutationsIndices ( ) ;
2022-03-01 04:23:55 -05:00
TArray < const FRigVMFunction * > Functions ;
for ( const int32 Index : Indices )
{
Functions . Add ( GetTemplate ( ) - > GetPermutation ( Index ) ) ;
}
return Functions ;
}
const FRigVMTemplate * URigVMTemplateNode : : GetTemplate ( ) const
{
if ( CachedTemplate = = nullptr )
{
2022-04-20 10:28:28 -04:00
CachedTemplate = FRigVMRegistry : : Get ( ) . FindTemplate ( GetNotation ( ) ) ;
2022-03-01 04:23:55 -05:00
}
return CachedTemplate ;
}
const FRigVMFunction * URigVMTemplateNode : : GetResolvedFunction ( ) const
{
if ( CachedFunction = = nullptr )
{
if ( ! ResolvedFunctionName . IsEmpty ( ) )
{
CachedFunction = FRigVMRegistry : : Get ( ) . FindFunction ( * ResolvedFunctionName ) ;
}
if ( CachedFunction = = nullptr )
{
2022-05-09 07:34:28 -04:00
TArray < int32 > PermutationIndices = GetFilteredPermutationsIndices ( ) ;
2022-03-01 04:23:55 -05:00
if ( PermutationIndices . Num ( ) = = 1 )
{
CachedFunction = GetTemplate ( ) - > GetPermutation ( PermutationIndices [ 0 ] ) ;
}
}
}
return CachedFunction ;
}
bool URigVMTemplateNode : : IsResolved ( ) const
{
return GetScriptStruct ( ) ! = nullptr ;
}
2022-03-14 10:19:31 -04:00
bool URigVMTemplateNode : : IsFullyUnresolved ( ) const
{
check ( GetTemplate ( ) ) ;
// all permutations are available means we haven't resolved any wildcard pin
2022-05-09 07:34:28 -04:00
return GetFilteredPermutationsIndices ( ) . Num ( ) = = GetTemplate ( ) - > NumPermutations ( ) ;
2022-03-14 10:19:31 -04:00
}
FString URigVMTemplateNode : : GetInitialDefaultValueForPin ( const FName & InRootPinName , const TArray < int32 > & InPermutationIndices ) const
{
if ( GetTemplate ( ) = = nullptr )
{
return FString ( ) ;
}
TArray < int32 > PermutationIndices = InPermutationIndices ;
if ( PermutationIndices . IsEmpty ( ) )
{
2022-05-09 07:34:28 -04:00
PermutationIndices = GetFilteredPermutationsIndices ( ) ;
2022-03-14 10:19:31 -04:00
}
FString DefaultValue ;
for ( const int32 PermutationIndex : PermutationIndices )
{
2022-04-20 05:02:39 -04:00
FString NewDefaultValue ;
if ( const FRigVMFunction * Permutation = GetTemplate ( ) - > GetPermutation ( PermutationIndex ) )
{
const TSharedPtr < FStructOnScope > StructOnScope = MakeShareable ( new FStructOnScope ( Permutation - > Struct ) ) ;
const FRigVMStruct * DefaultStruct = ( const FRigVMStruct * ) StructOnScope - > GetStructMemory ( ) ;
2022-03-14 10:19:31 -04:00
2022-04-20 05:02:39 -04:00
NewDefaultValue = DefaultStruct - > ExportToFullyQualifiedText (
Cast < UScriptStruct > ( StructOnScope - > GetStruct ( ) ) , InRootPinName ) ;
}
2022-04-21 09:10:19 -04:00
else
{
const FRigVMTemplate * Template = GetTemplate ( ) ;
const FRigVMTemplateArgument * Argument = Template - > FindArgument ( InRootPinName ) ;
const FRigVMTemplateArgument : : FType Type = Argument - > GetTypes ( ) [ PermutationIndex ] ;
if ( Type . IsArray ( ) )
{
NewDefaultValue = TEXT ( " () " ) ;
}
else
{
if ( UScriptStruct * ScriptStruct = Cast < UScriptStruct > ( Type . CPPTypeObject ) )
{
TArray < uint8 , TAlignedHeapAllocator < 16 > > TempBuffer ;
TempBuffer . AddUninitialized ( ScriptStruct - > GetStructureSize ( ) ) ;
// call the struct constructor to initialize the struct
ScriptStruct - > InitializeDefaultValue ( TempBuffer . GetData ( ) ) ;
ScriptStruct - > ExportText ( NewDefaultValue , TempBuffer . GetData ( ) , nullptr , nullptr , PPF_None , nullptr ) ;
ScriptStruct - > DestroyStruct ( TempBuffer . GetData ( ) ) ;
}
else if ( UEnum * Enum = Cast < UEnum > ( Type . CPPTypeObject ) )
{
NewDefaultValue = Enum - > GetNameStringByValue ( 0 ) ;
}
else if ( UClass * Class = Cast < UClass > ( Type . CPPTypeObject ) )
{
// not supporting objects yet
ensure ( false ) ;
}
else if ( Type . CPPType = = RigVMTypeUtils : : FloatType )
{
NewDefaultValue = TEXT ( " 0.000000 " ) ;
}
else if ( Type . CPPType = = RigVMTypeUtils : : DoubleType )
{
NewDefaultValue = TEXT ( " 0.000000 " ) ;
}
else if ( Type . CPPType = = RigVMTypeUtils : : Int32Type )
{
NewDefaultValue = TEXT ( " 0 " ) ;
}
else if ( Type . CPPType = = RigVMTypeUtils : : BoolType )
{
NewDefaultValue = TEXT ( " False " ) ;
}
else if ( Type . CPPType = = RigVMTypeUtils : : FStringType )
{
NewDefaultValue = TEXT ( " " ) ;
}
else if ( Type . CPPType = = RigVMTypeUtils : : FNameType )
{
NewDefaultValue = TEXT ( " " ) ;
}
}
}
2022-03-14 10:19:31 -04:00
if ( ! NewDefaultValue . IsEmpty ( ) )
{
if ( DefaultValue . IsEmpty ( ) )
{
DefaultValue = NewDefaultValue ;
}
else if ( ! NewDefaultValue . Equals ( DefaultValue ) )
{
return FString ( ) ;
}
}
}
return DefaultValue ;
}
2022-03-17 07:20:36 -04:00
FName URigVMTemplateNode : : GetDisplayNameForPin ( const FName & InRootPinName ,
const TArray < int32 > & InPermutationIndices ) const
{
# if WITH_EDITOR
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
{
const TArray < int32 > * PermutationIndicesPtr = & InPermutationIndices ;
if ( PermutationIndicesPtr - > IsEmpty ( ) )
{
2022-05-09 07:34:28 -04:00
PermutationIndicesPtr = & GetFilteredPermutationsIndices ( ) ;
2022-03-17 07:20:36 -04:00
}
const FText DisplayNameText = Template - > GetDisplayNameForArgument ( InRootPinName , * PermutationIndicesPtr ) ;
if ( DisplayNameText . IsEmpty ( ) )
{
return InRootPinName ;
}
const FName DisplayName = * DisplayNameText . ToString ( ) ;
if ( DisplayName . IsEqual ( InRootPinName ) )
{
return NAME_None ;
}
return DisplayName ;
}
# endif
return NAME_None ;
}
2022-05-09 07:34:28 -04:00
const TArray < int32 > & URigVMTemplateNode : : GetFilteredPermutationsIndices ( ) const
{
return FilteredPermutations ;
}
TArray < FRigVMTemplateArgument : : FType > URigVMTemplateNode : : GetFilteredTypesForPin ( URigVMPin * InPin ) const
{
ensureMsgf ( InPin - > GetNode ( ) = = this , TEXT ( " GetFilteredTypesForPin of %s with pin from another node %s " ) , * GetNodePath ( ) , * InPin - > GetPinPath ( true ) ) ;
TArray < FRigVMTemplateArgument : : FType > FilteredTypes ;
if ( FilteredPermutations . IsEmpty ( ) )
{
return FilteredTypes ;
}
2022-05-18 06:43:26 -04:00
if ( ! PreferredPermutationTypes . IsEmpty ( ) )
{
for ( const FString & PreferredType : PreferredPermutationTypes )
{
FString ArgName , CPPType ;
PreferredType . Split ( TEXT ( " : " ) , & ArgName , & CPPType ) ;
if ( InPin - > GetName ( ) = = ArgName )
{
const FRigVMTemplateArgument * Argument = GetTemplate ( ) - > FindArgument ( * ArgName ) ;
for ( const FRigVMTemplateArgument : : FType & Type : Argument - > GetTypes ( ) )
{
if ( Type . CPPType = = CPPType )
{
return { Type } ;
}
}
}
}
}
2022-05-09 07:34:28 -04:00
URigVMPin * RootPin = InPin ;
bool bIsArrayElement = false ;
if ( URigVMPin * ParentPin = InPin - > GetParentPin ( ) )
{
RootPin = ParentPin ;
bIsArrayElement = true ;
}
if ( const FRigVMTemplateArgument * Argument = GetTemplate ( ) - > FindArgument ( RootPin - > GetFName ( ) ) )
{
FilteredTypes = Argument - > GetSupportedTypes ( FilteredPermutations ) ;
if ( bIsArrayElement )
{
for ( FRigVMTemplateArgument : : FType & ArrayType : FilteredTypes )
{
ArrayType . ConvertToBaseElement ( ) ;
}
}
}
return FilteredTypes ;
}
TArray < int32 > URigVMTemplateNode : : GetNewFilteredPermutations ( URigVMPin * InPin , URigVMPin * LinkedPin )
{
TArray < int32 > NewFilteredPermutations ;
if ( InPin - > GetNode ( ) ! = this )
{
return NewFilteredPermutations ;
}
NewFilteredPermutations . Reserve ( FilteredPermutations . Num ( ) ) ;
bool bIsArrayElement = false ;
2022-05-09 14:13:48 -04:00
bool bIsStructElement = false ;
2022-05-09 07:34:28 -04:00
URigVMPin * RootPin = InPin ;
if ( URigVMPin * ParentPin = InPin - > GetParentPin ( ) )
{
RootPin = ParentPin ;
2022-05-09 14:13:48 -04:00
bIsArrayElement = RootPin - > IsArray ( ) ;
bIsStructElement = RootPin - > IsStruct ( ) ;
}
if ( bIsStructElement )
{
2022-05-10 09:29:27 -04:00
if ( RigVMTypeUtils : : AreCompatible ( InPin - > GetCPPType ( ) , InPin - > GetCPPTypeObject ( ) , LinkedPin - > GetCPPType ( ) , LinkedPin - > GetCPPTypeObject ( ) ) )
2022-05-09 14:13:48 -04:00
{
return FilteredPermutations ;
}
2022-05-09 07:34:28 -04:00
}
2022-05-18 06:43:26 -04:00
TArray < int32 > PermutationsToTry = PreferredPermutationTypes . IsEmpty ( ) ? FilteredPermutations : TArray < int32 > ( FindPermutationsForTypes ( PreferredPermutationTypes ) ) ;
2022-05-09 07:34:28 -04:00
bool bLinkedIsTemplate = false ;
if ( URigVMTemplateNode * LinkedTemplate = Cast < URigVMTemplateNode > ( LinkedPin - > GetNode ( ) ) )
{
2022-05-10 09:29:27 -04:00
if ( ! LinkedTemplate - > IsSingleton ( ) & & ! LinkedPin - > IsStructMember ( ) )
2022-05-09 07:34:28 -04:00
{
bLinkedIsTemplate = true ;
if ( const FRigVMTemplateArgument * Argument = GetTemplate ( ) - > FindArgument ( RootPin - > GetFName ( ) ) )
{
for ( int32 PermutationIndex : PermutationsToTry )
{
FRigVMTemplateArgument : : FType Type = Argument - > GetTypes ( ) [ PermutationIndex ] ;
if ( bIsArrayElement )
{
Type . ConvertToBaseElement ( ) ;
}
if ( LinkedTemplate - > FilteredSupportsType ( LinkedPin , Type . CPPType ) )
{
NewFilteredPermutations . Add ( PermutationIndex ) ;
}
}
}
}
}
if ( ! bLinkedIsTemplate )
{
if ( const FRigVMTemplateArgument * Argument = GetTemplate ( ) - > FindArgument ( RootPin - > GetFName ( ) ) )
{
2022-05-18 06:43:26 -04:00
const FString LinkedCPPType = LinkedPin - > GetCPPType ( ) ;
2022-05-09 07:34:28 -04:00
for ( int32 PermIndex : PermutationsToTry )
{
FRigVMTemplateArgument : : FType Type = Argument - > GetTypes ( ) [ PermIndex ] ;
if ( bIsArrayElement )
{
Type . ConvertToBaseElement ( ) ;
}
2022-05-18 06:43:26 -04:00
if ( Type . Matches ( LinkedCPPType ) )
2022-05-09 07:34:28 -04:00
{
NewFilteredPermutations . Add ( PermIndex ) ;
}
}
}
}
return NewFilteredPermutations ;
}
TArray < int32 > URigVMTemplateNode : : GetNewFilteredPermutations ( URigVMPin * InPin , const TArray < FRigVMTemplateArgument : : FType > & InTypes )
{
TArray < int32 > NewFilteredPermutations ;
NewFilteredPermutations . Reserve ( FilteredPermutations . Num ( ) ) ;
URigVMPin * RootPin = InPin ;
TArray < FRigVMTemplateArgument : : FType > RootTypes = InTypes ;
if ( URigVMPin * ParentPin = InPin - > GetParentPin ( ) )
{
RootPin = ParentPin ;
for ( FRigVMTemplateArgument : : FType & Type : RootTypes )
{
Type . ConvertToArray ( ) ;
}
}
2022-05-18 06:43:26 -04:00
TArray < int32 > PermutationsToTry = PreferredPermutationTypes . IsEmpty ( ) ? FilteredPermutations : TArray < int32 > ( FindPermutationsForTypes ( PreferredPermutationTypes ) ) ;
2022-05-09 07:34:28 -04:00
if ( const FRigVMTemplateArgument * Argument = GetTemplate ( ) - > FindArgument ( RootPin - > GetFName ( ) ) )
{
const TArray < FRigVMTemplateArgument : : FType > & Types = Argument - > GetTypes ( ) ;
for ( int32 PermIndex : PermutationsToTry )
{
for ( FRigVMTemplateArgument : : FType & RootType : RootTypes )
{
if ( Types [ PermIndex ] . Matches ( RootType . CPPType ) )
{
NewFilteredPermutations . Add ( PermIndex ) ;
break ;
}
}
}
}
return NewFilteredPermutations ;
}
2022-05-18 06:43:26 -04:00
TArray < int32 > URigVMTemplateNode : : FindPermutationsForTypes ( const TArray < FString > & ArgumentTypes , bool bAllowCasting )
2022-05-09 07:34:28 -04:00
{
2022-05-11 05:46:12 -04:00
TArray < int32 > Permutations ;
2022-05-09 07:34:28 -04:00
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
{
2022-05-18 06:43:26 -04:00
TArray < const FRigVMTemplateArgument * > Args ;
TArray < FString > CPPTypes ;
for ( const FString & TypePairString : ArgumentTypes )
{
FString ArgName , Type ;
if ( ! TypePairString . Split ( TEXT ( " : " ) , & ArgName , & Type ) )
{
return { } ;
}
if ( const FRigVMTemplateArgument * Argument = Template - > FindArgument ( * ArgName ) )
{
Args . Add ( Argument ) ;
CPPTypes . Add ( Type ) ;
}
else
{
return { } ;
}
}
2022-05-09 07:34:28 -04:00
for ( int32 i = 0 ; i < Template - > NumPermutations ( ) ; + + i )
{
bool bAllArgsMatched = true ;
2022-05-18 06:43:26 -04:00
for ( int32 ArgIndex = 0 ; ArgIndex < Args . Num ( ) ; + + ArgIndex )
2022-05-09 07:34:28 -04:00
{
2022-05-18 06:43:26 -04:00
const FRigVMTemplateArgument * Argument = Args [ ArgIndex ] ;
2022-05-09 07:34:28 -04:00
{
2022-05-18 06:43:26 -04:00
if ( ( bAllowCasting & & ! Argument - > GetTypes ( ) [ i ] . Matches ( CPPTypes [ ArgIndex ] ) ) | |
( ! bAllowCasting & & Argument - > GetTypes ( ) [ i ] . CPPType ! = CPPTypes [ ArgIndex ] ) )
2022-05-09 07:34:28 -04:00
{
bAllArgsMatched = false ;
break ;
}
}
}
if ( bAllArgsMatched )
{
2022-05-11 05:46:12 -04:00
Permutations . Add ( i ) ;
2022-05-09 07:34:28 -04:00
}
}
}
2022-05-11 05:46:12 -04:00
return Permutations ;
2022-05-09 07:34:28 -04:00
}
TArray < FString > URigVMTemplateNode : : GetArgumentTypesForPermutation ( const int32 InPermutationIndex )
{
TArray < FString > ArgTypes ;
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
{
for ( int32 ArgIndex = 0 ; ArgIndex < Template - > NumArguments ( ) ; + + ArgIndex )
{
const FRigVMTemplateArgument * Argument = Template - > GetArgument ( ArgIndex ) ;
if ( Argument - > GetTypes ( ) . Num ( ) > InPermutationIndex )
{
ArgTypes . Add ( Argument - > GetName ( ) . ToString ( ) + TEXT ( " : " ) + Argument - > GetTypes ( ) [ InPermutationIndex ] . CPPType ) ;
}
else
{
ArgTypes . Reset ( ) ;
return ArgTypes ;
}
}
}
return ArgTypes ;
}
bool URigVMTemplateNode : : PinNeedsFilteredTypesUpdate ( URigVMPin * InPin , const TArray < FRigVMTemplateArgument : : FType > & InTypes )
{
TArray < int32 > NewFilteredPermutations = GetNewFilteredPermutations ( InPin , InTypes ) ;
if ( NewFilteredPermutations . Num ( ) = = FilteredPermutations . Num ( ) )
{
return false ;
}
return true ;
}
bool URigVMTemplateNode : : PinNeedsFilteredTypesUpdate ( URigVMPin * InPin , URigVMPin * LinkedPin )
{
TArray < int32 > NewFilteredPermutations = GetNewFilteredPermutations ( InPin , LinkedPin ) ;
if ( NewFilteredPermutations . Num ( ) = = FilteredPermutations . Num ( ) )
{
return false ;
}
return true ;
}
bool URigVMTemplateNode : : UpdateFilteredPermutations ( URigVMPin * InPin , URigVMPin * LinkedPin )
{
ensureMsgf ( InPin - > GetNode ( ) = = this , TEXT ( " Updating filtered permutations of %s with pin from another node %s " ) , * GetNodePath ( ) , * InPin - > GetPinPath ( true ) ) ;
ensureMsgf ( LinkedPin - > GetNode ( ) ! = this , TEXT ( " Updating filtered permutations of %s with linked pin from same node %s " ) , * GetNodePath ( ) , * LinkedPin - > GetPinPath ( true ) ) ;
TArray < int32 > NewFilteredPermutations = GetNewFilteredPermutations ( InPin , LinkedPin ) ;
if ( NewFilteredPermutations . Num ( ) = = FilteredPermutations . Num ( ) )
{
return false ;
}
if ( NewFilteredPermutations . IsEmpty ( ) )
{
return false ;
}
FilteredPermutations = NewFilteredPermutations ;
return true ;
}
bool URigVMTemplateNode : : UpdateFilteredPermutations ( URigVMPin * InPin , const TArray < FRigVMTemplateArgument : : FType > & InTypes )
{
TArray < int32 > NewFilteredPermutations = GetNewFilteredPermutations ( InPin , InTypes ) ;
if ( NewFilteredPermutations . Num ( ) = = FilteredPermutations . Num ( ) )
{
return false ;
}
if ( NewFilteredPermutations . IsEmpty ( ) )
{
return false ;
}
FilteredPermutations = NewFilteredPermutations ;
return true ;
}
2022-03-01 04:23:55 -05:00
void URigVMTemplateNode : : InvalidateCache ( )
{
SupportedTypesCache . Reset ( ) ;
CachedFunction = nullptr ;
2022-05-09 14:13:48 -04:00
CachedTemplate = nullptr ;
2022-03-17 07:20:36 -04:00
ResolvedPermutations . Reset ( ) ;
2022-03-01 04:23:55 -05:00
for ( URigVMPin * Pin : GetPins ( ) )
{
if ( Pin - > IsWildCard ( ) )
{
ResolvedFunctionName . Reset ( ) ;
break ;
}
}
}
2022-05-09 07:34:28 -04:00
void URigVMTemplateNode : : InitializeFilteredPermutations ( )
{
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
{
if ( ! PreferredPermutationTypes . IsEmpty ( ) )
{
2022-05-18 06:43:26 -04:00
FilteredPermutations = FindPermutationsForTypes ( PreferredPermutationTypes ) ;
2022-05-09 07:34:28 -04:00
}
else
{
FilteredPermutations . SetNumUninitialized ( Template - > NumPermutations ( ) ) ;
for ( int32 i = 0 ; i < FilteredPermutations . Num ( ) ; + + i )
{
FilteredPermutations [ i ] = i ;
}
}
}
}
2022-05-09 14:13:48 -04:00
void URigVMTemplateNode : : InitializeFilteredPermutationsFromTypes ( )
{
if ( IsSingleton ( ) )
{
return ;
}
if ( const FRigVMTemplate * Template = GetTemplate ( ) )
{
TArray < FString > ArgTypes ;
for ( int32 ArgIndex = 0 ; ArgIndex < Template - > NumArguments ( ) ; + + ArgIndex )
{
const FRigVMTemplateArgument * Argument = Template - > GetArgument ( ArgIndex ) ;
if ( URigVMPin * Pin = FindPin ( Argument - > GetName ( ) . ToString ( ) ) )
{
2022-05-11 05:46:12 -04:00
if ( ! Pin - > IsWildCard ( ) )
{
ArgTypes . Add ( Argument - > GetName ( ) . ToString ( ) + TEXT ( " : " ) + Pin - > GetCPPType ( ) ) ;
}
2022-05-09 14:13:48 -04:00
}
}
2022-05-18 06:43:26 -04:00
TArray < int32 > Permutations = FindPermutationsForTypes ( ArgTypes ) ;
2022-05-11 05:46:12 -04:00
if ( ! Permutations . IsEmpty ( ) )
2022-05-09 14:13:48 -04:00
{
2022-05-11 05:46:12 -04:00
FilteredPermutations = Permutations ;
PreferredPermutationTypes = ArgTypes ;
2022-05-09 14:13:48 -04:00
}
else
{
InitializeFilteredPermutations ( ) ;
}
}
}