2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "BlueprintGraphPrivatePCH.h"
# include "KismetCompiler.h"
# define LOCTEXT_NAMESPACE "K2Node"
2014-10-14 10:29:11 -04:00
UK2Node_CallFunctionOnMember : : UK2Node_CallFunctionOnMember ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer )
2014-03-14 14:13:41 -04:00
{
}
UEdGraphPin * UK2Node_CallFunctionOnMember : : CreateSelfPin ( const UFunction * Function )
{
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
UEdGraphPin * SelfPin = NULL ;
if ( MemberVariableToCallOn . IsSelfContext ( ) )
{
// This means the function is defined within the blueprint, so the pin should be a true "self" pin
SelfPin = CreatePin ( EGPD_Input , K2Schema - > PC_Object , K2Schema - > PSC_Self , NULL , false , false , K2Schema - > PN_Self ) ;
}
else
{
// This means that the function is declared in an external class, and should reference that class
2015-03-12 14:17:48 -04:00
SelfPin = CreatePin ( EGPD_Input , K2Schema - > PC_Object , TEXT ( " " ) , MemberVariableToCallOn . GetMemberParentClass ( GetBlueprintClassFromNode ( ) ) , false , false , K2Schema - > PN_Self ) ;
2014-03-14 14:13:41 -04:00
}
check ( SelfPin ! = NULL ) ;
return SelfPin ;
}
2015-04-28 11:31:15 -04:00
FText UK2Node_CallFunctionOnMember : : GetFunctionContextString ( ) const
2014-03-14 14:13:41 -04:00
{
2015-03-12 14:17:48 -04:00
UClass * MemberVarClass = MemberVariableToCallOn . GetMemberParentClass ( GetBlueprintClassFromNode ( ) ) ;
2015-04-28 11:31:15 -04:00
FText CallFunctionClassName = ( MemberVarClass ! = NULL ) ? MemberVarClass - > GetDisplayNameText ( ) : FText : : GetEmpty ( ) ;
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " TargetName " ) , CallFunctionClassName ) ;
Args . Add ( TEXT ( " MemberVariableName " ) , FText : : FromName ( MemberVariableToCallOn . GetMemberName ( ) ) ) ;
return FText : : Format ( LOCTEXT ( " CallFunctionOnMemberDifferentContext " , " Target is {TargetName} ({MemberVariableName}) " ) , Args ) ;
2014-03-14 14:13:41 -04:00
}
FNodeHandlingFunctor * UK2Node_CallFunctionOnMember : : CreateNodeHandler ( FKismetCompilerContext & CompilerContext ) const
{
return new FNodeHandlingFunctor ( CompilerContext ) ;
}
void UK2Node_CallFunctionOnMember : : ExpandNode ( class FKismetCompilerContext & CompilerContext , UEdGraph * SourceGraph )
{
// This skips UK2Node_CallFunction::ExpandNode. Instead it spawns a new CallFunction node and does hookup that this is interested in,
// and then that CallFunction node will get its own Expansion to handle the parent portions
UK2Node : : ExpandNode ( CompilerContext , SourceGraph ) ;
2014-10-17 06:37:11 -04:00
const UEdGraphSchema_K2 * Schema = CompilerContext . GetSchema ( ) ;
UFunction * Function = GetTargetFunction ( ) ;
// Create real 'call function' node.
UK2Node_CallFunction * CallFuncNode = CompilerContext . SpawnIntermediateNode < UK2Node_CallFunction > ( this , SourceGraph ) ;
CallFuncNode - > SetFromFunction ( Function ) ;
CallFuncNode - > AllocateDefaultPins ( ) ;
UEdGraphPin * CallFuncSelfPin = Schema - > FindSelfPin ( * CallFuncNode , EGPD_Input ) ;
// Now because you can wire multiple variables to a self pin, need to iterate over each one and create a 'get var' node for each
UEdGraphPin * SelfPin = Schema - > FindSelfPin ( * this , EGPD_Input ) ;
if ( SelfPin ! = NULL )
2014-03-14 14:13:41 -04:00
{
2014-10-17 06:37:11 -04:00
if ( SelfPin - > LinkedTo . Num ( ) = = 0 )
2014-03-14 14:13:41 -04:00
{
2014-10-17 06:37:11 -04:00
UK2Node_VariableGet * GetVarNode = CompilerContext . SpawnIntermediateNode < UK2Node_VariableGet > ( this , SourceGraph ) ;
GetVarNode - > VariableReference . SetSelfMember ( MemberVariableToCallOn . GetMemberName ( ) ) ;
GetVarNode - > AllocateDefaultPins ( ) ;
2014-09-19 17:50:45 -04:00
2014-10-17 06:37:11 -04:00
if ( UEdGraphPin * ValuePin = GetVarNode - > GetValuePin ( ) )
{
ValuePin - > MakeLinkTo ( CallFuncSelfPin ) ;
2014-09-19 17:50:45 -04:00
}
2014-10-17 06:37:11 -04:00
}
else
{
for ( int32 TargetIdx = 0 ; TargetIdx < SelfPin - > LinkedTo . Num ( ) ; TargetIdx + + )
2014-09-19 17:50:45 -04:00
{
2014-10-17 06:37:11 -04:00
UEdGraphPin * SourcePin = SelfPin - > LinkedTo [ TargetIdx ] ;
if ( SourcePin ! = NULL )
2014-03-14 14:13:41 -04:00
{
2014-10-17 06:37:11 -04:00
// Create 'get var' node to get the member
UK2Node_VariableGet * GetVarNode = CompilerContext . SpawnIntermediateNode < UK2Node_VariableGet > ( this , SourceGraph ) ;
GetVarNode - > VariableReference = MemberVariableToCallOn ;
GetVarNode - > AllocateDefaultPins ( ) ;
UEdGraphPin * VarNodeSelfPin = Schema - > FindSelfPin ( * GetVarNode , EGPD_Input ) ;
if ( VarNodeSelfPin ! = NULL )
2014-03-14 14:13:41 -04:00
{
2014-10-17 06:37:11 -04:00
VarNodeSelfPin - > MakeLinkTo ( SourcePin ) ;
2014-03-14 14:13:41 -04:00
2014-10-17 06:37:11 -04:00
UEdGraphPin * ValuePin = GetVarNode - > GetValuePin ( ) ;
ValuePin - > MakeLinkTo ( CallFuncSelfPin ) ;
}
else
{
// Failed to find the member to call on for this expansion, so warn about it
CompilerContext . MessageLog . Warning ( * LOCTEXT ( " CallFunctionOnInvalidMember_Warning " , " Function node @@ called on invalid target member. " ) . ToString ( ) , this ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-10-17 06:37:11 -04:00
}
}
}
2014-03-14 14:13:41 -04:00
2014-10-17 06:37:11 -04:00
// Now move the rest of the connections (including exec connections...)
for ( int32 SrcPinIdx = 0 ; SrcPinIdx < Pins . Num ( ) ; SrcPinIdx + + )
{
UEdGraphPin * SrcPin = Pins [ SrcPinIdx ] ;
if ( SrcPin ! = NULL & & SrcPin ! = SelfPin ) // check its not the self pin
2014-03-14 14:13:41 -04:00
{
2014-10-17 06:37:11 -04:00
UEdGraphPin * DestPin = CallFuncNode - > FindPin ( SrcPin - > PinName ) ;
if ( DestPin ! = NULL )
2014-03-14 14:13:41 -04:00
{
2014-10-17 06:37:11 -04:00
CompilerContext . MovePinLinksToIntermediate ( * SrcPin , * DestPin ) ; // Source node is assumed to be owner...
2014-03-14 14:13:41 -04:00
}
}
}
2014-10-17 06:37:11 -04:00
// Finally, break any remaining links on the 'call func on member' node
BreakAllNodeLinks ( ) ;
2014-03-14 14:13:41 -04:00
}
2015-04-25 17:47:39 -04:00
bool UK2Node_CallFunctionOnMember : : HasExternalDependencies ( TArray < class UStruct * > * OptionalOutput ) const
2014-07-01 12:03:49 -04:00
{
const UBlueprint * SourceBlueprint = GetBlueprint ( ) ;
2015-04-25 17:47:39 -04:00
auto VarProperty = MemberVariableToCallOn . ResolveMember < UProperty > ( GetBlueprintClassFromNode ( ) ) ;
UClass * SourceClass = VarProperty ? VarProperty - > GetOwnerClass ( ) : nullptr ;
const bool bResult = ( SourceClass ! = NULL ) & & ( SourceClass - > ClassGeneratedBy ! = SourceBlueprint ) ;
2014-07-01 12:03:49 -04:00
if ( bResult & & OptionalOutput )
{
2015-04-25 17:47:39 -04:00
OptionalOutput - > AddUnique ( SourceClass ) ;
2014-07-01 12:03:49 -04:00
}
2015-04-25 17:47:39 -04:00
const bool bSuperResult = Super : : HasExternalDependencies ( OptionalOutput ) ;
return bSuperResult | | bResult ;
2014-07-01 12:03:49 -04:00
}
2014-03-14 14:13:41 -04:00
# undef LOCTEXT_NAMESPACE