2020-01-22 17:58:55 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "RigVMCompiler/RigVMAST.h"
2020-09-24 00:43:27 -04:00
# include "RigVMCompiler/RigVMCompiler.h"
2020-12-02 10:59:58 -04:00
# include "RigVMModel/Nodes/RigVMUnitNode.h"
2020-01-22 17:58:55 -05:00
# include "RigVMModel/Nodes/RigVMParameterNode.h"
# include "RigVMModel/Nodes/RigVMVariableNode.h"
# include "RigVMModel/Nodes/RigVMCommentNode.h"
# include "RigVMModel/Nodes/RigVMRerouteNode.h"
2020-09-24 00:43:27 -04:00
# include "RigVMModel/Nodes/RigVMBranchNode.h"
# include "RigVMModel/Nodes/RigVMIfNode.h"
# include "RigVMModel/Nodes/RigVMSelectNode.h"
# include "RigVMModel/Nodes/RigVMEnumNode.h"
2020-12-01 04:05:50 -04:00
# include "RigVMModel/Nodes/RigVMFunctionReturnNode.h"
# include "RigVMModel/Nodes/RigVMFunctionEntryNode.h"
2021-08-18 06:18:21 -04:00
# include "RigVMModel/Nodes/RigVMArrayNode.h"
2020-01-22 17:58:55 -05:00
# include "RigVMModel/RigVMGraph.h"
2020-09-24 00:43:27 -04:00
# include "RigVMModel/RigVMController.h"
2020-01-22 17:58:55 -05:00
# include "RigVMCore/RigVMExecuteContext.h"
# include "Stats/StatsHierarchical.h"
2020-11-19 04:52:31 -04:00
# include "RigVMDeveloperModule.h"
2021-10-06 11:19:48 -04:00
# include "VisualGraphUtils.h"
2020-11-19 04:52:31 -04:00
2021-01-12 06:47:41 -04:00
FRigVMExprAST : : FRigVMExprAST ( EType InType , const FRigVMASTProxy & InProxy )
2020-01-22 17:58:55 -05:00
: Name ( NAME_None )
, Type ( InType )
, Index ( INDEX_NONE )
{
}
FName FRigVMExprAST : : GetTypeName ( ) const
{
switch ( GetType ( ) )
{
case EType : : Block :
{
return TEXT ( " [.Block.] " ) ;
}
case EType : : Entry :
{
return TEXT ( " [.Entry.] " ) ;
}
case EType : : CallExtern :
{
return TEXT ( " [.Call..] " ) ;
}
case EType : : NoOp :
{
return TEXT ( " [.NoOp..] " ) ;
}
case EType : : Var :
{
return TEXT ( " [.Var...] " ) ;
}
case EType : : Literal :
{
return TEXT ( " [Literal] " ) ;
}
2020-10-26 06:51:31 -04:00
case EType : : ExternalVar :
{
return TEXT ( " [ExtVar.] " ) ;
}
2020-01-22 17:58:55 -05:00
case EType : : Assign :
{
return TEXT ( " [.Assign] " ) ;
}
case EType : : Copy :
{
return TEXT ( " [.Copy..] " ) ;
}
case EType : : CachedValue :
{
return TEXT ( " [.Cache.] " ) ;
}
case EType : : Exit :
{
return TEXT ( " [.Exit..] " ) ;
}
2020-09-24 00:43:27 -04:00
case EType : : Branch :
{
return TEXT ( " [Branch.] " ) ;
}
case EType : : If :
{
return TEXT ( " [..If...] " ) ;
}
case EType : : Select :
{
return TEXT ( " [Select.] " ) ;
}
2021-08-18 06:18:21 -04:00
case EType : : Array :
{
return TEXT ( " [Array..] " ) ;
}
2020-01-22 17:58:55 -05:00
case EType : : Invalid :
{
return TEXT ( " [Invalid] " ) ;
}
default :
{
ensure ( false ) ;
}
}
return NAME_None ;
}
const FRigVMExprAST * FRigVMExprAST : : GetParent ( ) const
{
if ( Parents . Num ( ) > 0 )
{
return ParentAt ( 0 ) ;
}
return nullptr ;
}
2020-09-24 00:43:27 -04:00
const FRigVMExprAST * FRigVMExprAST : : GetFirstParentOfType ( EType InExprType ) const
{
for ( const FRigVMExprAST * Parent : Parents )
{
if ( Parent - > IsA ( InExprType ) )
{
return Parent ;
}
}
for ( const FRigVMExprAST * Parent : Parents )
{
if ( const FRigVMExprAST * GrandParent = Parent - > GetFirstParentOfType ( InExprType ) )
{
return GrandParent ;
}
}
return nullptr ;
}
const FRigVMExprAST * FRigVMExprAST : : GetFirstChildOfType ( EType InExprType ) const
{
for ( const FRigVMExprAST * Child : Children )
{
if ( Child - > IsA ( InExprType ) )
{
return Child ;
}
}
for ( const FRigVMExprAST * Child : Children )
{
if ( const FRigVMExprAST * GrandChild = Child - > GetFirstChildOfType ( InExprType ) )
{
return GrandChild ;
}
}
return nullptr ;
}
2020-01-22 17:58:55 -05:00
const FRigVMBlockExprAST * FRigVMExprAST : : GetBlock ( ) const
{
if ( Parents . Num ( ) = = 0 )
{
if ( IsA ( EType : : Block ) )
{
return To < FRigVMBlockExprAST > ( ) ;
}
2020-09-24 00:43:27 -04:00
return ParserPtr - > GetObsoleteBlock ( ) ;
2020-01-22 17:58:55 -05:00
}
const FRigVMExprAST * Parent = GetParent ( ) ;
if ( Parent - > IsA ( EType : : Block ) )
{
return Parent - > To < FRigVMBlockExprAST > ( ) ;
}
return Parent - > GetBlock ( ) ;
}
const FRigVMBlockExprAST * FRigVMExprAST : : GetRootBlock ( ) const
{
const FRigVMBlockExprAST * Block = GetBlock ( ) ;
if ( IsA ( EType : : Block ) )
{
if ( Block & & NumParents ( ) > 0 )
{
return Block - > GetRootBlock ( ) ;
}
return To < FRigVMBlockExprAST > ( ) ;
}
if ( Block )
{
return Block - > GetRootBlock ( ) ;
}
return nullptr ;
}
2020-09-24 00:43:27 -04:00
int32 FRigVMExprAST : : GetMinChildIndexWithinParent ( const FRigVMExprAST * InParentExpr ) const
{
int32 MinIndex = INDEX_NONE ;
for ( const FRigVMExprAST * Parent : Parents )
{
int32 ChildIndex = INDEX_NONE ;
if ( Parent = = InParentExpr )
{
Parent - > Children . Find ( ( FRigVMExprAST * ) this , ChildIndex ) ;
}
else
{
ChildIndex = Parent - > GetMinChildIndexWithinParent ( InParentExpr ) ;
}
if ( ChildIndex < MinIndex | | MinIndex = = INDEX_NONE )
{
MinIndex = ChildIndex ;
}
}
return MinIndex ;
}
2020-01-22 17:58:55 -05:00
void FRigVMExprAST : : AddParent ( FRigVMExprAST * InParent )
{
ensure ( InParent ! = this ) ;
if ( Parents . Contains ( InParent ) )
{
return ;
}
2020-09-24 00:43:27 -04:00
2020-01-22 17:58:55 -05:00
InParent - > Children . Add ( this ) ;
Parents . Add ( InParent ) ;
}
void FRigVMExprAST : : RemoveParent ( FRigVMExprAST * InParent )
{
if ( Parents . Remove ( InParent ) > 0 )
{
InParent - > Children . Remove ( this ) ;
}
}
void FRigVMExprAST : : RemoveChild ( FRigVMExprAST * InChild )
{
InChild - > RemoveParent ( this ) ;
}
void FRigVMExprAST : : ReplaceParent ( FRigVMExprAST * InCurrentParent , FRigVMExprAST * InNewParent )
{
for ( int32 ParentIndex = 0 ; ParentIndex < Parents . Num ( ) ; ParentIndex + + )
{
if ( Parents [ ParentIndex ] = = InCurrentParent )
{
Parents [ ParentIndex ] = InNewParent ;
InCurrentParent - > Children . Remove ( this ) ;
InNewParent - > Children . Add ( this ) ;
}
}
}
void FRigVMExprAST : : ReplaceChild ( FRigVMExprAST * InCurrentChild , FRigVMExprAST * InNewChild )
{
for ( int32 ChildIndex = 0 ; ChildIndex < Children . Num ( ) ; ChildIndex + + )
{
if ( Children [ ChildIndex ] = = InCurrentChild )
{
Children [ ChildIndex ] = InNewChild ;
InCurrentChild - > Parents . Remove ( this ) ;
InNewChild - > Parents . Add ( this ) ;
}
}
}
2020-09-24 00:43:27 -04:00
void FRigVMExprAST : : ReplaceBy ( FRigVMExprAST * InReplacement )
{
TArray < FRigVMExprAST * > PreviousParents ;
PreviousParents . Append ( Parents ) ;
for ( FRigVMExprAST * PreviousParent : PreviousParents )
{
PreviousParent - > ReplaceChild ( this , InReplacement ) ;
}
}
bool FRigVMExprAST : : IsConstant ( ) const
{
for ( FRigVMExprAST * ChildExpr : Children )
{
if ( ! ChildExpr - > IsConstant ( ) )
{
return false ;
}
}
return true ;
}
2020-01-22 17:58:55 -05:00
FString FRigVMExprAST : : DumpText ( const FString & InPrefix ) const
{
FString Result ;
if ( Name . IsNone ( ) )
{
Result = FString : : Printf ( TEXT ( " %s%s " ) , * InPrefix , * GetTypeName ( ) . ToString ( ) ) ;
}
else
{
Result = FString : : Printf ( TEXT ( " %s%s %s " ) , * InPrefix , * GetTypeName ( ) . ToString ( ) , * Name . ToString ( ) ) ;
}
if ( Children . Num ( ) > 0 )
{
FString Prefix = InPrefix ;
if ( Prefix . IsEmpty ( ) )
{
Prefix = TEXT ( " -- " ) ;
}
else
{
Prefix = TEXT ( " --- " ) + Prefix ;
}
for ( FRigVMExprAST * Child : Children )
{
Result + = TEXT ( " \n " ) + Child - > DumpText ( Prefix ) ;
}
}
return Result ;
}
bool FRigVMBlockExprAST : : ShouldExecute ( ) const
{
return ContainsEntry ( ) ;
}
bool FRigVMBlockExprAST : : ContainsEntry ( ) const
{
if ( IsA ( FRigVMExprAST : : EType : : Entry ) )
{
return true ;
}
for ( FRigVMExprAST * Expression : * this )
{
if ( Expression - > IsA ( EType : : Entry ) )
{
return true ;
}
}
return false ;
}
bool FRigVMBlockExprAST : : Contains ( const FRigVMExprAST * InExpression ) const
{
2020-09-24 00:43:27 -04:00
if ( InExpression = = this )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
return true ;
}
for ( int32 ParentIndex = 0 ; ParentIndex < InExpression - > NumParents ( ) ; ParentIndex + + )
{
const FRigVMExprAST * ParentExpr = InExpression - > ParentAt ( ParentIndex ) ;
if ( Contains ( ParentExpr ) )
2020-01-22 17:58:55 -05:00
{
return true ;
}
2020-09-24 00:43:27 -04:00
}
2020-01-22 17:58:55 -05:00
2020-09-24 00:43:27 -04:00
return false ;
}
bool FRigVMNodeExprAST : : IsConstant ( ) const
{
if ( URigVMNode * CurrentNode = GetNode ( ) )
{
if ( CurrentNode - > IsDefinedAsConstant ( ) )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
return true ;
}
else if ( CurrentNode - > IsDefinedAsVarying ( ) )
{
return false ;
2020-01-22 17:58:55 -05:00
}
2020-10-26 06:51:31 -04:00
TArray < URigVMPin * > AllPins = CurrentNode - > GetAllPinsRecursively ( ) ;
for ( URigVMPin * Pin : AllPins )
{
2021-05-14 02:36:03 -04:00
// don't flatten pins which have a watch
if ( Pin - > RequiresWatch ( false ) )
{
return false ;
}
2020-10-26 06:51:31 -04:00
}
2020-01-22 17:58:55 -05:00
}
2020-09-24 00:43:27 -04:00
return FRigVMExprAST : : IsConstant ( ) ;
}
2021-08-18 06:18:21 -04:00
const FRigVMVarExprAST * FRigVMNodeExprAST : : FindVarWithPinName ( const FName & InPinName ) const
{
if ( URigVMNode * CurrentNode = GetNode ( ) )
{
for ( URigVMPin * Pin : CurrentNode - > GetPins ( ) )
{
if ( Pin - > GetFName ( ) = = InPinName )
{
const int32 PinIndex = Pin - > GetPinIndex ( ) ;
if ( PinIndex < = NumChildren ( ) )
{
const FRigVMExprAST * Child = ChildAt ( PinIndex ) ;
if ( Child - > IsA ( FRigVMExprAST : : Var ) )
{
return Child - > To < FRigVMVarExprAST > ( ) ;
}
}
}
}
}
return nullptr ;
}
2021-01-12 06:47:41 -04:00
FRigVMNodeExprAST : : FRigVMNodeExprAST ( EType InType , const FRigVMASTProxy & InNodeProxy )
2020-09-24 00:43:27 -04:00
: FRigVMBlockExprAST ( InType )
2021-01-12 06:47:41 -04:00
, Proxy ( InNodeProxy )
2020-09-24 00:43:27 -04:00
{
2020-01-22 17:58:55 -05:00
}
FName FRigVMEntryExprAST : : GetEventName ( ) const
{
if ( URigVMNode * EventNode = GetNode ( ) )
{
return EventNode - > GetEventName ( ) ;
}
return NAME_None ;
}
2020-09-24 00:43:27 -04:00
bool FRigVMVarExprAST : : IsConstant ( ) const
{
if ( GetPin ( ) - > IsExecuteContext ( ) )
{
return false ;
}
if ( GetPin ( ) - > IsDefinedAsConstant ( ) )
{
return true ;
}
if ( SupportsSoftLinks ( ) )
{
return false ;
}
ERigVMPinDirection Direction = GetPin ( ) - > GetDirection ( ) ;
if ( Direction = = ERigVMPinDirection : : Hidden )
{
if ( Cast < URigVMVariableNode > ( GetPin ( ) - > GetNode ( ) ) )
{
if ( GetPin ( ) - > GetName ( ) = = URigVMVariableNode : : VariableName )
{
return true ;
}
}
return false ;
}
if ( GetPin ( ) - > GetDirection ( ) = = ERigVMPinDirection : : IO | |
GetPin ( ) - > GetDirection ( ) = = ERigVMPinDirection : : Output )
{
if ( GetPin ( ) - > GetNode ( ) - > IsDefinedAsVarying ( ) )
{
return false ;
}
}
return FRigVMExprAST : : IsConstant ( ) ;
}
2020-01-22 17:58:55 -05:00
FString FRigVMVarExprAST : : GetCPPType ( ) const
{
2021-01-12 06:47:41 -04:00
return GetPin ( ) - > GetCPPType ( ) ;
2020-01-22 17:58:55 -05:00
}
UObject * FRigVMVarExprAST : : GetCPPTypeObject ( ) const
{
2021-01-12 06:47:41 -04:00
return GetPin ( ) - > GetCPPTypeObject ( ) ;
2020-01-22 17:58:55 -05:00
}
ERigVMPinDirection FRigVMVarExprAST : : GetPinDirection ( ) const
{
2021-01-12 06:47:41 -04:00
return GetPin ( ) - > GetDirection ( ) ;
2020-01-22 17:58:55 -05:00
}
FString FRigVMVarExprAST : : GetDefaultValue ( ) const
{
2021-01-19 04:57:43 -04:00
return GetPin ( ) - > GetDefaultValue ( URigVMPin : : FPinOverride ( GetProxy ( ) , GetParser ( ) - > GetPinOverrides ( ) ) ) ;
2020-01-22 17:58:55 -05:00
}
bool FRigVMVarExprAST : : IsExecuteContext ( ) const
{
2021-01-12 06:47:41 -04:00
return GetPin ( ) - > IsExecuteContext ( ) ;
2020-01-22 17:58:55 -05:00
}
bool FRigVMVarExprAST : : IsGraphParameter ( ) const
{
2021-01-12 06:47:41 -04:00
if ( Cast < URigVMParameterNode > ( GetPin ( ) - > GetNode ( ) ) )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
return GetPin ( ) - > GetName ( ) = = TEXT ( " Value " ) ;
2020-01-22 17:58:55 -05:00
}
return false ;
}
bool FRigVMVarExprAST : : IsGraphVariable ( ) const
{
2021-01-12 06:47:41 -04:00
if ( Cast < URigVMVariableNode > ( GetPin ( ) - > GetNode ( ) ) )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
return GetPin ( ) - > GetName ( ) = = URigVMVariableNode : : ValueName ;
2020-01-22 17:58:55 -05:00
}
return false ;
}
2020-09-24 00:43:27 -04:00
bool FRigVMVarExprAST : : IsEnumValue ( ) const
{
2021-01-12 06:47:41 -04:00
if ( Cast < URigVMEnumNode > ( GetPin ( ) - > GetNode ( ) ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
return GetPin ( ) - > GetName ( ) = = TEXT ( " EnumIndex " ) ;
2020-09-24 00:43:27 -04:00
}
return false ;
}
bool FRigVMVarExprAST : : SupportsSoftLinks ( ) const
{
2021-01-12 06:47:41 -04:00
if ( URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( GetPin ( ) - > GetNode ( ) ) )
2020-09-24 00:43:27 -04:00
{
2020-12-02 10:59:58 -04:00
if ( UnitNode - > IsLoopNode ( ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
if ( GetPin ( ) - > GetFName ( ) ! = FRigVMStruct : : ExecuteContextName & &
GetPin ( ) - > GetFName ( ) ! = FRigVMStruct : : ForLoopCompletedPinName )
2020-09-24 00:43:27 -04:00
{
return true ;
}
}
}
2021-08-18 06:18:21 -04:00
else if ( URigVMArrayNode * ArrayNode = Cast < URigVMArrayNode > ( GetPin ( ) - > GetNode ( ) ) )
{
if ( ArrayNode - > IsLoopNode ( ) )
{
if ( GetPin ( ) - > GetFName ( ) ! = FRigVMStruct : : ExecuteContextName & &
GetPin ( ) - > GetName ( ) ! = URigVMArrayNode : : CompletedName )
{
return true ;
}
}
}
2020-09-24 00:43:27 -04:00
return false ;
}
bool FRigVMBranchExprAST : : IsConstant ( ) const
{
if ( IsAlwaysTrue ( ) )
{
return GetTrueExpr ( ) - > IsConstant ( ) ;
}
else if ( IsAlwaysFalse ( ) )
{
return GetFalseExpr ( ) - > IsConstant ( ) ;
}
return FRigVMNodeExprAST : : IsConstant ( ) ;
}
bool FRigVMBranchExprAST : : IsAlwaysTrue ( ) const
{
const FRigVMVarExprAST * ConditionExpr = GetConditionExpr ( ) ;
if ( ConditionExpr - > IsA ( EType : : Literal ) )
{
const FString & PinDefaultValue = ConditionExpr - > GetDefaultValue ( ) ;
return PinDefaultValue = = TEXT ( " True " ) ;
}
return false ;
}
bool FRigVMBranchExprAST : : IsAlwaysFalse ( ) const
{
const FRigVMVarExprAST * ConditionExpr = GetConditionExpr ( ) ;
if ( ConditionExpr - > IsA ( EType : : Literal ) )
{
const FString & PinDefaultValue = ConditionExpr - > GetDefaultValue ( ) ;
return PinDefaultValue = = TEXT ( " False " ) | | PinDefaultValue . IsEmpty ( ) ;
}
return false ;
}
bool FRigVMIfExprAST : : IsConstant ( ) const
{
if ( IsAlwaysTrue ( ) )
{
return GetTrueExpr ( ) - > IsConstant ( ) ;
}
else if ( IsAlwaysFalse ( ) )
{
return GetFalseExpr ( ) - > IsConstant ( ) ;
}
return FRigVMNodeExprAST : : IsConstant ( ) ;
}
bool FRigVMIfExprAST : : IsAlwaysTrue ( ) const
{
const FRigVMVarExprAST * ConditionExpr = GetConditionExpr ( ) ;
if ( ConditionExpr - > IsA ( EType : : Literal ) )
{
const FString & PinDefaultValue = ConditionExpr - > GetDefaultValue ( ) ;
return PinDefaultValue = = TEXT ( " True " ) ;
}
return false ;
}
bool FRigVMIfExprAST : : IsAlwaysFalse ( ) const
{
const FRigVMVarExprAST * ConditionExpr = GetConditionExpr ( ) ;
if ( ConditionExpr - > IsA ( EType : : Literal ) )
{
const FString & PinDefaultValue = ConditionExpr - > GetDefaultValue ( ) ;
return PinDefaultValue = = TEXT ( " False " ) | | PinDefaultValue . IsEmpty ( ) ;
}
return false ;
}
bool FRigVMSelectExprAST : : IsConstant ( ) const
{
int32 ConstantCaseIndex = GetConstantValueIndex ( ) ;
if ( ConstantCaseIndex ! = INDEX_NONE )
{
return GetValueExpr ( ConstantCaseIndex ) - > IsConstant ( ) ;
}
return FRigVMNodeExprAST : : IsConstant ( ) ;
}
int32 FRigVMSelectExprAST : : GetConstantValueIndex ( ) const
{
const FRigVMVarExprAST * IndexExpr = GetIndexExpr ( ) ;
if ( IndexExpr - > IsA ( EType : : Literal ) )
{
int32 NumCases = NumValues ( ) ;
if ( NumCases = = 0 )
{
return INDEX_NONE ;
}
const FString & PinDefaultValue = IndexExpr - > GetDefaultValue ( ) ;
int32 CaseIndex = 0 ;
if ( ! PinDefaultValue . IsEmpty ( ) )
{
CaseIndex = FCString : : Atoi ( * PinDefaultValue ) ;
}
return FMath : : Clamp < int32 > ( CaseIndex , 0 , NumCases - 1 ) ;
}
return INDEX_NONE ;
}
int32 FRigVMSelectExprAST : : NumValues ( ) const
{
return GetNode ( ) - > FindPin ( URigVMSelectNode : : ValueName ) - > GetArraySize ( ) ;
}
2021-01-19 07:26:41 -04:00
void FRigVMParserASTSettings : : Report ( EMessageSeverity : : Type InSeverity , UObject * InSubject , const FString & InMessage ) const
{
if ( ReportDelegate . IsBound ( ) )
{
ReportDelegate . Execute ( InSeverity , InSubject , InMessage ) ;
}
else
{
if ( InSeverity = = EMessageSeverity : : Error )
{
FScriptExceptionHandler : : Get ( ) . HandleException ( ELogVerbosity : : Error , * InMessage , * FString ( ) ) ;
}
else if ( InSeverity = = EMessageSeverity : : Warning )
{
FScriptExceptionHandler : : Get ( ) . HandleException ( ELogVerbosity : : Warning , * InMessage , * FString ( ) ) ;
}
else
{
UE_LOG ( LogRigVMDeveloper , Display , TEXT ( " %s " ) , * InMessage ) ;
}
}
}
2021-01-12 06:47:41 -04:00
const TArray < FRigVMASTProxy > FRigVMParserAST : : EmptyProxyArray ;
2020-11-18 07:48:31 -04:00
2020-09-24 00:43:27 -04:00
FRigVMParserAST : : FRigVMParserAST ( URigVMGraph * InGraph , URigVMController * InController , const FRigVMParserASTSettings & InSettings , const TArray < FRigVMExternalVariable > & InExternalVariables , const TArray < FRigVMUserDataArray > & InRigVMUserData )
2020-01-22 17:58:55 -05:00
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2020-09-24 00:43:27 -04:00
2021-01-19 07:26:41 -04:00
Settings = InSettings ;
2020-09-24 00:43:27 -04:00
ObsoleteBlock = nullptr ;
2020-01-22 17:58:55 -05:00
LastCycleCheckExpr = nullptr ;
2020-10-26 12:29:38 -04:00
LinksToSkip = InSettings . LinksToSkip ;
2020-01-22 17:58:55 -05:00
2020-11-18 07:48:31 -04:00
// construct the inlined nodes and links information
Inline ( InGraph ) ;
2021-01-12 06:47:41 -04:00
for ( const FRigVMASTProxy & NodeProxy : NodeProxies )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
URigVMNode * Node = NodeProxy . GetSubjectChecked < URigVMNode > ( ) ;
2020-01-22 17:58:55 -05:00
if ( Node - > IsEvent ( ) )
{
2021-01-12 06:47:41 -04:00
TraverseMutableNode ( NodeProxy , nullptr ) ;
2020-01-22 17:58:55 -05:00
}
}
// traverse all remaining mutable nodes,
// followed by a pass for all remaining non-mutable nodes
for ( int32 PassIndex = 0 ; PassIndex < 2 ; PassIndex + + )
{
const bool bTraverseMutable = PassIndex = = 0 ;
2021-01-12 06:47:41 -04:00
for ( int32 NodeIndex = 0 ; NodeIndex < NodeProxies . Num ( ) ; NodeIndex + + )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
if ( const int32 * ExprIndex = NodeExpressionIndex . Find ( NodeProxies [ NodeIndex ] ) )
2020-01-22 17:58:55 -05:00
{
2020-02-18 09:32:18 -05:00
if ( * ExprIndex ! = INDEX_NONE )
{
continue ;
}
2020-01-22 17:58:55 -05:00
}
2021-01-12 06:47:41 -04:00
URigVMNode * Node = NodeProxies [ NodeIndex ] . GetSubjectChecked < URigVMNode > ( ) ;
if ( Node - > IsMutable ( ) = = bTraverseMutable )
2020-01-22 17:58:55 -05:00
{
if ( bTraverseMutable )
{
2021-01-12 06:47:41 -04:00
TraverseMutableNode ( NodeProxies [ NodeIndex ] , GetObsoleteBlock ( ) ) ;
2020-01-22 17:58:55 -05:00
}
else
{
2021-01-12 06:47:41 -04:00
TraverseNode ( NodeProxies [ NodeIndex ] , GetObsoleteBlock ( ) ) ;
2020-01-22 17:58:55 -05:00
}
}
}
}
FoldEntries ( ) ;
InjectExitsToEntries ( ) ;
2020-11-18 07:48:31 -04:00
FoldNoOps ( ) ;
2020-01-22 17:58:55 -05:00
2020-09-24 00:43:27 -04:00
// keep folding constant branches and values while we can
bool bContinueToFoldConstantBranches = InSettings . bFoldConstantBranches ;
while ( bContinueToFoldConstantBranches )
{
bContinueToFoldConstantBranches = false ;
if ( FoldConstantValuesToLiterals ( InGraph , InController , InExternalVariables , InRigVMUserData ) )
{
bContinueToFoldConstantBranches = true ;
}
if ( FoldUnreachableBranches ( InGraph ) )
{
bContinueToFoldConstantBranches = true ;
}
}
BubbleUpExpressions ( ) ;
2020-01-22 17:58:55 -05:00
if ( InSettings . bFoldAssignments )
{
FoldAssignments ( ) ;
}
if ( InSettings . bFoldLiterals )
{
FoldLiterals ( ) ;
}
}
2021-01-12 06:47:41 -04:00
FRigVMParserAST : : FRigVMParserAST ( URigVMGraph * InGraph , const TArray < FRigVMASTProxy > & InNodesToCompute )
2020-09-24 00:43:27 -04:00
{
LastCycleCheckExpr = nullptr ;
2021-01-12 06:47:41 -04:00
FRigVMBlockExprAST * Block = MakeExpr < FRigVMBlockExprAST > ( FRigVMExprAST : : EType : : Block , FRigVMASTProxy ( ) ) ;
2020-09-24 00:43:27 -04:00
Block - > Name = TEXT ( " NodesToCompute " ) ;
RootExpressions . Add ( Block ) ;
2021-01-12 06:47:41 -04:00
NodeProxies = InNodesToCompute ;
2020-11-18 07:48:31 -04:00
Inline ( InGraph , InNodesToCompute ) ;
2021-01-12 06:47:41 -04:00
for ( const FRigVMASTProxy & NodeProxy : NodeProxies )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
URigVMNode * Node = NodeProxy . GetSubjectChecked < URigVMNode > ( ) ;
2020-09-24 00:43:27 -04:00
if ( Node - > IsEvent ( ) )
{
continue ;
}
if ( Node - > IsMutable ( ) )
{
continue ;
}
2021-01-12 06:47:41 -04:00
TraverseNode ( NodeProxy , Block ) ;
2020-09-24 00:43:27 -04:00
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * ExitExpr = MakeExpr < FRigVMExitExprAST > ( FRigVMASTProxy ( ) ) ;
2020-09-24 00:43:27 -04:00
ExitExpr - > AddParent ( Block ) ;
}
2020-01-22 17:58:55 -05:00
FRigVMParserAST : : ~ FRigVMParserAST ( )
{
for ( FRigVMExprAST * Expression : Expressions )
{
delete ( Expression ) ;
}
Expressions . Empty ( ) ;
// root expressions are a subset of the
// expressions array, so no cleanup necessary
RootExpressions . Empty ( ) ;
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * FRigVMParserAST : : TraverseMutableNode ( const FRigVMASTProxy & InNodeProxy , FRigVMExprAST * InParentExpr )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
if ( SubjectToExpression . Contains ( InNodeProxy ) )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
return SubjectToExpression . FindChecked ( InNodeProxy ) ;
2020-01-22 17:58:55 -05:00
}
2021-04-07 13:09:20 -04:00
URigVMNode * Node = InNodeProxy . GetSubjectChecked < URigVMNode > ( ) ;
if ( Node - > HasOrphanedPins ( ) )
{
return nullptr ;
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * NodeExpr = CreateExpressionForNode ( InNodeProxy , InParentExpr ) ;
2020-09-24 00:43:27 -04:00
if ( NodeExpr )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
if ( InParentExpr = = nullptr )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
InParentExpr = NodeExpr ;
2020-01-22 17:58:55 -05:00
}
2020-09-24 00:43:27 -04:00
2021-01-12 06:47:41 -04:00
TraversePins ( InNodeProxy , NodeExpr ) ;
2020-09-24 00:43:27 -04:00
2021-01-12 06:47:41 -04:00
for ( URigVMPin * SourcePin : Node - > GetPins ( ) )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
if ( SourcePin - > GetDirection ( ) = = ERigVMPinDirection : : Output | | SourcePin - > GetDirection ( ) = = ERigVMPinDirection : : IO )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
if ( SourcePin - > IsExecuteContext ( ) )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SourcePinProxy = InNodeProxy . GetSibling ( SourcePin ) ;
2020-09-24 00:43:27 -04:00
FRigVMExprAST * ParentExpr = InParentExpr ;
2021-08-18 06:18:21 -04:00
if ( NodeExpr - > IsA ( FRigVMExprAST : : Branch ) | | Node - > IsLoopNode ( ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
if ( FRigVMExprAST * * PinExpr = SubjectToExpression . Find ( SourcePinProxy ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMBlockExprAST * BlockExpr = MakeExpr < FRigVMBlockExprAST > ( FRigVMExprAST : : EType : : Block , FRigVMASTProxy ( ) ) ;
2020-09-24 00:43:27 -04:00
BlockExpr - > AddParent ( * PinExpr ) ;
BlockExpr - > Name = SourcePin - > GetFName ( ) ;
ParentExpr = BlockExpr ;
}
}
2021-01-12 06:47:41 -04:00
const TArray < FRigVMASTProxy > & TargetPins = GetTargetPins ( SourcePinProxy ) ;
for ( const FRigVMASTProxy & TargetPinProxy : TargetPins )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
if ( ShouldLinkBeSkipped ( FRigVMPinProxyPair ( SourcePinProxy , TargetPinProxy ) ) )
2020-10-26 12:29:38 -04:00
{
continue ;
}
2021-01-12 06:47:41 -04:00
URigVMNode * TargetNode = TargetPinProxy . GetSubjectChecked < URigVMPin > ( ) - > GetNode ( ) ;
FRigVMASTProxy TargetNodeProxy = TargetPinProxy . GetSibling ( TargetNode ) ;
TraverseMutableNode ( TargetNodeProxy , ParentExpr ) ;
2020-09-24 00:43:27 -04:00
}
2020-01-22 17:58:55 -05:00
}
}
}
}
return NodeExpr ;
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * FRigVMParserAST : : TraverseNode ( const FRigVMASTProxy & InNodeProxy , FRigVMExprAST * InParentExpr )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
URigVMNode * Node = InNodeProxy . GetSubjectChecked < URigVMNode > ( ) ;
if ( Cast < URigVMCommentNode > ( Node ) )
2020-01-22 17:58:55 -05:00
{
return nullptr ;
}
2021-04-07 13:09:20 -04:00
if ( Node - > HasOrphanedPins ( ) )
{
return nullptr ;
}
2021-01-12 06:47:41 -04:00
if ( SubjectToExpression . Contains ( InNodeProxy ) )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
FRigVMExprAST * NodeExpr = SubjectToExpression . FindChecked ( InNodeProxy ) ;
2020-01-22 17:58:55 -05:00
NodeExpr - > AddParent ( InParentExpr ) ;
return NodeExpr ;
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * NodeExpr = CreateExpressionForNode ( InNodeProxy , InParentExpr ) ;
2020-09-24 00:43:27 -04:00
if ( NodeExpr )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
TraversePins ( InNodeProxy , NodeExpr ) ;
2020-09-24 00:43:27 -04:00
}
return NodeExpr ;
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * FRigVMParserAST : : CreateExpressionForNode ( const FRigVMASTProxy & InNodeProxy , FRigVMExprAST * InParentExpr )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
URigVMNode * Node = InNodeProxy . GetSubjectChecked < URigVMNode > ( ) ;
2020-09-24 00:43:27 -04:00
FRigVMExprAST * NodeExpr = nullptr ;
2021-01-12 06:47:41 -04:00
if ( Node - > IsEvent ( ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
NodeExpr = MakeExpr < FRigVMEntryExprAST > ( InNodeProxy ) ;
NodeExpr - > Name = Node - > GetEventName ( ) ;
2020-01-22 17:58:55 -05:00
}
else
{
2021-01-12 06:47:41 -04:00
if ( InNodeProxy . IsA < URigVMRerouteNode > ( ) | |
InNodeProxy . IsA < URigVMParameterNode > ( ) | |
InNodeProxy . IsA < URigVMVariableNode > ( ) | |
2021-06-16 08:58:10 -04:00
InNodeProxy . IsA < URigVMEnumNode > ( ) | |
InNodeProxy . IsA < URigVMLibraryNode > ( ) | |
InNodeProxy . IsA < URigVMFunctionEntryNode > ( ) | |
InNodeProxy . IsA < URigVMFunctionReturnNode > ( ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
NodeExpr = MakeExpr < FRigVMNoOpExprAST > ( InNodeProxy ) ;
2020-09-24 00:43:27 -04:00
}
2021-01-12 06:47:41 -04:00
else if ( InNodeProxy . IsA < URigVMBranchNode > ( ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
NodeExpr = MakeExpr < FRigVMBranchExprAST > ( InNodeProxy ) ;
2020-09-24 00:43:27 -04:00
}
2021-01-12 06:47:41 -04:00
else if ( InNodeProxy . IsA < URigVMIfNode > ( ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
NodeExpr = MakeExpr < FRigVMIfExprAST > ( InNodeProxy ) ;
2020-09-24 00:43:27 -04:00
}
2021-01-12 06:47:41 -04:00
else if ( InNodeProxy . IsA < URigVMSelectNode > ( ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
NodeExpr = MakeExpr < FRigVMSelectExprAST > ( InNodeProxy ) ;
2020-09-24 00:43:27 -04:00
}
2021-08-18 06:18:21 -04:00
else if ( InNodeProxy . IsA < URigVMArrayNode > ( ) )
{
NodeExpr = MakeExpr < FRigVMArrayExprAST > ( InNodeProxy ) ;
}
2020-09-24 00:43:27 -04:00
else
{
2021-01-12 06:47:41 -04:00
NodeExpr = MakeExpr < FRigVMCallExternExprAST > ( InNodeProxy ) ;
2020-09-24 00:43:27 -04:00
}
2021-01-12 06:47:41 -04:00
NodeExpr - > Name = Node - > GetFName ( ) ;
2020-09-24 00:43:27 -04:00
}
if ( InParentExpr ! = nullptr )
{
NodeExpr - > AddParent ( InParentExpr ) ;
}
else
{
RootExpressions . Add ( NodeExpr ) ;
2020-01-22 17:58:55 -05:00
}
2021-01-12 06:47:41 -04:00
SubjectToExpression . Add ( InNodeProxy , NodeExpr ) ;
NodeExpressionIndex . Add ( InNodeProxy , NodeExpr - > GetIndex ( ) ) ;
2020-01-22 17:58:55 -05:00
return NodeExpr ;
}
2021-01-12 06:47:41 -04:00
TArray < FRigVMExprAST * > FRigVMParserAST : : TraversePins ( const FRigVMASTProxy & InNodeProxy , FRigVMExprAST * InParentExpr )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
URigVMNode * Node = InNodeProxy . GetSubjectChecked < URigVMNode > ( ) ;
2020-01-22 17:58:55 -05:00
TArray < FRigVMExprAST * > PinExpressions ;
2021-01-12 06:47:41 -04:00
for ( URigVMPin * Pin : Node - > GetPins ( ) )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy PinProxy = InNodeProxy . GetSibling ( Pin ) ;
2020-09-24 00:43:27 -04:00
if ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : Input & &
InParentExpr - > IsA ( FRigVMExprAST : : EType : : Select ) )
{
if ( Pin - > GetName ( ) = = URigVMSelectNode : : ValueName )
{
const TArray < URigVMPin * > & CasePins = Pin - > GetSubPins ( ) ;
for ( URigVMPin * CasePin : CasePins )
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy CasePinProxy = PinProxy . GetSibling ( CasePin ) ;
PinExpressions . Add ( TraversePin ( CasePinProxy , InParentExpr ) ) ;
2020-09-24 00:43:27 -04:00
}
continue ;
}
}
2021-01-12 06:47:41 -04:00
PinExpressions . Add ( TraversePin ( PinProxy , InParentExpr ) ) ;
2020-01-22 17:58:55 -05:00
}
return PinExpressions ;
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * FRigVMParserAST : : TraversePin ( const FRigVMASTProxy & InPinProxy , FRigVMExprAST * InParentExpr )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
ensure ( ! SubjectToExpression . Contains ( InPinProxy ) ) ;
2020-01-22 17:58:55 -05:00
2021-01-12 06:47:41 -04:00
URigVMPin * Pin = InPinProxy . GetSubjectChecked < URigVMPin > ( ) ;
2021-01-19 04:57:43 -04:00
URigVMPin : : FPinOverride PinOverride ( InPinProxy , PinOverrides ) ;
2021-01-12 06:47:41 -04:00
TArray < FRigVMPinProxyPair > Links = GetSourceLinks ( InPinProxy , true ) ;
2020-10-26 12:29:38 -04:00
if ( LinksToSkip . Num ( ) > 0 )
{
2021-01-12 06:47:41 -04:00
Links . RemoveAll ( [ this ] ( const FRigVMPinProxyPair & LinkToCheck )
2020-11-18 07:48:31 -04:00
{
return this - > ShouldLinkBeSkipped ( LinkToCheck ) ;
}
) ;
2020-10-26 12:29:38 -04:00
}
2020-01-22 17:58:55 -05:00
FRigVMExprAST * PinExpr = nullptr ;
2021-01-12 06:47:41 -04:00
if ( Cast < URigVMVariableNode > ( Pin - > GetNode ( ) ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
if ( Pin - > GetName ( ) = = URigVMVariableNode : : VariableName )
2020-09-24 00:43:27 -04:00
{
return nullptr ;
}
}
2021-01-12 06:47:41 -04:00
else if ( Cast < URigVMParameterNode > ( Pin - > GetNode ( ) ) | |
Cast < URigVMEnumNode > ( Pin - > GetNode ( ) ) )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
if ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : Visible )
2020-01-22 17:58:55 -05:00
{
return nullptr ;
}
}
2021-01-12 06:47:41 -04:00
if ( ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : Input | |
Pin - > GetDirection ( ) = = ERigVMPinDirection : : Visible ) & &
2021-11-29 11:26:01 -05:00
Links . Num ( ) = = 0 )
2020-01-22 17:58:55 -05:00
{
2021-11-29 11:26:01 -05:00
if ( Cast < URigVMParameterNode > ( Pin - > GetNode ( ) ) | |
2021-11-15 05:32:56 -05:00
Cast < URigVMVariableNode > ( Pin - > GetNode ( ) ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
PinExpr = MakeExpr < FRigVMVarExprAST > ( FRigVMExprAST : : EType : : Var , InPinProxy ) ;
FRigVMExprAST * PinLiteralExpr = MakeExpr < FRigVMLiteralExprAST > ( InPinProxy ) ;
2020-09-24 00:43:27 -04:00
PinLiteralExpr - > Name = PinExpr - > Name ;
2021-01-12 06:47:41 -04:00
FRigVMExprAST * PinCopyExpr = MakeExpr < FRigVMCopyExprAST > ( InPinProxy , InPinProxy ) ;
2020-09-24 00:43:27 -04:00
PinCopyExpr - > AddParent ( PinExpr ) ;
PinLiteralExpr - > AddParent ( PinCopyExpr ) ;
}
else
{
2021-01-12 06:47:41 -04:00
PinExpr = MakeExpr < FRigVMLiteralExprAST > ( InPinProxy ) ;
2020-09-24 00:43:27 -04:00
}
}
2021-01-12 06:47:41 -04:00
else if ( Cast < URigVMEnumNode > ( Pin - > GetNode ( ) ) )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
PinExpr = MakeExpr < FRigVMLiteralExprAST > ( InPinProxy ) ;
2020-01-22 17:58:55 -05:00
}
else
{
2021-01-12 06:47:41 -04:00
PinExpr = MakeExpr < FRigVMVarExprAST > ( FRigVMExprAST : : EType : : Var , InPinProxy ) ;
2020-01-22 17:58:55 -05:00
}
2020-09-24 00:43:27 -04:00
2020-01-22 17:58:55 -05:00
PinExpr - > AddParent ( InParentExpr ) ;
2021-01-12 06:47:41 -04:00
PinExpr - > Name = * Pin - > GetPinPath ( ) ;
SubjectToExpression . Add ( InPinProxy , PinExpr ) ;
2020-01-22 17:58:55 -05:00
2021-01-12 06:47:41 -04:00
if ( Pin - > IsExecuteContext ( ) )
2020-01-22 17:58:55 -05:00
{
return PinExpr ;
}
2020-10-26 06:51:31 -04:00
if ( PinExpr - > IsA ( FRigVMExprAST : : ExternalVar ) )
{
return PinExpr ;
}
2021-01-12 06:47:41 -04:00
if ( ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : IO | |
Pin - > GetDirection ( ) = = ERigVMPinDirection : : Input )
& & ! Pin - > IsExecuteContext ( ) )
2020-01-22 17:58:55 -05:00
{
bool bHasSourceLinkToRoot = false ;
2021-01-12 06:47:41 -04:00
URigVMPin * RootPin = Pin - > GetRootPin ( ) ;
for ( const FRigVMPinProxyPair & SourceLink : Links )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
if ( SourceLink . Value . GetSubject ( ) = = RootPin )
2020-01-22 17:58:55 -05:00
{
bHasSourceLinkToRoot = true ;
break ;
}
}
2020-09-24 00:43:27 -04:00
if ( ! bHasSourceLinkToRoot & &
2021-01-12 06:47:41 -04:00
GetSourcePins ( InPinProxy ) . Num ( ) = = 0 & &
2021-11-29 11:26:01 -05:00
( Pin - > GetDirection ( ) = = ERigVMPinDirection : : IO | | Links . Num ( ) > 0 ) )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
FRigVMLiteralExprAST * LiteralExpr = MakeExpr < FRigVMLiteralExprAST > ( InPinProxy ) ;
FRigVMCopyExprAST * LiteralCopyExpr = MakeExpr < FRigVMCopyExprAST > ( InPinProxy , InPinProxy ) ;
LiteralCopyExpr - > Name = * FString : : Printf ( TEXT ( " %s -> %s " ) , * Pin - > GetPinPath ( ) , * Pin - > GetPinPath ( ) ) ;
2020-01-22 17:58:55 -05:00
LiteralCopyExpr - > AddParent ( PinExpr ) ;
LiteralExpr - > AddParent ( LiteralCopyExpr ) ;
2021-01-12 06:47:41 -04:00
LiteralExpr - > Name = * Pin - > GetPinPath ( ) ;
2020-01-22 17:58:55 -05:00
2021-01-12 06:47:41 -04:00
SubjectToExpression [ InPinProxy ] = LiteralExpr ;
2020-01-22 17:58:55 -05:00
}
}
2020-09-24 00:43:27 -04:00
FRigVMExprAST * ParentExprForLinks = PinExpr ;
2021-01-12 06:47:41 -04:00
if ( ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : IO | | Pin - > GetDirection ( ) = = ERigVMPinDirection : : Input ) & &
2020-09-24 00:43:27 -04:00
( InParentExpr - > IsA ( FRigVMExprAST : : If ) | | InParentExpr - > IsA ( FRigVMExprAST : : Select ) ) & &
2020-11-18 07:48:31 -04:00
Links . Num ( ) > 0 )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMBlockExprAST * BlockExpr = MakeExpr < FRigVMBlockExprAST > ( FRigVMExprAST : : EType : : Block , FRigVMASTProxy ( ) ) ;
2020-09-24 00:43:27 -04:00
BlockExpr - > AddParent ( PinExpr ) ;
2021-01-12 06:47:41 -04:00
BlockExpr - > Name = Pin - > GetFName ( ) ;
2020-09-24 00:43:27 -04:00
ParentExprForLinks = BlockExpr ;
}
2020-01-22 17:58:55 -05:00
2021-01-12 06:47:41 -04:00
for ( const FRigVMPinProxyPair & SourceLink : Links )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
TraverseLink ( SourceLink , ParentExprForLinks ) ;
2020-01-22 17:58:55 -05:00
}
return PinExpr ;
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * FRigVMParserAST : : TraverseLink ( const FRigVMPinProxyPair & InLink , FRigVMExprAST * InParentExpr )
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
const FRigVMASTProxy & SourceProxy = InLink . Key ;
const FRigVMASTProxy & TargetProxy = InLink . Value ;
URigVMPin * SourcePin = SourceProxy . GetSubjectChecked < URigVMPin > ( ) ;
URigVMPin * TargetPin = TargetProxy . GetSubjectChecked < URigVMPin > ( ) ;
2020-01-22 17:58:55 -05:00
URigVMPin * SourceRootPin = SourcePin - > GetRootPin ( ) ;
URigVMPin * TargetRootPin = TargetPin - > GetRootPin ( ) ;
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SourceNodeProxy = SourceProxy . GetSibling ( SourcePin - > GetNode ( ) ) ;
2020-01-22 17:58:55 -05:00
bool bRequiresCopy = SourceRootPin ! = SourcePin | | TargetRootPin ! = TargetPin ;
if ( ! bRequiresCopy )
{
if ( Cast < URigVMParameterNode > ( TargetRootPin - > GetNode ( ) ) | |
Cast < URigVMVariableNode > ( TargetRootPin - > GetNode ( ) ) )
{
bRequiresCopy = true ;
}
}
2020-09-24 00:43:27 -04:00
2020-01-22 17:58:55 -05:00
FRigVMAssignExprAST * AssignExpr = nullptr ;
if ( bRequiresCopy )
{
2021-01-12 06:47:41 -04:00
AssignExpr = MakeExpr < FRigVMCopyExprAST > ( SourceProxy , TargetProxy ) ;
2020-01-22 17:58:55 -05:00
}
else
{
2021-01-12 06:47:41 -04:00
AssignExpr = MakeExpr < FRigVMAssignExprAST > ( FRigVMExprAST : : EType : : Assign , SourceProxy , TargetProxy ) ;
2020-01-22 17:58:55 -05:00
}
2020-11-18 07:48:31 -04:00
AssignExpr - > Name = * GetLinkAsString ( InLink ) ;
2020-01-22 17:58:55 -05:00
AssignExpr - > AddParent ( InParentExpr ) ;
2021-01-12 06:47:41 -04:00
FRigVMExprAST * NodeExpr = TraverseNode ( SourceNodeProxy , AssignExpr ) ;
2020-09-24 00:43:27 -04:00
if ( NodeExpr )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
// if this is a copy expression - we should require the copy to use a ref instead
if ( NodeExpr - > IsA ( FRigVMExprAST : : EType : : CallExtern ) | |
NodeExpr - > IsA ( FRigVMExprAST : : EType : : If ) | |
2021-08-18 06:18:21 -04:00
NodeExpr - > IsA ( FRigVMExprAST : : EType : : Select ) | |
NodeExpr - > IsA ( FRigVMExprAST : : EType : : Array ) )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
for ( FRigVMExprAST * ChildExpr : * NodeExpr )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
if ( ChildExpr - > IsA ( FRigVMExprAST : : EType : : Var ) )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
FRigVMVarExprAST * VarExpr = ChildExpr - > To < FRigVMVarExprAST > ( ) ;
if ( VarExpr - > GetPin ( ) = = SourceRootPin )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
if ( VarExpr - > SupportsSoftLinks ( ) )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
AssignExpr - > ReplaceChild ( NodeExpr , VarExpr ) ;
return AssignExpr ;
2020-01-22 17:58:55 -05:00
}
2020-09-24 00:43:27 -04:00
FRigVMCachedValueExprAST * CacheExpr = nullptr ;
for ( FRigVMExprAST * VarExprParent : VarExpr - > Parents )
{
if ( VarExprParent - > IsA ( FRigVMExprAST : : EType : : CachedValue ) )
{
CacheExpr = VarExprParent - > To < FRigVMCachedValueExprAST > ( ) ;
break ;
}
}
2020-01-22 17:58:55 -05:00
2020-09-24 00:43:27 -04:00
if ( CacheExpr = = nullptr )
{
2021-01-12 06:47:41 -04:00
CacheExpr = MakeExpr < FRigVMCachedValueExprAST > ( FRigVMASTProxy ( ) ) ;
2020-09-24 00:43:27 -04:00
CacheExpr - > Name = AssignExpr - > GetName ( ) ;
VarExpr - > AddParent ( CacheExpr ) ;
NodeExpr - > AddParent ( CacheExpr ) ;
}
AssignExpr - > ReplaceChild ( NodeExpr , CacheExpr ) ;
return AssignExpr ;
}
2020-01-22 17:58:55 -05:00
}
}
2020-09-24 00:43:27 -04:00
checkNoEntry ( ) ;
2020-01-22 17:58:55 -05:00
}
}
return AssignExpr ;
}
void FRigVMParserAST : : FoldEntries ( )
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
TArray < FRigVMExprAST * > FoldRootExpressions ;
TArray < FRigVMExprAST * > ExpressionsToRemove ;
TMap < FName , FRigVMEntryExprAST * > EntryByName ;
for ( FRigVMExprAST * RootExpr : RootExpressions )
{
if ( RootExpr - > IsA ( FRigVMExprAST : : EType : : Entry ) )
{
FRigVMEntryExprAST * Entry = RootExpr - > To < FRigVMEntryExprAST > ( ) ;
if ( EntryByName . Contains ( Entry - > GetEventName ( ) ) )
{
FRigVMEntryExprAST * FoldEntry = EntryByName . FindChecked ( Entry - > GetEventName ( ) ) ;
// replace the original entry with a noop
2021-01-12 06:47:41 -04:00
FRigVMNoOpExprAST * NoOpExpr = MakeExpr < FRigVMNoOpExprAST > ( Entry - > GetProxy ( ) ) ;
2020-01-22 17:58:55 -05:00
NoOpExpr - > AddParent ( FoldEntry ) ;
NoOpExpr - > Name = Entry - > Name ;
2021-01-12 06:47:41 -04:00
SubjectToExpression . FindChecked ( Entry - > GetProxy ( ) ) = NoOpExpr ;
2020-01-22 17:58:55 -05:00
TArray < FRigVMExprAST * > Children = Entry - > Children ; // copy since the loop changes the array
for ( FRigVMExprAST * ChildExpr : Children )
{
ChildExpr - > RemoveParent ( Entry ) ;
if ( ChildExpr - > IsA ( FRigVMExprAST : : Var ) )
{
if ( ChildExpr - > To < FRigVMVarExprAST > ( ) - > IsExecuteContext ( ) )
{
2020-04-08 10:20:10 -04:00
ExpressionsToRemove . AddUnique ( ChildExpr ) ;
2020-01-22 17:58:55 -05:00
continue ;
}
}
ChildExpr - > AddParent ( FoldEntry ) ;
}
2020-04-08 10:20:10 -04:00
ExpressionsToRemove . AddUnique ( Entry ) ;
2020-01-22 17:58:55 -05:00
}
else
{
FoldRootExpressions . Add ( Entry ) ;
EntryByName . Add ( Entry - > GetEventName ( ) , Entry ) ;
}
}
else
{
FoldRootExpressions . Add ( RootExpr ) ;
}
}
RootExpressions = FoldRootExpressions ;
RemoveExpressions ( ExpressionsToRemove ) ;
}
void FRigVMParserAST : : InjectExitsToEntries ( )
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
for ( FRigVMExprAST * RootExpr : RootExpressions )
{
if ( RootExpr - > IsA ( FRigVMExprAST : : EType : : Entry ) )
{
bool bHasExit = false ;
if ( RootExpr - > Children . Num ( ) > 0 )
{
if ( RootExpr - > Children . Last ( ) - > IsA ( FRigVMExprAST : : EType : : Exit ) )
{
bHasExit = true ;
break ;
}
}
if ( ! bHasExit )
{
2021-01-12 06:47:41 -04:00
FRigVMExprAST * ExitExpr = MakeExpr < FRigVMExitExprAST > ( FRigVMASTProxy ( ) ) ;
2020-01-22 17:58:55 -05:00
ExitExpr - > AddParent ( RootExpr ) ;
2020-09-24 00:43:27 -04:00
}
}
}
}
void FRigVMParserAST : : BubbleUpExpressions ( )
{
for ( int32 ExpressionIndex = 0 ; ExpressionIndex < Expressions . Num ( ) ; ExpressionIndex + + )
{
FRigVMExprAST * Expression = Expressions [ ExpressionIndex ] ;
if ( ! Expression - > IsA ( FRigVMExprAST : : CachedValue ) )
{
continue ;
}
if ( Expression - > NumParents ( ) < 2 )
{
continue ;
}
// collect all of the blocks this is in and make sure it's bubbled up before that
TArray < FRigVMBlockExprAST * > Blocks ;
for ( int32 ParentIndex = 0 ; ParentIndex < Expression - > NumParents ( ) ; ParentIndex + + )
{
const FRigVMExprAST * ParentExpression = Expression - > ParentAt ( ParentIndex ) ;
if ( ParentExpression - > IsA ( FRigVMExprAST : : Block ) )
{
Blocks . AddUnique ( ( FRigVMBlockExprAST * ) ParentExpression - > To < FRigVMBlockExprAST > ( ) ) ;
}
else
{
Blocks . AddUnique ( ( FRigVMBlockExprAST * ) ParentExpression - > GetBlock ( ) ) ;
}
}
if ( Blocks . Num ( ) > 1 )
{
TArray < FRigVMBlockExprAST * > BlockCandidates ;
BlockCandidates . Append ( Blocks ) ;
FRigVMBlockExprAST * OuterBlock = nullptr ;
2021-10-28 10:25:38 -04:00
// deal with a case where an expression is linked within both the true and false case of an "if" node
if ( Blocks . Num ( ) = = 2 )
{
const FRigVMExprAST * Parent0 = Blocks [ 0 ] - > GetParent ( ) ;
const FRigVMExprAST * Parent1 = Blocks [ 1 ] - > GetParent ( ) ;
if ( Parent0 & & Parent1 )
{
const FRigVMExprAST * GrandParent0 = Parent0 - > GetParent ( ) ;
const FRigVMExprAST * GrandParent1 = Parent1 - > GetParent ( ) ;
if ( GrandParent0 & & GrandParent1 & & GrandParent0 = = GrandParent1 )
{
if ( GrandParent0 - > IsA ( FRigVMExprAST : : EType : : If ) )
{
const FRigVMIfExprAST * IfExpression = GrandParent0 - > To < FRigVMIfExprAST > ( ) ;
const FRigVMExprAST * ConditionBlockExpression = IfExpression - > GetConditionExpr ( ) - > GetFirstChildOfType ( FRigVMExprAST : : Block ) ;
if ( ConditionBlockExpression )
{
OuterBlock = ( FRigVMBlockExprAST * ) ConditionBlockExpression - > To < FRigVMBlockExprAST > ( ) ;
OuterBlock - > Children . Add ( Expression ) ;
Expression - > Parents . Insert ( OuterBlock , 0 ) ;
continue ;
}
}
}
}
}
// this expression is part of multiple blocks, and it needs to be bubbled up.
// for this we'll walk up the block tree and find the first block which contains all of them
2020-09-24 00:43:27 -04:00
for ( int32 BlockCandidateIndex = 0 ; BlockCandidateIndex < BlockCandidates . Num ( ) ; BlockCandidateIndex + + )
{
FRigVMBlockExprAST * BlockCandidate = BlockCandidates [ BlockCandidateIndex ] ;
bool bFoundCandidate = true ;
for ( int32 BlockIndex = 0 ; BlockIndex < Blocks . Num ( ) ; BlockIndex + + )
{
FRigVMBlockExprAST * Block = Blocks [ BlockIndex ] ;
if ( ! BlockCandidate - > Contains ( Block ) )
{
bFoundCandidate = false ;
break ;
}
}
if ( bFoundCandidate )
{
OuterBlock = BlockCandidate ;
break ;
}
BlockCandidates . AddUnique ( ( FRigVMBlockExprAST * ) BlockCandidate - > GetBlock ( ) ) ;
}
// we found a block which contains all of our blocks.
// we are now going to inject this block as the first parent
// of the cached value, so that the traverser sees it earlier
if ( OuterBlock )
{
int32 ChildIndex = Expression - > GetMinChildIndexWithinParent ( OuterBlock ) ;
if ( ChildIndex ! = INDEX_NONE )
{
OuterBlock - > Children . Insert ( Expression , ChildIndex ) ;
Expression - > Parents . Insert ( OuterBlock , 0 ) ;
}
2020-01-22 17:58:55 -05:00
}
}
}
}
void FRigVMParserAST : : RefreshExprIndices ( )
{
for ( int32 Index = 0 ; Index < Expressions . Num ( ) ; Index + + )
{
Expressions [ Index ] - > Index = Index ;
}
}
void FRigVMParserAST : : FoldNoOps ( )
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
for ( FRigVMExprAST * Expression : Expressions )
{
if ( Expression - > IsA ( FRigVMExprAST : : EType : : NoOp ) )
{
if ( URigVMNode * Node = Expression - > To < FRigVMNoOpExprAST > ( ) - > GetNode ( ) )
{
if ( URigVMParameterNode * ParameterNode = Cast < URigVMParameterNode > ( Node ) )
{
if ( ! ParameterNode - > IsInput ( ) )
{
continue ;
}
}
2020-11-18 07:48:31 -04:00
if ( URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( Node ) )
2020-01-22 17:58:55 -05:00
{
if ( ! VariableNode - > IsGetter ( ) )
{
continue ;
}
}
}
// copy since we are changing the content during iteration below
TArray < FRigVMExprAST * > Children = Expression - > Children ;
TArray < FRigVMExprAST * > Parents = Expression - > Parents ;
for ( FRigVMExprAST * Parent : Parents )
{
Expression - > RemoveParent ( Parent ) ;
}
for ( FRigVMExprAST * Child : Children )
{
Child - > RemoveParent ( Expression ) ;
for ( FRigVMExprAST * Parent : Parents )
{
Child - > AddParent ( Parent ) ;
}
}
}
}
}
void FRigVMParserAST : : FoldAssignments ( )
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
TArray < FRigVMExprAST * > ExpressionsToRemove ;
// first - Fold all assignment chains
for ( FRigVMExprAST * Expression : Expressions )
{
if ( Expression - > Parents . Num ( ) = = 0 )
{
continue ;
}
if ( Expression - > GetType ( ) ! = FRigVMExprAST : : EType : : Assign )
{
continue ;
}
FRigVMAssignExprAST * AssignExpr = Expression - > To < FRigVMAssignExprAST > ( ) ;
ensure ( AssignExpr - > Parents . Num ( ) = = 1 ) ;
ensure ( AssignExpr - > Children . Num ( ) = = 1 ) ;
2021-06-22 14:11:52 -04:00
URigVMPin * SourcePin = AssignExpr - > GetSourcePin ( ) ;
URigVMPin * TargetPin = AssignExpr - > GetTargetPin ( ) ;
// in case the assign has different types for left and right - we need to avoid folding
// since this assign represents a cast operation
if ( SourcePin - > GetCPPTypeObject ( ) ! = TargetPin - > GetCPPTypeObject ( ) )
{
continue ;
}
else if ( SourcePin - > GetCPPTypeObject ( ) = = nullptr )
{
if ( SourcePin - > GetCPPType ( ) ! = TargetPin - > GetCPPType ( ) )
{
continue ;
}
}
2020-01-22 17:58:55 -05:00
// non-input pins on anything but a reroute node should be skipped
2021-06-22 14:11:52 -04:00
if ( TargetPin - > GetDirection ( ) ! = ERigVMPinDirection : : Input & &
Cast < URigVMRerouteNode > ( TargetPin - > GetNode ( ) ) = = nullptr )
2020-01-22 17:58:55 -05:00
{
continue ;
}
2020-09-24 00:43:27 -04:00
// if this node is a loop node - let's skip the folding
2021-06-22 14:11:52 -04:00
if ( URigVMUnitNode * UnitNode = Cast < URigVMUnitNode > ( TargetPin - > GetNode ( ) ) )
2020-09-24 00:43:27 -04:00
{
2020-12-02 10:59:58 -04:00
if ( UnitNode - > IsLoopNode ( ) )
2020-09-24 00:43:27 -04:00
{
continue ;
}
}
2020-10-22 19:19:16 -04:00
// if this node is a variable node and the pin requires a watch... skip this
2021-06-22 14:11:52 -04:00
if ( Cast < URigVMVariableNode > ( SourcePin - > GetNode ( ) ) )
2020-10-22 19:19:16 -04:00
{
2021-06-22 14:11:52 -04:00
if ( SourcePin - > RequiresWatch ( true ) )
2020-10-22 19:19:16 -04:00
{
continue ;
}
}
2021-08-18 06:18:21 -04:00
// if this node is an array iterator node - let's skip the folding
if ( URigVMArrayNode * ArrayNode = Cast < URigVMArrayNode > ( TargetPin - > GetNode ( ) ) )
{
if ( ArrayNode - > IsLoopNode ( ) )
{
continue ;
}
}
2020-10-22 19:19:16 -04:00
2020-01-22 17:58:55 -05:00
FRigVMExprAST * Parent = AssignExpr - > Parents [ 0 ] ;
2020-09-24 00:43:27 -04:00
if ( ! Parent - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
continue ;
}
2020-01-22 17:58:55 -05:00
FRigVMExprAST * Child = AssignExpr - > Children [ 0 ] ;
AssignExpr - > RemoveParent ( Parent ) ;
Child - > RemoveParent ( AssignExpr ) ;
TArray < FRigVMExprAST * > GrandParents = Parent - > Parents ;
for ( FRigVMExprAST * GrandParent : GrandParents )
{
GrandParent - > ReplaceChild ( Parent , Child ) ;
if ( GrandParent - > IsA ( FRigVMExprAST : : EType : : Assign ) )
{
FRigVMAssignExprAST * GrandParentAssign = GrandParent - > To < FRigVMAssignExprAST > ( ) ;
2021-01-12 06:47:41 -04:00
GrandParentAssign - > SourceProxy = AssignExpr - > SourceProxy ;
GrandParentAssign - > Name = * FString : : Printf ( TEXT ( " %s -> %s " ) , * GrandParentAssign - > GetSourcePin ( ) - > GetPinPath ( ) , * GrandParentAssign - > GetTargetPin ( ) - > GetPinPath ( ) ) ;
2020-01-22 17:58:55 -05:00
}
}
2020-04-08 10:20:10 -04:00
ExpressionsToRemove . AddUnique ( AssignExpr ) ;
2020-01-22 17:58:55 -05:00
if ( Parent - > Parents . Num ( ) = = 0 )
{
2020-04-08 10:20:10 -04:00
ExpressionsToRemove . AddUnique ( Parent ) ;
2020-01-22 17:58:55 -05:00
}
}
RemoveExpressions ( ExpressionsToRemove ) ;
}
2020-09-24 00:43:27 -04:00
bool FRigVMParserAST : : FoldConstantValuesToLiterals ( URigVMGraph * InGraph , URigVMController * InController , const TArray < FRigVMExternalVariable > & InExternalVariables , const TArray < FRigVMUserDataArray > & InRigVMUserData )
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
if ( InController = = nullptr )
{
return false ;
}
if ( InRigVMUserData . Num ( ) = = 0 )
{
return false ;
}
// loop over all call externs and figure out if they are a non-const node
// with one or more const pins. we then build a temporary VM to run the part of the
// graph, and pull out the required values - we then bake the value into a literal
// and remove the tree that created the value.
TMap < FString , FString > ComputedDefaultValues ;
2021-01-12 06:47:41 -04:00
TArray < FRigVMASTProxy > PinsToUpdate ;
TArray < FRigVMASTProxy > RootPinsToUpdate ;
TArray < FRigVMASTProxy > PinsToCompute ;
TArray < FRigVMASTProxy > NodesToCompute ;
2020-09-24 00:43:27 -04:00
2021-01-12 06:47:41 -04:00
for ( const FRigVMASTProxy & NodeProxy : NodeProxies )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
if ( NodeProxy . IsA < URigVMParameterNode > ( ) | |
NodeProxy . IsA < URigVMVariableNode > ( ) | |
NodeProxy . IsA < URigVMEnumNode > ( ) )
2020-09-24 00:43:27 -04:00
{
continue ;
}
2021-01-12 06:47:41 -04:00
FRigVMExprAST * * NodeExprPtr = SubjectToExpression . Find ( NodeProxy ) ;
2020-09-24 00:43:27 -04:00
if ( NodeExprPtr = = nullptr )
{
continue ;
}
FRigVMExprAST * NodeExpr = * NodeExprPtr ;
if ( NodeExpr - > IsConstant ( ) )
{
continue ;
}
2021-01-12 06:47:41 -04:00
URigVMNode * Node = NodeProxy . GetSubjectChecked < URigVMNode > ( ) ;
2020-09-24 00:43:27 -04:00
const TArray < URigVMPin * > Pins = Node - > GetPins ( ) ;
for ( URigVMPin * Pin : Pins )
{
if ( Pin - > GetDirection ( ) ! = ERigVMPinDirection : : Input & &
Pin - > GetDirection ( ) ! = ERigVMPinDirection : : IO )
{
continue ;
}
2021-01-12 06:47:41 -04:00
FRigVMASTProxy PinProxy = NodeProxy . GetSibling ( Pin ) ;
FRigVMExprAST * * PinExprPtr = SubjectToExpression . Find ( PinProxy ) ;
2020-09-24 00:43:27 -04:00
if ( PinExprPtr = = nullptr )
{
continue ;
}
FRigVMExprAST * PinExpr = * PinExprPtr ;
if ( PinExpr - > IsA ( FRigVMExprAST : : EType : : Literal ) )
{
if ( const FRigVMExprAST * VarPinExpr = PinExpr - > GetFirstParentOfType ( FRigVMExprAST : : EType : : Var ) )
{
if ( VarPinExpr - > GetName ( ) = = PinExpr - > GetName ( ) )
{
PinExpr = ( FRigVMExprAST * ) VarPinExpr ;
}
}
// if we are still a literal, carry on
if ( PinExpr - > IsA ( FRigVMExprAST : : EType : : Literal ) )
{
continue ;
}
}
2021-01-12 06:47:41 -04:00
TArray < FRigVMPinProxyPair > SourcePins = GetSourceLinks ( PinProxy , true ) ;
2020-09-24 00:43:27 -04:00
if ( SourcePins . Num ( ) = = 0 )
{
continue ;
}
if ( ! PinExpr - > IsConstant ( ) )
{
continue ;
}
bool bFoundValidSourcePin = false ;
2021-01-12 06:47:41 -04:00
for ( const FRigVMPinProxyPair & SourcePin : SourcePins )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
const FRigVMASTProxy & SourcePinProxy = SourcePin . Key ;
URigVMNode * SourceNode = SourcePinProxy . GetSubjectChecked < URigVMPin > ( ) - > GetNode ( ) ;
FRigVMASTProxy SourceNodeProxy = SourcePin . Key . GetSibling ( SourceNode ) ;
2020-09-24 00:43:27 -04:00
2021-01-12 06:47:41 -04:00
check ( SourceNodeProxy . IsValid ( ) ) ;
if ( SourceNodeProxy . IsA < URigVMParameterNode > ( ) | |
SourceNodeProxy . IsA < URigVMVariableNode > ( ) | |
SourceNodeProxy . IsA < URigVMRerouteNode > ( ) | |
SourceNodeProxy . IsA < URigVMEnumNode > ( ) )
2020-09-24 00:43:27 -04:00
{
continue ;
}
2021-01-12 06:47:41 -04:00
PinsToCompute . AddUnique ( SourcePinProxy ) ;
NodesToCompute . AddUnique ( SourceNodeProxy ) ;
2020-09-24 00:43:27 -04:00
bFoundValidSourcePin = true ;
}
if ( bFoundValidSourcePin )
{
2021-01-12 06:47:41 -04:00
PinsToUpdate . Add ( PinProxy ) ;
RootPinsToUpdate . AddUnique ( PinProxy . GetSibling ( Pin - > GetRootPin ( ) ) ) ;
2020-09-24 00:43:27 -04:00
}
}
}
if ( NodesToCompute . Num ( ) = = 0 )
{
return false ;
}
2021-06-03 05:45:48 -04:00
// add all of the additional nodes driving these
for ( int32 NodeToComputeIndex = 0 ; NodeToComputeIndex < NodesToCompute . Num ( ) ; NodeToComputeIndex + + )
{
FRigVMASTProxy & ProxyToCompute = NodesToCompute [ NodeToComputeIndex ] ;
if ( URigVMNode * NodeToCompute = ProxyToCompute . GetSubject < URigVMNode > ( ) )
{
TArray < URigVMNode * > SourceNodes = NodeToCompute - > GetLinkedSourceNodes ( ) ;
for ( URigVMNode * SourceNode : SourceNodes )
{
FRigVMASTProxy SourceProxy = ProxyToCompute . GetSibling ( SourceNode ) ;
NodesToCompute . AddUnique ( SourceProxy ) ;
}
}
}
2020-09-24 00:43:27 -04:00
// we now know the node we need to run.
// let's build an temporary AST which has only those nodes
TSharedPtr < FRigVMParserAST > TempAST = MakeShareable ( new FRigVMParserAST ( InGraph , NodesToCompute ) ) ;
2021-10-06 08:42:42 -04:00
// share the pin overrides with the constant folding AST to ensure
// the complete view of default values across function references is available
// in the subset AST.
TempAST - > PinOverrides = PinOverrides ;
2020-09-24 00:43:27 -04:00
// build the VM to run this AST
TMap < FString , FRigVMOperand > Operands ;
2021-08-03 08:50:47 -04:00
URigVM * TempVM = NewObject < URigVM > ( InGraph ) ;
2020-09-24 00:43:27 -04:00
URigVMCompiler * TempCompiler = NewObject < URigVMCompiler > ( GetTransientPackage ( ) ) ;
TempCompiler - > Settings . SetupNodeInstructionIndex = false ;
2021-05-14 02:36:03 -04:00
TempCompiler - > Settings . IsPreprocessorPhase = true ;
TempCompiler - > Settings . EnablePinWatches = false ;
TempCompiler - > Settings . ASTSettings = FRigVMParserASTSettings : : Fast ( ) ;
2020-09-24 00:43:27 -04:00
TempCompiler - > Compile ( InGraph , InController , TempVM , InExternalVariables , InRigVMUserData , & Operands , TempAST ) ;
2021-07-27 14:04:39 -04:00
# if UE_RIGVM_UCLASS_BASED_STORAGE_DISABLED
2021-04-29 05:02:50 -04:00
FRigVMMemoryContainer * Memory [ ] = { TempVM - > WorkMemoryPtr , TempVM - > LiteralMemoryPtr , TempVM - > DebugMemoryPtr } ;
2020-09-24 00:43:27 -04:00
for ( const FRigVMUserDataArray & RigVMUserData : InRigVMUserData )
{
2021-04-29 05:02:50 -04:00
TempVM - > Execute ( FRigVMMemoryContainerPtrArray ( Memory , 3 ) , RigVMUserData ) ;
2020-09-24 00:43:27 -04:00
}
2021-07-27 14:04:39 -04:00
# else
TArray < URigVMMemoryStorage * > Memory ;
Memory . Add ( TempVM - > GetWorkMemory ( ) ) ;
Memory . Add ( TempVM - > GetLiteralMemory ( ) ) ;
Memory . Add ( TempVM - > GetDebugMemory ( ) ) ;
for ( const FRigVMUserDataArray & RigVMUserData : InRigVMUserData )
{
TempVM - > Execute ( Memory , RigVMUserData ) ;
}
# endif
2020-09-24 00:43:27 -04:00
// copy the values out of the temp VM and set them on the cached value
2021-01-12 06:47:41 -04:00
for ( const FRigVMASTProxy & PinToComputeProxy : PinsToCompute )
2020-09-24 00:43:27 -04:00
{
TGuardValue < bool > GuardControllerNotifs ( InController - > bSuspendNotifications , true ) ;
2021-01-12 06:47:41 -04:00
URigVMPin * PinToCompute = PinToComputeProxy . GetSubjectChecked < URigVMPin > ( ) ;
2020-09-24 00:43:27 -04:00
URigVMPin * RootPin = PinToCompute - > GetRootPin ( ) ;
2021-01-12 06:47:41 -04:00
FRigVMASTProxy RootPinProxy = PinToComputeProxy . GetSibling ( RootPin ) ;
2020-09-24 00:43:27 -04:00
FRigVMVarExprAST * RootVarExpr = nullptr ;
2021-01-12 06:47:41 -04:00
FRigVMExprAST * * RootPinExprPtr = SubjectToExpression . Find ( RootPinProxy ) ;
2020-09-24 00:43:27 -04:00
if ( RootPinExprPtr ! = nullptr )
{
FRigVMExprAST * RootPinExpr = * RootPinExprPtr ;
if ( RootPinExpr - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
RootVarExpr = RootPinExpr - > To < FRigVMVarExprAST > ( ) ;
}
}
FString PinHash = URigVMCompiler : : GetPinHash ( RootPin , RootVarExpr , false ) ;
const FRigVMOperand & Operand = Operands . FindChecked ( PinHash ) ;
2021-07-27 14:04:39 -04:00
# if UE_RIGVM_UCLASS_BASED_STORAGE_DISABLED
2020-09-24 00:43:27 -04:00
TArray < FString > DefaultValues = TempVM - > GetWorkMemory ( ) . GetRegisterValueAsString ( Operand , RootPin - > GetCPPType ( ) , RootPin - > GetCPPTypeObject ( ) ) ;
2021-06-03 05:45:48 -04:00
2021-07-27 14:04:39 -04:00
# else
2021-09-22 06:52:44 -04:00
FString DefaultValue ;
if ( Operand . GetMemoryType ( ) = = ERigVMMemoryType : : Work )
{
DefaultValue = TempVM - > GetWorkMemory ( ) - > GetDataAsString ( Operand . GetRegisterIndex ( ) ) ;
}
else if ( Operand . GetMemoryType ( ) = = ERigVMMemoryType : : Literal )
{
DefaultValue = TempVM - > GetLiteralMemory ( ) - > GetDataAsString ( Operand . GetRegisterIndex ( ) ) ;
}
2021-07-27 14:04:39 -04:00
if ( DefaultValue . IsEmpty ( ) )
{
continue ;
}
# endif
2021-06-03 05:45:48 -04:00
// FString TempDefaultValue = FString::Printf(TEXT("(%s)"), *FString::Join(DefaultValues, TEXT(",")));
// UE_LOG(LogRigVMDeveloper, Display, TEXT("Computed constant value '%s' = '%s'"), *PinHash, *TempDefaultValue);
2021-07-27 14:04:39 -04:00
# if UE_RIGVM_UCLASS_BASED_STORAGE_DISABLED
2020-09-24 00:43:27 -04:00
if ( DefaultValues . Num ( ) = = 0 )
{
continue ;
}
2021-07-27 14:04:39 -04:00
# endif
2020-09-24 00:43:27 -04:00
TArray < FString > SegmentNames ;
if ( ! URigVMPin : : SplitPinPath ( PinToCompute - > GetSegmentPath ( ) , SegmentNames ) )
{
SegmentNames . Add ( PinToCompute - > GetName ( ) ) ;
}
2021-07-27 14:04:39 -04:00
# if UE_RIGVM_UCLASS_BASED_STORAGE_DISABLED
2020-09-24 00:43:27 -04:00
FString DefaultValue = DefaultValues [ 0 ] ;
if ( RootPin - > IsArray ( ) )
{
DefaultValue = FString : : Printf ( TEXT ( " (%s) " ) , * FString : : Join ( DefaultValues , TEXT ( " , " ) ) ) ;
}
2021-07-27 14:04:39 -04:00
# endif
2020-09-24 00:43:27 -04:00
URigVMPin * PinForDefaultValue = RootPin ;
while ( PinForDefaultValue ! = PinToCompute & & SegmentNames . Num ( ) > 0 )
{
2020-12-16 12:11:20 -04:00
TArray < FString > SplitDefaultValues = URigVMPin : : SplitDefaultValue ( DefaultValue ) ;
2020-09-24 00:43:27 -04:00
if ( PinForDefaultValue - > IsArray ( ) )
{
int32 ElementIndex = FCString : : Atoi ( * SegmentNames [ 0 ] ) ;
DefaultValue = SplitDefaultValues [ ElementIndex ] ;
PinForDefaultValue = PinForDefaultValue - > GetSubPins ( ) [ ElementIndex ] ;
URigVMController : : PostProcessDefaultValue ( PinForDefaultValue , DefaultValue ) ;
SegmentNames . RemoveAt ( 0 ) ;
}
else if ( PinForDefaultValue - > IsStruct ( ) )
{
2021-10-25 20:05:28 -04:00
if ( SplitDefaultValues . IsEmpty ( ) )
{
break ;
}
2020-09-24 00:43:27 -04:00
for ( const FString & MemberNameValuePair : SplitDefaultValues )
{
FString MemberName , MemberValue ;
if ( MemberNameValuePair . Split ( TEXT ( " = " ) , & MemberName , & MemberValue ) )
{
if ( MemberName = = SegmentNames [ 0 ] )
{
URigVMPin * SubPin = PinForDefaultValue - > FindSubPin ( MemberName ) ;
if ( SubPin = = nullptr )
{
SegmentNames . Reset ( ) ;
break ;
}
DefaultValue = MemberValue ;
PinForDefaultValue = SubPin ;
URigVMController : : PostProcessDefaultValue ( PinForDefaultValue , DefaultValue ) ;
SegmentNames . RemoveAt ( 0 ) ;
break ;
}
}
}
}
else
{
checkNoEntry ( ) ;
}
}
2021-01-12 06:47:41 -04:00
const TArray < FRigVMASTProxy > & TargetPins = GetTargetPins ( PinToComputeProxy ) ;
for ( const FRigVMASTProxy & TargetPinProxy : TargetPins )
2020-09-24 00:43:27 -04:00
{
2021-01-19 04:57:43 -04:00
URigVMPin : : FPinOverrideValue OverrideValue ;
OverrideValue . DefaultValue = DefaultValue ;
PinOverrides . FindOrAdd ( TargetPinProxy ) = OverrideValue ;
2020-09-24 00:43:27 -04:00
}
}
// now remove all of the expressions no longer needed
TArray < FRigVMExprAST * > ExpressionsToRemove ;
2021-01-12 06:47:41 -04:00
for ( const FRigVMASTProxy & RootPinToUpdateProxy : RootPinsToUpdate )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMExprAST * * PreviousExprPtr = SubjectToExpression . Find ( RootPinToUpdateProxy ) ;
2020-09-24 00:43:27 -04:00
if ( PreviousExprPtr )
{
FRigVMVarExprAST * PreviousVarExpr = ( * PreviousExprPtr ) - > To < FRigVMVarExprAST > ( ) ;
// if the previous var expression is a literal used to initialize a var
// (for example on an IO pin, or when we are driving sub pins)
if ( PreviousVarExpr - > IsA ( FRigVMExprAST : : EType : : Literal ) )
{
bool bRedirectedVar = false ;
for ( int32 ParentIndex = 0 ; ParentIndex < PreviousVarExpr - > NumParents ( ) ; ParentIndex + + )
{
const FRigVMExprAST * ParentExpr = PreviousVarExpr - > ParentAt ( ParentIndex ) ;
if ( ParentExpr - > IsA ( FRigVMExprAST : : EType : : Assign ) )
{
for ( int32 GrandParentIndex = 0 ; GrandParentIndex < ParentExpr - > NumParents ( ) ; GrandParentIndex + + )
{
const FRigVMExprAST * GrandParentExpr = ParentExpr - > ParentAt ( GrandParentIndex ) ;
if ( GrandParentExpr - > IsA ( FRigVMExprAST : : EType : : Block ) )
{
GrandParentExpr = GrandParentExpr - > GetParent ( ) ;
}
if ( GrandParentExpr - > IsA ( FRigVMExprAST : : EType : : Var ) & & ( GrandParentExpr - > GetName ( ) = = PreviousVarExpr - > GetName ( ) ) )
{
PreviousVarExpr = ( FRigVMVarExprAST * ) GrandParentExpr - > To < FRigVMVarExprAST > ( ) ;
bRedirectedVar = true ;
break ;
}
}
}
if ( bRedirectedVar )
{
break ;
}
}
}
2021-01-12 06:47:41 -04:00
FRigVMLiteralExprAST * LiteralExpr = MakeExpr < FRigVMLiteralExprAST > ( RootPinToUpdateProxy ) ;
2020-09-24 00:43:27 -04:00
LiteralExpr - > Name = PreviousVarExpr - > Name ;
2021-01-12 06:47:41 -04:00
SubjectToExpression [ RootPinToUpdateProxy ] = LiteralExpr ;
2020-09-24 00:43:27 -04:00
PreviousVarExpr - > ReplaceBy ( LiteralExpr ) ;
ExpressionsToRemove . Add ( PreviousVarExpr ) ;
}
}
2021-08-03 08:50:47 -04:00
TempVM - > Rename ( nullptr , GetTransientPackage ( ) , REN_ForceNoResetLoaders | REN_DoNotDirty | REN_DontCreateRedirectors | REN_NonTransactional ) ;
2021-11-18 14:37:34 -05:00
TempVM - > MarkAsGarbage ( ) ;
2021-08-03 08:50:47 -04:00
2020-09-24 00:43:27 -04:00
RemoveExpressions ( ExpressionsToRemove ) ;
return ExpressionsToRemove . Num ( ) > 0 ;
}
bool FRigVMParserAST : : FoldUnreachableBranches ( URigVMGraph * InGraph )
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
TArray < FRigVMExprAST * > ExpressionsToRemove ;
2021-01-12 06:47:41 -04:00
for ( const FRigVMASTProxy & NodeProxy : NodeProxies )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
if ( NodeProxy . IsA < URigVMParameterNode > ( ) | |
NodeProxy . IsA < URigVMVariableNode > ( ) )
2020-09-24 00:43:27 -04:00
{
continue ;
}
2021-01-12 06:47:41 -04:00
//URigVMNode* Node = NodeProxy.GetSubjectChecked<URigVMNode>();
FRigVMExprAST * * NodeExprPtr = SubjectToExpression . Find ( NodeProxy ) ;
2020-09-24 00:43:27 -04:00
if ( NodeExprPtr = = nullptr )
{
continue ;
}
FRigVMExprAST * NodeExpr = * NodeExprPtr ;
if ( NodeExpr - > NumParents ( ) = = 0 )
{
continue ;
}
if ( NodeExpr - > IsA ( FRigVMExprAST : : EType : : Branch ) )
{
const FRigVMBranchExprAST * BranchExpr = NodeExpr - > To < FRigVMBranchExprAST > ( ) ;
FRigVMExprAST * ExprReplacement = nullptr ;
if ( BranchExpr - > IsAlwaysTrue ( ) )
{
ExprReplacement = ( FRigVMExprAST * ) BranchExpr - > GetTrueExpr ( ) ;
}
else if ( BranchExpr - > IsAlwaysFalse ( ) )
{
ExprReplacement = ( FRigVMExprAST * ) BranchExpr - > GetFalseExpr ( ) ;
}
if ( ExprReplacement )
{
if ( ExprReplacement - > NumChildren ( ) = = 1 )
{
ExprReplacement = ( FRigVMExprAST * ) ExprReplacement - > ChildAt ( 0 ) ;
if ( ExprReplacement - > IsA ( FRigVMExprAST : : EType : : Block ) )
{
ExprReplacement - > RemoveParent ( ( FRigVMExprAST * ) ExprReplacement - > GetParent ( ) ) ;
NodeExpr - > ReplaceBy ( ExprReplacement ) ;
ExpressionsToRemove . Add ( NodeExpr ) ;
}
}
}
}
else
{
FRigVMExprAST * CachedValueExpr = ( FRigVMExprAST * ) NodeExpr - > GetParent ( ) ;
if ( ! CachedValueExpr - > IsA ( FRigVMExprAST : : EType : : CachedValue ) )
{
continue ;
}
FRigVMExprAST * ExprReplacement = nullptr ;
if ( NodeExpr - > IsA ( FRigVMExprAST : : EType : : If ) )
{
const FRigVMIfExprAST * IfExpr = NodeExpr - > To < FRigVMIfExprAST > ( ) ;
if ( IfExpr - > IsAlwaysTrue ( ) )
{
ExprReplacement = ( FRigVMExprAST * ) IfExpr - > GetTrueExpr ( ) ;
}
else if ( IfExpr - > IsAlwaysFalse ( ) )
{
ExprReplacement = ( FRigVMExprAST * ) IfExpr - > GetFalseExpr ( ) ;
}
}
else if ( NodeExpr - > IsA ( FRigVMExprAST : : EType : : Select ) )
{
const FRigVMSelectExprAST * SelectExpr = NodeExpr - > To < FRigVMSelectExprAST > ( ) ;
int32 ConstantCaseIndex = SelectExpr - > GetConstantValueIndex ( ) ;
if ( ConstantCaseIndex ! = INDEX_NONE )
{
ExprReplacement = ( FRigVMExprAST * ) SelectExpr - > GetValueExpr ( ConstantCaseIndex ) ;
}
}
if ( ExprReplacement )
{
ExprReplacement - > RemoveParent ( ( FRigVMExprAST * ) ExprReplacement - > GetParent ( ) ) ;
CachedValueExpr - > ReplaceBy ( ExprReplacement ) ;
ExpressionsToRemove . Add ( CachedValueExpr ) ;
}
}
}
RemoveExpressions ( ExpressionsToRemove ) ;
return ExpressionsToRemove . Num ( ) > 0 ;
}
2020-01-22 17:58:55 -05:00
void FRigVMParserAST : : FoldLiterals ( )
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
TMap < FString , FRigVMLiteralExprAST * > ValueToLiteral ;
TArray < FRigVMExprAST * > ExpressionsToRemove ;
for ( int32 ExpressionIndex = 0 ; ExpressionIndex < Expressions . Num ( ) ; ExpressionIndex + + )
{
FRigVMExprAST * Expression = Expressions [ ExpressionIndex ] ;
if ( Expression - > Parents . Num ( ) = = 0 )
{
continue ;
}
if ( Expression - > GetType ( ) = = FRigVMExprAST : : EType : : Literal )
{
ensure ( Expression - > Children . Num ( ) = = 0 ) ;
FRigVMLiteralExprAST * LiteralExpr = Expression - > To < FRigVMLiteralExprAST > ( ) ;
2020-09-24 00:43:27 -04:00
FString DefaultValue = LiteralExpr - > GetDefaultValue ( ) ;
if ( DefaultValue . IsEmpty ( ) )
{
2020-12-01 10:22:06 -04:00
if ( LiteralExpr - > GetCPPType ( ) = = TEXT ( " bool " ) )
{
DefaultValue = TEXT ( " False " ) ;
}
else if ( LiteralExpr - > GetCPPType ( ) = = TEXT ( " float " ) )
{
DefaultValue = TEXT ( " 0.000000 " ) ;
}
2021-06-22 14:11:52 -04:00
else if ( LiteralExpr - > GetCPPType ( ) = = TEXT ( " double " ) )
{
DefaultValue = TEXT ( " 0.000000 " ) ;
}
2020-12-01 10:22:06 -04:00
else if ( LiteralExpr - > GetCPPType ( ) = = TEXT ( " int32 " ) )
{
DefaultValue = TEXT ( " 0 " ) ;
}
else
{
continue ;
}
2020-09-24 00:43:27 -04:00
}
FString Hash = FString : : Printf ( TEXT ( " [%s] %s " ) , * LiteralExpr - > GetCPPType ( ) , * DefaultValue ) ;
2020-01-22 17:58:55 -05:00
FRigVMLiteralExprAST * const * MappedExpr = ValueToLiteral . Find ( Hash ) ;
if ( MappedExpr )
{
TArray < FRigVMExprAST * > Parents = Expression - > Parents ;
for ( FRigVMExprAST * Parent : Parents )
{
Parent - > ReplaceChild ( Expression , * MappedExpr ) ;
}
2020-04-08 10:20:10 -04:00
ExpressionsToRemove . AddUnique ( Expression ) ;
2020-01-22 17:58:55 -05:00
}
else
{
ValueToLiteral . Add ( Hash , LiteralExpr ) ;
}
}
}
RemoveExpressions ( ExpressionsToRemove ) ;
}
2021-01-12 06:47:41 -04:00
const FRigVMExprAST * FRigVMParserAST : : GetExprForSubject ( const FRigVMASTProxy & InProxy ) const
2020-01-22 17:58:55 -05:00
{
2021-01-12 06:47:41 -04:00
if ( FRigVMExprAST * const * ExpressionPtr = SubjectToExpression . Find ( InProxy ) )
2020-01-22 17:58:55 -05:00
{
return * ExpressionPtr ;
}
return nullptr ;
}
2021-04-29 05:02:50 -04:00
TArray < const FRigVMExprAST * > FRigVMParserAST : : GetExpressionsForSubject ( UObject * InSubject ) const
{
TArray < const FRigVMExprAST * > ExpressionsForSubject ;
for ( TPair < FRigVMASTProxy , FRigVMExprAST * > Pair : SubjectToExpression )
{
if ( Pair . Key . GetCallstack ( ) . Last ( ) = = InSubject )
{
ExpressionsForSubject . Add ( Pair . Value ) ;
}
}
return ExpressionsForSubject ;
}
2020-01-22 17:58:55 -05:00
void FRigVMParserAST : : PrepareCycleChecking ( URigVMPin * InPin )
{
if ( InPin = = nullptr )
{
LastCycleCheckExpr = nullptr ;
CycleCheckFlags . Reset ( ) ;
return ;
}
2021-01-12 06:47:41 -04:00
FRigVMASTProxy NodeProxy = FRigVMASTProxy : : MakeFromUObject ( InPin - > GetNode ( ) ) ;
2020-01-22 17:58:55 -05:00
const FRigVMExprAST * Expression = nullptr ;
2021-01-12 06:47:41 -04:00
if ( FRigVMExprAST * const * ExpressionPtr = SubjectToExpression . Find ( NodeProxy ) )
2020-01-22 17:58:55 -05:00
{
Expression = * ExpressionPtr ;
}
else
{
return ;
}
if ( LastCycleCheckExpr ! = Expression )
{
LastCycleCheckExpr = Expression ;
CycleCheckFlags . SetNumZeroed ( Expressions . Num ( ) ) ;
CycleCheckFlags [ LastCycleCheckExpr - > GetIndex ( ) ] = ETraverseRelationShip_Self ;
}
}
bool FRigVMParserAST : : CanLink ( URigVMPin * InSourcePin , URigVMPin * InTargetPin , FString * OutFailureReason )
{
if ( InSourcePin = = nullptr | | InTargetPin = = nullptr | | InSourcePin = = InTargetPin )
{
if ( OutFailureReason )
{
* OutFailureReason = FString ( TEXT ( " Provided objects contain nullptr. " ) ) ;
}
return false ;
}
URigVMNode * SourceNode = InSourcePin - > GetNode ( ) ;
URigVMNode * TargetNode = InTargetPin - > GetNode ( ) ;
if ( SourceNode = = TargetNode )
{
if ( OutFailureReason )
{
* OutFailureReason = FString ( TEXT ( " Source and Target Nodes are identical. " ) ) ;
}
return false ;
}
2021-01-28 11:51:24 -04:00
if ( SourceNode - > IsA < URigVMRerouteNode > ( ) )
{
TArray < URigVMNode * > LinkedSourceNodes = SourceNode - > GetLinkedSourceNodes ( ) ;
for ( int32 LinkedSourceNodeIndex = 0 ; LinkedSourceNodeIndex < LinkedSourceNodes . Num ( ) ; LinkedSourceNodeIndex + + )
{
URigVMNode * LinkedSourceNode = LinkedSourceNodes [ LinkedSourceNodeIndex ] ;
if ( LinkedSourceNode - > IsA < URigVMRerouteNode > ( ) )
{
LinkedSourceNodes . Append ( LinkedSourceNode - > GetLinkedSourceNodes ( ) ) ;
}
else
{
SourceNode = LinkedSourceNode ;
break ;
}
}
}
if ( TargetNode - > IsA < URigVMRerouteNode > ( ) )
{
TArray < URigVMNode * > LinkedTargetNodes = TargetNode - > GetLinkedTargetNodes ( ) ;
for ( int32 LinkedTargetNodeIndex = 0 ; LinkedTargetNodeIndex < LinkedTargetNodes . Num ( ) ; LinkedTargetNodeIndex + + )
{
URigVMNode * LinkedTargetNode = LinkedTargetNodes [ LinkedTargetNodeIndex ] ;
if ( LinkedTargetNode - > IsA < URigVMRerouteNode > ( ) )
{
LinkedTargetNodes . Append ( LinkedTargetNode - > GetLinkedTargetNodes ( ) ) ;
}
else
{
TargetNode = LinkedTargetNode ;
break ;
}
}
}
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SourceNodeProxy = FRigVMASTProxy : : MakeFromUObject ( SourceNode ) ;
FRigVMASTProxy TargetNodeProxy = FRigVMASTProxy : : MakeFromUObject ( TargetNode ) ;
2020-01-22 17:58:55 -05:00
const FRigVMExprAST * SourceExpression = nullptr ;
2021-01-12 06:47:41 -04:00
if ( FRigVMExprAST * const * SourceExpressionPtr = SubjectToExpression . Find ( SourceNodeProxy ) )
2020-01-22 17:58:55 -05:00
{
SourceExpression = * SourceExpressionPtr ;
}
else
{
if ( OutFailureReason )
{
* OutFailureReason = FString ( TEXT ( " Source node is not part of AST. " ) ) ;
}
return false ;
}
2020-09-24 00:43:27 -04:00
const FRigVMVarExprAST * SourceVarExpression = nullptr ;
2021-01-12 06:47:41 -04:00
if ( FRigVMExprAST * const * SourceVarExpressionPtr = SubjectToExpression . Find ( SourceNodeProxy . GetSibling ( InSourcePin - > GetRootPin ( ) ) ) )
2020-09-24 00:43:27 -04:00
{
if ( ( * SourceVarExpressionPtr ) - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
SourceVarExpression = ( * SourceVarExpressionPtr ) - > To < FRigVMVarExprAST > ( ) ;
}
}
2020-01-22 17:58:55 -05:00
const FRigVMExprAST * TargetExpression = nullptr ;
2021-01-12 06:47:41 -04:00
if ( FRigVMExprAST * const * TargetExpressionPtr = SubjectToExpression . Find ( TargetNodeProxy ) )
2020-01-22 17:58:55 -05:00
{
TargetExpression = * TargetExpressionPtr ;
}
else
{
if ( OutFailureReason )
{
* OutFailureReason = FString ( TEXT ( " Target node is not part of AST. " ) ) ;
}
return false ;
}
const FRigVMBlockExprAST * SourceBlock = SourceExpression - > GetBlock ( ) ;
const FRigVMBlockExprAST * TargetBlock = TargetExpression - > GetBlock ( ) ;
if ( SourceBlock = = nullptr | | TargetBlock = = nullptr )
{
return false ;
}
if ( SourceBlock = = TargetBlock | |
SourceBlock - > Contains ( TargetBlock ) | |
2020-09-24 00:43:27 -04:00
TargetBlock - > Contains ( SourceBlock ) | |
TargetBlock - > GetRootBlock ( ) - > Contains ( SourceBlock ) | |
SourceBlock - > GetRootBlock ( ) - > Contains ( TargetBlock ) )
2020-01-22 17:58:55 -05:00
{
2020-09-24 00:43:27 -04:00
if ( SourceVarExpression )
{
if ( SourceVarExpression - > SupportsSoftLinks ( ) )
{
return true ;
}
}
2020-01-22 17:58:55 -05:00
if ( LastCycleCheckExpr ! = SourceExpression & & LastCycleCheckExpr ! = TargetExpression )
{
PrepareCycleChecking ( InSourcePin ) ;
}
TArray < ETraverseRelationShip > & Flags = CycleCheckFlags ;
TraverseParents ( LastCycleCheckExpr , [ & Flags ] ( const FRigVMExprAST * InExpr ) - > bool {
if ( Flags [ InExpr - > GetIndex ( ) ] = = ETraverseRelationShip_Self )
{
return true ;
}
if ( Flags [ InExpr - > GetIndex ( ) ] ! = ETraverseRelationShip_Unknown )
{
return false ;
}
2020-09-24 00:43:27 -04:00
if ( InExpr - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
if ( InExpr - > To < FRigVMVarExprAST > ( ) - > SupportsSoftLinks ( ) )
{
return false ;
}
}
2020-01-22 17:58:55 -05:00
Flags [ InExpr - > GetIndex ( ) ] = ETraverseRelationShip_Parent ;
return true ;
} ) ;
TraverseChildren ( LastCycleCheckExpr , [ & Flags ] ( const FRigVMExprAST * InExpr ) - > bool {
if ( Flags [ InExpr - > GetIndex ( ) ] = = ETraverseRelationShip_Self )
{
return true ;
}
if ( Flags [ InExpr - > GetIndex ( ) ] ! = ETraverseRelationShip_Unknown )
{
return false ;
}
2020-09-24 00:43:27 -04:00
if ( InExpr - > IsA ( FRigVMExprAST : : EType : : Var ) )
{
if ( InExpr - > To < FRigVMVarExprAST > ( ) - > SupportsSoftLinks ( ) )
{
return false ;
}
}
2020-01-22 17:58:55 -05:00
Flags [ InExpr - > GetIndex ( ) ] = ETraverseRelationShip_Child ;
return true ;
} ) ;
bool bFoundCycle = false ;
if ( LastCycleCheckExpr = = SourceExpression )
{
bFoundCycle = Flags [ TargetExpression - > GetIndex ( ) ] = = ETraverseRelationShip_Child ;
}
else
{
bFoundCycle = Flags [ SourceExpression - > GetIndex ( ) ] = = ETraverseRelationShip_Parent ;
}
if ( bFoundCycle )
{
if ( OutFailureReason )
{
* OutFailureReason = FString ( TEXT ( " Cycles are not allowed. " ) ) ;
}
return false ;
}
}
else
{
2020-09-24 00:43:27 -04:00
// if one of the blocks is not part of the current
// execution - that's fine.
2020-01-22 17:58:55 -05:00
if ( SourceBlock - > GetRootBlock ( ) - > ContainsEntry ( ) ! =
TargetBlock - > GetRootBlock ( ) - > ContainsEntry ( ) )
{
return true ;
}
if ( OutFailureReason )
{
2020-09-24 00:43:27 -04:00
* OutFailureReason = FString : : Printf ( TEXT ( " You cannot combine nodes from \" %s \" and \" %s \" . " ) , * SourceBlock - > GetName ( ) . ToString ( ) , * TargetBlock - > GetName ( ) . ToString ( ) ) ;
2020-01-22 17:58:55 -05:00
}
return false ;
}
return true ;
}
FString FRigVMParserAST : : DumpText ( ) const
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
FString Result ;
for ( FRigVMExprAST * RootExpr : RootExpressions )
{
2020-11-18 07:48:31 -04:00
if ( RootExpr = = GetObsoleteBlock ( false /* create */ ) )
{
continue ;
}
2020-01-22 17:58:55 -05:00
Result + = TEXT ( " \n " ) + RootExpr - > DumpText ( ) ;
}
return Result ;
}
FString FRigVMParserAST : : DumpDot ( ) const
{
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
TArray < bool > OutExpressionDefined ;
OutExpressionDefined . AddZeroed ( Expressions . Num ( ) ) ;
2021-10-06 11:19:48 -04:00
FVisualGraph VisualGraph ( TEXT ( " AST " ) ) ;
2020-01-22 17:58:55 -05:00
2021-10-06 11:19:48 -04:00
VisualGraph . AddSubGraph ( TEXT ( " AST " ) , FName ( TEXT ( " AST " ) ) ) ;
VisualGraph . AddSubGraph ( TEXT ( " unused " ) , FName ( TEXT ( " Unused " ) ) ) ;
struct Local
2020-01-22 17:58:55 -05:00
{
2021-10-06 11:19:48 -04:00
static TArray < int32 > VisitChildren ( const FRigVMExprAST * InExpr , int32 InSubGraphIndex , FVisualGraph & OutGraph )
{
TArray < int32 > ChildNodeIndices ;
for ( FRigVMExprAST * Child : InExpr - > Children )
{
ChildNodeIndices . Add ( VisitExpr ( Child , InSubGraphIndex , OutGraph ) ) ;
}
return ChildNodeIndices ;
}
static int32 VisitExpr ( const FRigVMExprAST * InExpr , int32 InSubGraphIndex , FVisualGraph & OutGraph )
{
const FName NodeName = * FString : : Printf ( TEXT ( " node_%d " ) , InExpr - > GetIndex ( ) ) ;
int32 NodeIndex = OutGraph . FindNode ( NodeName ) ;
if ( NodeIndex ! = INDEX_NONE )
{
return NodeIndex ;
}
FString Label = InExpr - > GetName ( ) . ToString ( ) ;
TOptional < EVisualGraphShape > Shape = EVisualGraphShape : : Ellipse ;
int32 SubGraphIndex = InSubGraphIndex ;
switch ( InExpr - > GetType ( ) )
{
case FRigVMExprAST : : EType : : Literal :
{
Label = FString : : Printf ( TEXT ( " %s(Literal) " ) , * InExpr - > To < FRigVMLiteralExprAST > ( ) - > GetPin ( ) - > GetName ( ) ) ;
break ;
}
case FRigVMExprAST : : EType : : ExternalVar :
{
Label = FString : : Printf ( TEXT ( " %s(ExternalVar) " ) , * InExpr - > To < FRigVMExternalVarExprAST > ( ) - > GetPin ( ) - > GetBoundVariableName ( ) ) ;
break ;
}
case FRigVMExprAST : : EType : : Var :
{
if ( InExpr - > To < FRigVMVarExprAST > ( ) - > IsGraphParameter ( ) )
{
URigVMParameterNode * ParameterNode = Cast < URigVMParameterNode > ( InExpr - > To < FRigVMVarExprAST > ( ) - > GetPin ( ) - > GetNode ( ) ) ;
check ( ParameterNode ) ;
Label = FString : : Printf ( TEXT ( " Param %s " ) , * ParameterNode - > GetParameterName ( ) . ToString ( ) ) ;
}
else if ( InExpr - > To < FRigVMVarExprAST > ( ) - > IsGraphVariable ( ) )
{
URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( InExpr - > To < FRigVMVarExprAST > ( ) - > GetPin ( ) - > GetNode ( ) ) ;
check ( VariableNode ) ;
Label = FString : : Printf ( TEXT ( " Variable %s " ) , * VariableNode - > GetVariableName ( ) . ToString ( ) ) ;
}
else if ( InExpr - > To < FRigVMVarExprAST > ( ) - > IsEnumValue ( ) )
{
URigVMEnumNode * EnumNode = Cast < URigVMEnumNode > ( InExpr - > To < FRigVMVarExprAST > ( ) - > GetPin ( ) - > GetNode ( ) ) ;
check ( EnumNode ) ;
Label = FString : : Printf ( TEXT ( " Enum %s " ) , * EnumNode - > GetCPPType ( ) ) ;
}
else
{
Label = InExpr - > To < FRigVMVarExprAST > ( ) - > GetPin ( ) - > GetName ( ) ;
}
if ( InExpr - > To < FRigVMVarExprAST > ( ) - > IsExecuteContext ( ) )
{
Shape = EVisualGraphShape : : House ;
}
break ;
}
case FRigVMExprAST : : EType : : Block :
{
if ( InExpr - > GetParent ( ) = = nullptr )
{
Label = TEXT ( " Unused " ) ;
SubGraphIndex = OutGraph . FindSubGraph ( TEXT ( " unused " ) ) ; ;
}
else
{
Label = TEXT ( " Block " ) ;
}
break ;
}
case FRigVMExprAST : : EType : : Assign :
{
Label = TEXT ( " = " ) ;
break ;
}
case FRigVMExprAST : : EType : : Copy :
{
Label = TEXT ( " Copy " ) ;
break ;
}
case FRigVMExprAST : : EType : : CachedValue :
{
Label = TEXT ( " Cache " ) ;
break ;
}
case FRigVMExprAST : : EType : : CallExtern :
{
if ( URigVMUnitNode * Node = Cast < URigVMUnitNode > ( InExpr - > To < FRigVMCallExternExprAST > ( ) - > GetNode ( ) ) )
{
Label = Node - > GetScriptStruct ( ) - > GetName ( ) ;
}
break ;
}
case FRigVMExprAST : : EType : : NoOp :
{
Label = TEXT ( " NoOp " ) ;
break ;
}
case FRigVMExprAST : : EType : : Array :
{
ERigVMOpCode OpCode = CastChecked < URigVMArrayNode > ( InExpr - > To < FRigVMArrayExprAST > ( ) - > GetNode ( ) ) - > GetOpCode ( ) ;
Label = StaticEnum < ERigVMOpCode > ( ) - > GetDisplayNameTextByValue ( ( int64 ) OpCode ) . ToString ( ) ;
break ;
}
case FRigVMExprAST : : EType : : Exit :
{
Label = TEXT ( " Exit " ) ;
break ;
}
case FRigVMExprAST : : EType : : Entry :
{
SubGraphIndex = OutGraph . FindSubGraph ( InExpr - > GetName ( ) ) ;
if ( SubGraphIndex = = INDEX_NONE )
{
const int32 ASTGraphIndex = OutGraph . FindSubGraph ( TEXT ( " AST " ) ) ;
SubGraphIndex = OutGraph . AddSubGraph ( InExpr - > GetName ( ) , InExpr - > GetName ( ) , ASTGraphIndex ) ;
}
break ;
}
default :
{
break ;
}
}
switch ( InExpr - > GetType ( ) )
{
case FRigVMExprAST : : EType : : Entry :
case FRigVMExprAST : : EType : : Exit :
case FRigVMExprAST : : EType : : Branch :
case FRigVMExprAST : : EType : : Block :
{
Shape = EVisualGraphShape : : Diamond ;
break ;
}
case FRigVMExprAST : : EType : : Assign :
case FRigVMExprAST : : EType : : Copy :
case FRigVMExprAST : : EType : : CallExtern :
case FRigVMExprAST : : EType : : If :
case FRigVMExprAST : : EType : : Select :
case FRigVMExprAST : : EType : : NoOp :
{
Shape = EVisualGraphShape : : Box ;
break ;
}
default :
{
break ;
}
}
if ( ! Label . IsEmpty ( ) )
{
const TOptional < FName > DisplayName = FName ( * Label ) ;
NodeIndex = OutGraph . AddNode ( NodeName , DisplayName , TOptional < FLinearColor > ( ) , Shape ) ;
OutGraph . AddNodeToSubGraph ( NodeIndex , SubGraphIndex ) ;
}
TArray < int32 > ChildNodeIndices = VisitChildren ( InExpr , SubGraphIndex , OutGraph ) ;
if ( NodeIndex ! = INDEX_NONE )
{
for ( const int32 ChildNodeIndex : ChildNodeIndices )
{
if ( ChildNodeIndex ! = INDEX_NONE )
{
OutGraph . AddEdge ( ChildNodeIndex , NodeIndex , EVisualGraphEdgeDirection : : SourceToTarget ) ;
}
}
}
return NodeIndex ;
}
} ;
for ( FRigVMExprAST * Expr : RootExpressions )
{
if ( Expr = = GetObsoleteBlock ( false ) )
2020-11-18 07:48:31 -04:00
{
continue ;
}
2021-10-06 11:19:48 -04:00
Local : : VisitExpr ( Expr , INDEX_NONE , VisualGraph ) ;
2020-01-22 17:58:55 -05:00
}
2021-10-06 11:19:48 -04:00
return VisualGraph . DumpDot ( ) ;
2020-01-22 17:58:55 -05:00
}
2020-11-18 07:48:31 -04:00
FRigVMBlockExprAST * FRigVMParserAST : : GetObsoleteBlock ( bool bCreateIfMissing )
2020-09-24 00:43:27 -04:00
{
2020-11-18 07:48:31 -04:00
if ( ObsoleteBlock = = nullptr & & bCreateIfMissing )
2020-09-24 00:43:27 -04:00
{
2021-01-12 06:47:41 -04:00
ObsoleteBlock = MakeExpr < FRigVMBlockExprAST > ( FRigVMExprAST : : EType : : Block , FRigVMASTProxy ( ) ) ;
2020-09-24 00:43:27 -04:00
ObsoleteBlock - > bIsObsolete = true ;
RootExpressions . Add ( ObsoleteBlock ) ;
}
return ObsoleteBlock ;
}
2020-11-18 07:48:31 -04:00
const FRigVMBlockExprAST * FRigVMParserAST : : GetObsoleteBlock ( bool bCreateIfMissing ) const
2020-09-24 00:43:27 -04:00
{
2020-11-18 07:48:31 -04:00
if ( ObsoleteBlock = = nullptr & & bCreateIfMissing )
2020-09-24 00:43:27 -04:00
{
FRigVMParserAST * MutableThis = ( FRigVMParserAST * ) this ;
2021-01-12 06:47:41 -04:00
MutableThis - > ObsoleteBlock = MutableThis - > MakeExpr < FRigVMBlockExprAST > ( FRigVMExprAST : : EType : : Block , FRigVMASTProxy ( ) ) ;
2020-09-24 00:43:27 -04:00
MutableThis - > ObsoleteBlock - > bIsObsolete = true ;
MutableThis - > RootExpressions . Add ( MutableThis - > ObsoleteBlock ) ;
}
return ObsoleteBlock ;
}
2021-04-13 12:03:23 -04:00
void FRigVMParserAST : : RemoveExpressions ( TArray < FRigVMExprAST * > InExprs )
2020-01-22 17:58:55 -05:00
{
2021-04-13 12:03:23 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2020-09-24 00:43:27 -04:00
2021-04-13 12:03:23 -04:00
if ( InExprs . IsEmpty ( ) )
{
return ;
}
RefreshExprIndices ( ) ;
TArray < FRigVMExprAST * > ExpressionsToRemove ;
ExpressionsToRemove . Append ( InExprs ) ;
TArray < int32 > NumRemainingParents ;
NumRemainingParents . AddUninitialized ( Expressions . Num ( ) ) ;
for ( int32 ExpressionIndex = 0 ; ExpressionIndex < Expressions . Num ( ) ; ExpressionIndex + + )
{
NumRemainingParents [ ExpressionIndex ] = Expressions [ ExpressionIndex ] - > Parents . Num ( ) ;
}
TArray < bool > bRemoveExpression ;
bRemoveExpression . AddZeroed ( Expressions . Num ( ) ) ;
for ( int32 ExpressionIndex = 0 ; ExpressionIndex < ExpressionsToRemove . Num ( ) ; ExpressionIndex + + )
{
FRigVMExprAST * Expr = ExpressionsToRemove [ ExpressionIndex ] ;
bRemoveExpression [ Expr - > GetIndex ( ) ] = true ;
for ( FRigVMExprAST * Child : Expr - > Children )
2020-09-24 00:43:27 -04:00
{
2021-04-13 12:03:23 -04:00
if ( - - NumRemainingParents [ Child - > GetIndex ( ) ] = = 0 )
{
ExpressionsToRemove . Add ( Child ) ;
}
2020-09-24 00:43:27 -04:00
}
2020-01-22 17:58:55 -05:00
}
2021-04-13 12:03:23 -04:00
TArray < FRigVMExprAST * > RemainingExpressions ;
RemainingExpressions . Reserve ( Expressions . Num ( ) - ExpressionsToRemove . Num ( ) ) ;
for ( int32 ExpressionIndex = 0 ; ExpressionIndex < Expressions . Num ( ) ; ExpressionIndex + + )
{
if ( ! bRemoveExpression [ ExpressionIndex ] )
{
FRigVMExprAST * Expr = Expressions [ ExpressionIndex ] ;
RemainingExpressions . Add ( Expr ) ;
for ( int32 ChildIndex = 0 ; ChildIndex < Expr - > Children . Num ( ) ; ChildIndex + + )
{
FRigVMExprAST * ChildExpr = Expr - > Children [ ChildIndex ] ;
if ( bRemoveExpression [ ChildExpr - > GetIndex ( ) ] )
{
Expr - > Children . RemoveAt ( ChildIndex ) ;
break ;
}
}
for ( int32 ParentIndex = 0 ; ParentIndex < Expr - > Parents . Num ( ) ; ParentIndex + + )
{
FRigVMExprAST * ParentExpr = Expr - > Parents [ ParentIndex ] ;
if ( bRemoveExpression [ ParentExpr - > GetIndex ( ) ] )
{
Expr - > Parents . RemoveAt ( ParentIndex ) ;
break ;
}
}
}
}
Expressions = RemainingExpressions ;
2020-01-22 17:58:55 -05:00
2021-01-12 06:47:41 -04:00
TArray < FRigVMASTProxy > KeysToRemove ;
for ( TPair < FRigVMASTProxy , FRigVMExprAST * > Pair : SubjectToExpression )
2020-01-22 17:58:55 -05:00
{
2021-04-13 12:03:23 -04:00
if ( bRemoveExpression [ Pair . Value - > GetIndex ( ) ] )
2020-01-22 17:58:55 -05:00
{
KeysToRemove . Add ( Pair . Key ) ;
}
}
2021-04-13 12:03:23 -04:00
2021-01-12 06:47:41 -04:00
for ( const FRigVMASTProxy & KeyToRemove : KeysToRemove )
2020-01-22 17:58:55 -05:00
{
SubjectToExpression . Remove ( KeyToRemove ) ;
}
2021-04-13 12:03:23 -04:00
for ( int32 ExpressionIndex = ExpressionsToRemove . Num ( ) - 1 ; ExpressionIndex > = 0 ; ExpressionIndex - - )
{
delete ExpressionsToRemove [ ExpressionIndex ] ;
}
2020-01-22 17:58:55 -05:00
2021-04-13 12:03:23 -04:00
RefreshExprIndices ( ) ;
2020-01-22 17:58:55 -05:00
}
void FRigVMParserAST : : TraverseParents ( const FRigVMExprAST * InExpr , TFunctionRef < bool ( const FRigVMExprAST * ) > InContinuePredicate )
{
if ( ! InContinuePredicate ( InExpr ) )
{
return ;
}
for ( const FRigVMExprAST * ParentExpr : InExpr - > Parents )
{
TraverseParents ( ParentExpr , InContinuePredicate ) ;
}
}
void FRigVMParserAST : : TraverseChildren ( const FRigVMExprAST * InExpr , TFunctionRef < bool ( const FRigVMExprAST * ) > InContinuePredicate )
{
if ( ! InContinuePredicate ( InExpr ) )
{
return ;
}
for ( const FRigVMExprAST * ChildExpr : InExpr - > Children )
{
TraverseChildren ( ChildExpr , InContinuePredicate ) ;
}
}
2021-01-12 06:47:41 -04:00
const TArray < FRigVMASTProxy > & FRigVMParserAST : : GetSourcePins ( const FRigVMASTProxy & InPinProxy ) const
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
if ( const TArray < FRigVMASTProxy > * LinkedPins = SourceLinks . Find ( InPinProxy ) )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
return * LinkedPins ;
2020-11-18 07:48:31 -04:00
}
2021-01-12 06:47:41 -04:00
return EmptyProxyArray ;
2020-11-18 07:48:31 -04:00
}
2021-01-12 06:47:41 -04:00
const TArray < FRigVMASTProxy > & FRigVMParserAST : : GetTargetPins ( const FRigVMASTProxy & InPinProxy ) const
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
if ( const TArray < FRigVMASTProxy > * LinkedPins = TargetLinks . Find ( InPinProxy ) )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
return * LinkedPins ;
2020-11-18 07:48:31 -04:00
}
2021-01-12 06:47:41 -04:00
return EmptyProxyArray ;
2020-11-18 07:48:31 -04:00
}
2021-01-12 06:47:41 -04:00
TArray < FRigVMPinProxyPair > FRigVMParserAST : : GetSourceLinks ( const FRigVMASTProxy & InPinProxy , bool bRecursive ) const
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
const TArray < FRigVMASTProxy > & SourcePins = GetSourcePins ( InPinProxy ) ;
2020-11-18 07:48:31 -04:00
2021-01-12 06:47:41 -04:00
TArray < FRigVMPinProxyPair > Pairs ;
for ( const FRigVMASTProxy & SourcePin : SourcePins )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
Pairs . Add ( FRigVMPinProxyPair ( SourcePin , InPinProxy ) ) ;
2020-11-18 07:48:31 -04:00
}
if ( bRecursive )
{
2021-01-12 06:47:41 -04:00
URigVMPin * Pin = InPinProxy . GetSubjectChecked < URigVMPin > ( ) ;
for ( URigVMPin * SubPin : Pin - > GetSubPins ( ) )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SubPinProxy = InPinProxy . GetSibling ( SubPin ) ;
Pairs . Append ( GetSourceLinks ( SubPinProxy , true ) ) ;
2020-11-18 07:48:31 -04:00
}
}
return Pairs ;
}
2021-01-12 06:47:41 -04:00
TArray < FRigVMPinProxyPair > FRigVMParserAST : : GetTargetLinks ( const FRigVMASTProxy & InPinProxy , bool bRecursive ) const
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
const TArray < FRigVMASTProxy > & TargetPins = GetTargetPins ( InPinProxy ) ;
2020-11-18 07:48:31 -04:00
2021-01-12 06:47:41 -04:00
TArray < FRigVMPinProxyPair > Pairs ;
for ( const FRigVMASTProxy & TargetPin : TargetPins )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
Pairs . Add ( FRigVMPinProxyPair ( InPinProxy , TargetPin ) ) ;
2020-11-18 07:48:31 -04:00
}
if ( bRecursive )
{
2021-01-12 06:47:41 -04:00
URigVMPin * Pin = InPinProxy . GetSubjectChecked < URigVMPin > ( ) ;
for ( URigVMPin * SubPin : Pin - > GetSubPins ( ) )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SubPinProxy = InPinProxy . GetSibling ( SubPin ) ;
Pairs . Append ( GetTargetLinks ( SubPinProxy , true ) ) ;
2020-11-18 07:48:31 -04:00
}
}
return Pairs ;
}
void FRigVMParserAST : : Inline ( URigVMGraph * InGraph )
{
2021-01-12 06:47:41 -04:00
TArray < FRigVMASTProxy > LocalNodeProxies ;
for ( URigVMNode * LocalNode : InGraph - > GetNodes ( ) )
{
LocalNodeProxies . Add ( FRigVMASTProxy : : MakeFromUObject ( LocalNode ) ) ;
}
Inline ( InGraph , LocalNodeProxies ) ;
2020-11-18 07:48:31 -04:00
}
2021-01-12 06:47:41 -04:00
void FRigVMParserAST : : Inline ( URigVMGraph * InGraph , const TArray < FRigVMASTProxy > & InNodeProxies )
2020-11-18 07:48:31 -04:00
{
2021-01-21 05:20:34 -04:00
DECLARE_SCOPE_HIERARCHICAL_COUNTER_FUNC ( )
2020-11-18 07:48:31 -04:00
struct LocalPinTraversalInfo
{
2021-01-19 04:57:43 -04:00
URigVMPin : : FPinOverrideMap * PinOverrides ;
2021-09-27 11:48:28 -04:00
TMap < FRigVMASTProxy , FRigVMASTProxy > * SourcePins ;
2021-01-12 06:47:41 -04:00
TMap < FRigVMASTProxy , TArray < FRigVMASTProxy > > * TargetLinks ;
TMap < FRigVMASTProxy , TArray < FRigVMASTProxy > > * SourceLinks ;
TArray < FRigVMASTProxy > LibraryNodeCallstack ;
2021-01-19 07:26:41 -04:00
FRigVMParserASTSettings * Settings ;
2020-12-01 04:05:50 -04:00
2021-01-12 06:47:41 -04:00
static bool ShouldRecursePin ( const FRigVMASTProxy & InPinProxy )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
URigVMPin * Pin = InPinProxy . GetSubjectChecked < URigVMPin > ( ) ;
URigVMNode * Node = Pin - > GetNode ( ) ;
2021-09-27 11:50:32 -04:00
if ( URigVMVariableNode * VarNode = Cast < URigVMVariableNode > ( Node ) )
{
return VarNode - > IsInputArgument ( ) ;
}
2020-12-01 04:05:50 -04:00
return Node - > IsA < URigVMRerouteNode > ( ) | |
Node - > IsA < URigVMLibraryNode > ( ) | |
Node - > IsA < URigVMFunctionEntryNode > ( ) | |
Node - > IsA < URigVMFunctionReturnNode > ( ) ;
}
2021-01-12 06:47:41 -04:00
static bool IsValidPinForAST ( const FRigVMASTProxy & InPinProxy )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
return ! ShouldRecursePin ( InPinProxy ) ;
2020-12-01 04:05:50 -04:00
}
2021-01-12 06:47:41 -04:00
static bool IsValidLinkForAST ( const FRigVMASTProxy & InSourcePinProxy , const FRigVMASTProxy & InTargetPinProxy )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
return IsValidPinForAST ( InSourcePinProxy ) & & IsValidPinForAST ( InTargetPinProxy ) ;
2020-12-01 04:05:50 -04:00
}
2020-11-18 07:48:31 -04:00
2021-01-12 06:47:41 -04:00
static FRigVMASTProxy FindSourcePin ( const FRigVMASTProxy & InPinProxy , LocalPinTraversalInfo & OutTraversalInfo )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
URigVMPin * Pin = InPinProxy . GetSubjectChecked < URigVMPin > ( ) ;
2020-12-01 04:05:50 -04:00
// if this pin is a root on a library
2021-01-12 06:47:41 -04:00
if ( Pin - > GetParentPin ( ) = = nullptr )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
if ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : Output | |
Pin - > GetDirection ( ) = = ERigVMPinDirection : : IO )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
URigVMNode * Node = Pin - > GetNode ( ) ;
2020-12-01 04:05:50 -04:00
if ( URigVMLibraryNode * LibraryNode = Cast < URigVMLibraryNode > ( Node ) )
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy LibraryNodeProxy = InPinProxy . GetSibling ( LibraryNode ) ;
if ( ! OutTraversalInfo . LibraryNodeCallstack . Contains ( LibraryNodeProxy ) )
2020-12-01 04:05:50 -04:00
{
if ( URigVMFunctionReturnNode * ReturnNode = LibraryNode - > GetReturnNode ( ) )
{
2021-01-12 06:47:41 -04:00
if ( URigVMPin * ReturnPin = ReturnNode - > FindPin ( Pin - > GetName ( ) ) )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
OutTraversalInfo . LibraryNodeCallstack . Push ( LibraryNodeProxy ) ;
FRigVMASTProxy ReturnPinProxy = LibraryNodeProxy . GetChild ( ReturnPin ) ;
FRigVMASTProxy SourcePinProxy = FindSourcePin ( ReturnPinProxy , OutTraversalInfo ) ;
SourcePinProxy = SourcePinProxy . IsValid ( ) ? SourcePinProxy : ReturnPinProxy ;
2021-09-27 11:48:28 -04:00
OutTraversalInfo . SourcePins - > FindOrAdd ( InPinProxy ) = SourcePinProxy ;
2021-01-12 06:47:41 -04:00
OutTraversalInfo . LibraryNodeCallstack . Pop ( ) ;
return SourcePinProxy ;
2020-12-01 04:05:50 -04:00
}
}
}
}
2021-09-27 11:50:32 -04:00
else if ( URigVMVariableNode * VariableNode = Cast < URigVMVariableNode > ( Node ) )
{
if ( VariableNode - > IsInputArgument ( ) )
{
if ( URigVMFunctionEntryNode * EntryNode = VariableNode - > GetGraph ( ) - > GetEntryNode ( ) )
{
if ( URigVMPin * EntryPin = EntryNode - > FindPin ( VariableNode - > GetVariableName ( ) . ToString ( ) ) )
{
FRigVMASTProxy EntryPinProxy = InPinProxy . GetSibling ( EntryPin ) ;
FRigVMASTProxy SourcePinProxy = FindSourcePin ( EntryPinProxy , OutTraversalInfo ) ;
SourcePinProxy = SourcePinProxy . IsValid ( ) ? SourcePinProxy : EntryPinProxy ;
2021-09-27 12:08:28 -04:00
OutTraversalInfo . SourcePins - > FindOrAdd ( InPinProxy ) = SourcePinProxy ;
2021-09-27 11:50:32 -04:00
return SourcePinProxy ;
}
}
}
}
2020-12-01 04:05:50 -04:00
else if ( URigVMFunctionEntryNode * EntryNode = Cast < URigVMFunctionEntryNode > ( Node ) )
{
2021-01-12 06:47:41 -04:00
for ( int32 LibraryNodeIndex = OutTraversalInfo . LibraryNodeCallstack . Num ( ) - 1 ; LibraryNodeIndex > = 0 ; LibraryNodeIndex - - )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy LibraryNodeProxy = OutTraversalInfo . LibraryNodeCallstack [ LibraryNodeIndex ] ;
URigVMLibraryNode * LastLibraryNode = LibraryNodeProxy . GetSubject < URigVMLibraryNode > ( ) ;
if ( LastLibraryNode = = nullptr )
{
continue ;
}
2020-12-01 04:05:50 -04:00
if ( LastLibraryNode - > GetEntryNode ( ) = = EntryNode )
{
2021-01-12 06:47:41 -04:00
if ( URigVMPin * LibraryPin = LastLibraryNode - > FindPin ( Pin - > GetName ( ) ) )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy LibraryPinProxy = LibraryNodeProxy . GetSibling ( LibraryPin ) ;
FRigVMASTProxy SourcePinProxy = FindSourcePin ( LibraryPinProxy , OutTraversalInfo ) ;
SourcePinProxy = SourcePinProxy . IsValid ( ) ? SourcePinProxy : LibraryPinProxy ;
2021-09-27 11:48:28 -04:00
OutTraversalInfo . SourcePins - > FindOrAdd ( InPinProxy ) = SourcePinProxy ;
2021-01-12 06:47:41 -04:00
return SourcePinProxy ;
2020-12-01 04:05:50 -04:00
}
}
}
}
}
}
2021-01-12 06:47:41 -04:00
if ( Pin - > GetDirection ( ) ! = ERigVMPinDirection : : Input & &
2021-01-20 09:43:48 -04:00
Pin - > GetDirection ( ) ! = ERigVMPinDirection : : IO & &
Pin - > GetDirection ( ) ! = ERigVMPinDirection : : Output )
2020-11-19 04:52:31 -04:00
{
2021-01-12 06:47:41 -04:00
return FRigVMASTProxy ( ) ;
2020-11-19 04:52:31 -04:00
}
2020-12-01 04:05:50 -04:00
bool bIOPinOnLeftOfLibraryNode = false ;
2021-01-12 06:47:41 -04:00
if ( Pin - > GetDirection ( ) = = ERigVMPinDirection : : IO )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
if ( URigVMLibraryNode * LibraryNode = Cast < URigVMLibraryNode > ( Pin - > GetNode ( ) ) )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
bIOPinOnLeftOfLibraryNode = OutTraversalInfo . LibraryNodeCallstack . Contains ( InPinProxy . GetSibling ( LibraryNode ) ) ;
2020-12-01 04:05:50 -04:00
}
}
if ( ! bIOPinOnLeftOfLibraryNode )
{
// note: this map isn't going to work for functions which are referenced.
// (since the pin objects are shared between multiple invocation nodes)
2021-09-27 11:48:28 -04:00
if ( const FRigVMASTProxy * SourcePinProxy = OutTraversalInfo . SourcePins - > Find ( InPinProxy ) )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
return * SourcePinProxy ;
2020-12-01 04:05:50 -04:00
}
2020-11-18 07:48:31 -04:00
}
2020-11-19 04:52:31 -04:00
TArray < FString > SegmentPath ;
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SourcePinProxy ;
2020-11-19 04:52:31 -04:00
2021-01-12 06:47:41 -04:00
URigVMPin * ChildPin = Pin ;
2020-11-19 04:52:31 -04:00
while ( ChildPin ! = nullptr )
2020-11-18 07:48:31 -04:00
{
2021-01-20 09:43:48 -04:00
if ( ChildPin - > GetDirection ( ) = = ERigVMPinDirection : : Output & & ChildPin - > GetParentPin ( ) = = nullptr )
{
2021-06-10 06:16:12 -04:00
if ( URigVMFunctionEntryNode * EntryNode = Cast < URigVMFunctionEntryNode > ( ChildPin - > GetNode ( ) ) )
2021-01-20 09:43:48 -04:00
{
if ( URigVMCollapseNode * OuterNode = Cast < URigVMCollapseNode > ( EntryNode - > GetGraph ( ) - > GetOuter ( ) ) )
{
if ( URigVMPin * OuterPin = OuterNode - > FindPin ( ChildPin - > GetName ( ) ) )
{
FRigVMASTProxy OuterPinProxy = InPinProxy . GetParent ( ) . GetSibling ( OuterPin ) ;
SourcePinProxy = FindSourcePin ( OuterPinProxy , OutTraversalInfo ) ;
SourcePinProxy = SourcePinProxy . IsValid ( ) ? SourcePinProxy : OuterPinProxy ;
break ;
}
}
}
2021-06-10 06:16:12 -04:00
else if ( URigVMLibraryNode * LibraryNode = Cast < URigVMLibraryNode > ( ChildPin - > GetNode ( ) ) )
{
2021-09-27 06:52:24 -04:00
if ( ChildPin ! = InPinProxy . GetSubject < URigVMPin > ( ) )
2021-06-10 06:16:12 -04:00
{
2021-09-27 06:52:24 -04:00
const FRigVMASTProxy ChildPinProxy = InPinProxy . GetSibling ( ChildPin ) ;
if ( ShouldRecursePin ( ChildPinProxy ) )
2021-06-10 06:16:12 -04:00
{
2021-09-27 06:52:24 -04:00
FRigVMASTProxy SourceSourcePinProxy = FindSourcePin ( ChildPinProxy , OutTraversalInfo ) ;
if ( SourceSourcePinProxy . IsValid ( ) )
{
SourcePinProxy = SourceSourcePinProxy ;
}
2021-06-10 06:16:12 -04:00
}
}
}
2021-01-20 09:43:48 -04:00
}
2020-11-19 04:52:31 -04:00
TArray < URigVMLink * > SourceLinks = ChildPin - > GetSourceLinks ( false /* recursive */ ) ;
2021-11-29 11:26:01 -05:00
if ( SourceLinks . Num ( ) > 0 )
2020-11-18 07:48:31 -04:00
{
2021-11-15 05:32:56 -05:00
URigVMPin * SourcePin = nullptr ;
if ( SourceLinks . Num ( ) > 0 )
{
SourcePin = SourceLinks [ 0 ] - > GetSourcePin ( ) ;
}
else
{
if ( URigVMGraph * Graph = ChildPin - > GetGraph ( ) )
{
if ( URigVMFunctionEntryNode * EntryNode = Graph - > GetEntryNode ( ) )
{
SourcePin = EntryNode - > FindPin ( ChildPin - > GetBoundVariableName ( ) ) ;
}
}
}
check ( SourcePin ) ;
2021-01-12 06:47:41 -04:00
SourcePinProxy = InPinProxy . GetSibling ( SourcePin ) ;
2020-11-18 07:48:31 -04:00
2020-11-19 04:52:31 -04:00
// only continue the recursion on reroutes
2021-01-12 06:47:41 -04:00
if ( ShouldRecursePin ( SourcePinProxy ) )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SourceSourcePinProxy = FindSourcePin ( SourcePinProxy , OutTraversalInfo ) ;
if ( SourceSourcePinProxy . IsValid ( ) )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
SourcePinProxy = SourceSourcePinProxy ;
2020-11-18 07:48:31 -04:00
}
}
2020-11-19 04:52:31 -04:00
break ;
2020-11-18 07:48:31 -04:00
}
2020-11-19 04:52:31 -04:00
URigVMPin * ParentPin = ChildPin - > GetParentPin ( ) ;
if ( ParentPin )
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy ParentPinProxy = InPinProxy . GetSibling ( ParentPin ) ;
2020-11-19 04:52:31 -04:00
// if we found a parent pin which has a source that is not a reroute
2021-09-27 11:48:28 -04:00
if ( FRigVMASTProxy * ParentSourcePinProxyPtr = OutTraversalInfo . SourcePins - > Find ( ParentPinProxy ) )
2020-11-19 04:52:31 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy & ParentSourcePinProxy = * ParentSourcePinProxyPtr ;
if ( ParentSourcePinProxy . IsValid ( ) )
2020-11-19 04:52:31 -04:00
{
2021-01-12 06:47:41 -04:00
if ( ! ShouldRecursePin ( ParentSourcePinProxy ) )
2020-11-19 04:52:31 -04:00
{
2021-01-12 06:47:41 -04:00
SourcePinProxy = FRigVMASTProxy ( ) ;
2020-11-19 04:52:31 -04:00
break ;
}
}
}
SegmentPath . Push ( ChildPin - > GetName ( ) ) ;
}
ChildPin = ParentPin ;
}
2021-01-12 06:47:41 -04:00
if ( SourcePinProxy . IsValid ( ) )
2020-11-19 04:52:31 -04:00
{
while ( ! SegmentPath . IsEmpty ( ) )
{
FString Segment = SegmentPath . Pop ( ) ;
2021-01-12 06:47:41 -04:00
URigVMPin * SourcePin = SourcePinProxy . GetSubjectChecked < URigVMPin > ( ) ;
2020-11-19 04:52:31 -04:00
if ( URigVMPin * SourceSubPin = SourcePin - > FindSubPin ( Segment ) )
{
2021-01-12 06:47:41 -04:00
SourcePinProxy = SourcePinProxy . GetSibling ( SourceSubPin ) ;
2020-11-19 04:52:31 -04:00
// only continue the recursion on reroutes
2021-01-12 06:47:41 -04:00
if ( ShouldRecursePin ( SourcePinProxy ) )
2020-11-19 04:52:31 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SourceSourceSubPinProxy = FindSourcePin ( SourcePinProxy , OutTraversalInfo ) ;
if ( SourceSourceSubPinProxy . IsValid ( ) )
2020-11-19 04:52:31 -04:00
{
2021-01-12 06:47:41 -04:00
SourcePinProxy = SourceSourceSubPinProxy ;
2020-11-19 04:52:31 -04:00
}
}
}
else
{
2021-01-12 06:47:41 -04:00
SourcePinProxy = FRigVMASTProxy ( ) ;
2020-11-19 04:52:31 -04:00
break ;
}
}
2020-11-18 07:48:31 -04:00
}
2020-12-01 04:05:50 -04:00
if ( ! bIOPinOnLeftOfLibraryNode )
2020-11-19 04:52:31 -04:00
{
2021-09-27 11:48:28 -04:00
OutTraversalInfo . SourcePins - > FindOrAdd ( InPinProxy ) = SourcePinProxy ;
2020-11-19 04:52:31 -04:00
}
2021-01-12 06:47:41 -04:00
return SourcePinProxy ;
2020-11-18 07:48:31 -04:00
}
2021-01-12 06:47:41 -04:00
static void VisitPin ( const FRigVMASTProxy & InPinProxy , LocalPinTraversalInfo & OutTraversalInfo )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SourcePinProxy = FindSourcePin ( InPinProxy , OutTraversalInfo ) ;
if ( SourcePinProxy . IsValid ( ) )
2020-11-18 07:48:31 -04:00
{
// The source pin is the final determined source pin, since
// FindSourcePin is recursive.
// If the source pin is on a reroute node, this means that
// we only care about the default value - since it is a
// "hanging" reroute without any live input.
2020-12-01 04:05:50 -04:00
// same goes for library nodes or return nodes - we'll
// just use the default pin value in that case.
2020-11-18 07:48:31 -04:00
2021-01-12 06:47:41 -04:00
URigVMPin * SourcePin = SourcePinProxy . GetSubjectChecked < URigVMPin > ( ) ;
2020-12-01 04:05:50 -04:00
URigVMNode * SourceNode = SourcePin - > GetNode ( ) ;
if ( SourceNode - > IsA < URigVMRerouteNode > ( ) | |
SourceNode - > IsA < URigVMLibraryNode > ( ) | |
SourceNode - > IsA < URigVMFunctionReturnNode > ( ) )
2020-11-18 07:48:31 -04:00
{
2021-01-19 04:57:43 -04:00
OutTraversalInfo . PinOverrides - > FindOrAdd ( InPinProxy ) = URigVMPin : : FPinOverrideValue ( SourcePin ) ;
2020-11-18 07:48:31 -04:00
}
else
{
2021-01-12 06:47:41 -04:00
if ( IsValidLinkForAST ( SourcePinProxy , InPinProxy ) )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
OutTraversalInfo . SourceLinks - > FindOrAdd ( InPinProxy ) . Add ( SourcePinProxy ) ;
OutTraversalInfo . TargetLinks - > FindOrAdd ( SourcePinProxy ) . Add ( InPinProxy ) ;
2020-12-01 04:05:50 -04:00
}
2020-11-18 07:48:31 -04:00
}
}
2021-01-12 06:47:41 -04:00
URigVMPin * Pin = InPinProxy . GetSubjectChecked < URigVMPin > ( ) ;
for ( URigVMPin * SubPin : Pin - > GetSubPins ( ) )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy SubPinProxy = InPinProxy . GetSibling ( SubPin ) ;
VisitPin ( SubPinProxy , OutTraversalInfo ) ;
2020-11-18 07:48:31 -04:00
}
}
2020-12-01 04:05:50 -04:00
2021-01-12 06:47:41 -04:00
static void VisitNode ( const FRigVMASTProxy & InNodeProxy , LocalPinTraversalInfo & OutTraversalInfo )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
if ( InNodeProxy . IsA < URigVMRerouteNode > ( ) | |
InNodeProxy . IsA < URigVMFunctionEntryNode > ( ) | |
InNodeProxy . IsA < URigVMFunctionReturnNode > ( ) )
2020-12-01 04:05:50 -04:00
{
return ;
}
2021-01-12 06:47:41 -04:00
if ( URigVMLibraryNode * LibraryNode = InNodeProxy . GetSubject < URigVMLibraryNode > ( ) )
2020-12-01 04:05:50 -04:00
{
2021-01-19 07:26:41 -04:00
if ( LibraryNode - > GetContainedGraph ( ) = = nullptr )
{
if ( URigVMFunctionReferenceNode * FunctionRef = Cast < URigVMFunctionReferenceNode > ( LibraryNode ) )
{
FString FunctionPath = FunctionRef - > ReferencedNodePtr . ToString ( ) ;
OutTraversalInfo . Settings - > Reportf (
EMessageSeverity : : Error ,
LibraryNode ,
TEXT ( " Function Reference '%s' references a missing function (%s). " ) ,
* LibraryNode - > GetName ( ) ,
* FunctionPath ) ;
}
else
{
OutTraversalInfo . Settings - > Reportf (
EMessageSeverity : : Error ,
LibraryNode ,
TEXT ( " Library Node '%s' doesn't contain a subgraph. " ) ,
* LibraryNode - > GetName ( ) ) ;
}
return ;
}
2021-01-12 06:47:41 -04:00
OutTraversalInfo . LibraryNodeCallstack . Push ( InNodeProxy ) ;
2020-12-01 04:05:50 -04:00
TArray < URigVMNode * > ContainedNodes = LibraryNode - > GetContainedNodes ( ) ;
for ( URigVMNode * ContainedNode : ContainedNodes )
{
2021-01-12 06:47:41 -04:00
// create a proxy which uses the previous node as a callstack
FRigVMASTProxy ContainedNodeProxy = InNodeProxy . GetChild ( ContainedNode ) ;
VisitNode ( ContainedNodeProxy , OutTraversalInfo ) ;
2020-12-01 04:05:50 -04:00
}
2021-01-12 06:47:41 -04:00
OutTraversalInfo . LibraryNodeCallstack . Pop ( ) ;
2020-12-01 04:05:50 -04:00
}
else
{
2021-01-12 06:47:41 -04:00
URigVMNode * Node = InNodeProxy . GetSubjectChecked < URigVMNode > ( ) ;
for ( URigVMPin * Pin : Node - > GetPins ( ) )
2020-12-01 04:05:50 -04:00
{
2021-01-12 06:47:41 -04:00
FRigVMASTProxy PinProxy = InNodeProxy . GetSibling ( Pin ) ;
LocalPinTraversalInfo : : VisitPin ( PinProxy , OutTraversalInfo ) ;
2020-12-01 04:05:50 -04:00
}
}
}
2020-11-18 07:48:31 -04:00
} ;
2021-01-12 06:47:41 -04:00
NodeProxies . Reset ( ) ;
2020-11-18 07:48:31 -04:00
SourceLinks . Reset ( ) ;
TargetLinks . Reset ( ) ;
2020-12-01 04:05:50 -04:00
// a) find all of the relevant nodes,
// inline and traverse into library nodes
2021-01-12 06:47:41 -04:00
NodeProxies = InNodeProxies ;
2020-11-18 07:48:31 -04:00
// c) flatten links from an entry node / to a return node
// also traverse links along reroutes and flatten them
LocalPinTraversalInfo TraversalInfo ;
2021-01-19 04:57:43 -04:00
TraversalInfo . PinOverrides = & PinOverrides ;
2021-09-27 11:48:28 -04:00
TraversalInfo . SourcePins = & SharedOperandPins ;
2020-11-18 07:48:31 -04:00
TraversalInfo . TargetLinks = & TargetLinks ;
TraversalInfo . SourceLinks = & SourceLinks ;
2021-01-19 07:26:41 -04:00
TraversalInfo . Settings = & Settings ;
2020-11-18 07:48:31 -04:00
2021-01-12 06:47:41 -04:00
for ( const FRigVMASTProxy & NodeProxy : NodeProxies )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
LocalPinTraversalInfo : : VisitNode ( NodeProxy , TraversalInfo ) ;
2020-11-18 07:48:31 -04:00
}
}
2021-01-12 06:47:41 -04:00
bool FRigVMParserAST : : ShouldLinkBeSkipped ( const FRigVMPinProxyPair & InLink ) const
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
URigVMPin * SourcePin = InLink . Key . GetSubjectChecked < URigVMPin > ( ) ;
URigVMPin * TargetPin = InLink . Value . GetSubjectChecked < URigVMPin > ( ) ;
2020-11-18 07:48:31 -04:00
for ( URigVMLink * LinkToSkip : LinksToSkip )
{
2021-01-12 06:47:41 -04:00
if ( LinkToSkip - > GetSourcePin ( ) = = SourcePin & &
LinkToSkip - > GetTargetPin ( ) = = TargetPin )
2020-11-18 07:48:31 -04:00
{
return true ;
}
}
return false ;
}
2021-01-12 06:47:41 -04:00
FString FRigVMParserAST : : GetLinkAsString ( const FRigVMPinProxyPair & InLink )
2020-11-18 07:48:31 -04:00
{
2021-01-12 06:47:41 -04:00
URigVMPin * SourcePin = InLink . Key . GetSubjectChecked < URigVMPin > ( ) ;
URigVMPin * TargetPin = InLink . Value . GetSubjectChecked < URigVMPin > ( ) ;
return FString : : Printf ( TEXT ( " %s -> %s " ) , * SourcePin - > GetPinPath ( ) , * TargetPin - > GetPinPath ( ) ) ;
2020-11-18 07:48:31 -04:00
}