2014-03-14 14:13:41 -04:00
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
# include "BlueprintGraphPrivatePCH.h"
# include "KismetCompiler.h"
//////////////////////////////////////////////////////////////////////////
// FKCHandler_VariableGet
2014-04-23 18:30:37 -04:00
# define LOCTEXT_NAMESPACE "K2Node"
2014-03-14 14:13:41 -04:00
class FKCHandler_VariableGet : public FNodeHandlingFunctor
{
public :
FKCHandler_VariableGet ( FKismetCompilerContext & InCompilerContext )
: FNodeHandlingFunctor ( InCompilerContext )
{
}
2014-06-13 06:14:46 -04:00
virtual void RegisterNet ( FKismetFunctionContext & Context , UEdGraphPin * Net ) override
2014-03-14 14:13:41 -04:00
{
// This net is a variable read
ResolveAndRegisterScopedTerm ( Context , Net , Context . VariableReferences ) ;
}
2014-06-13 06:14:46 -04:00
virtual void RegisterNets ( FKismetFunctionContext & Context , UEdGraphNode * Node ) override
2014-03-14 14:13:41 -04:00
{
UK2Node_Variable * VarNode = Cast < UK2Node_Variable > ( Node ) ;
if ( VarNode )
{
VarNode - > CheckForErrors ( CompilerContext . GetSchema ( ) , Context . MessageLog ) ;
}
2014-05-09 17:43:40 -04:00
// Report an error that the local variable could not be found
if ( VarNode - > VariableReference . IsLocalScope ( ) & & VarNode - > GetPropertyForVariable ( ) = = NULL )
{
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " VariableName " ) , FText : : FromName ( VarNode - > VariableReference . GetMemberName ( ) ) ) ;
2014-05-30 10:43:00 -04:00
if ( VarNode - > VariableReference . GetMemberScopeName ( ) ! = Context . Function - > GetName ( ) )
{
Args . Add ( TEXT ( " ScopeName " ) , FText : : FromString ( VarNode - > VariableReference . GetMemberScopeName ( ) ) ) ;
CompilerContext . MessageLog . Warning ( * FText : : Format ( LOCTEXT ( " LocalVariableNotFoundInScope_Error " , " Unable to find local variable with name '{VariableName}' for @@, scope expected: @@, scope found: {ScopeName} " ) , Args ) . ToString ( ) , Node , Node - > GetGraph ( ) ) ;
}
else
{
CompilerContext . MessageLog . Warning ( * FText : : Format ( LOCTEXT ( " LocalVariableNotFound_Error " , " Unable to find local variable with name '{VariableName}' for @@ " ) , Args ) . ToString ( ) , Node ) ;
}
2014-05-09 17:43:40 -04:00
}
2014-03-14 14:13:41 -04:00
FNodeHandlingFunctor : : RegisterNets ( Context , Node ) ;
}
} ;
2014-09-12 12:56:24 -04:00
namespace K2Node_VariableGetImpl
{
/**
* Shared utility method for retrieving a UK2Node_VariableGet ' s bare tooltip .
*
* @ param VarName The name of the variable that the node represents .
* @ return A formatted text string , describing what the VariableGet node does .
*/
static FText GetBaseTooltip ( FName VarName ) ;
}
static FText K2Node_VariableGetImpl : : GetBaseTooltip ( FName VarName )
{
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " VarName " ) , FText : : FromName ( VarName ) ) ;
return FText : : Format ( LOCTEXT ( " GetVariableTooltip " , " Read the value of variable {VarName} " ) , Args ) ;
}
2014-03-14 14:13:41 -04:00
UK2Node_VariableGet : : UK2Node_VariableGet ( const class FPostConstructInitializeProperties & PCIP )
: Super ( PCIP )
{
}
void UK2Node_VariableGet : : AllocateDefaultPins ( )
{
if ( GetVarName ( ) ! = NAME_None )
{
if ( CreatePinForVariable ( EGPD_Output ) )
{
CreatePinForSelf ( ) ;
}
}
Super : : AllocateDefaultPins ( ) ;
}
void UK2Node_VariableGet : : ReallocatePinsDuringReconstruction ( TArray < UEdGraphPin * > & OldPins )
{
if ( GetVarName ( ) ! = NAME_None )
{
if ( ! CreatePinForVariable ( EGPD_Output ) )
{
if ( ! RecreatePinForVariable ( EGPD_Output , OldPins ) )
{
return ;
}
}
CreatePinForSelf ( ) ;
}
}
2014-09-17 13:01:38 -04:00
FText UK2Node_VariableGet : : GetPropertyTooltip ( UProperty const * VariableProperty )
2014-09-12 12:56:24 -04:00
{
FName VarName = NAME_None ;
if ( VariableProperty ! = nullptr )
{
VarName = VariableProperty - > GetFName ( ) ;
UClass * SourceClass = VariableProperty - > GetOwnerClass ( ) ;
// discover if the variable property is a non blueprint user variable
bool const bIsNativeVariable = ( SourceClass ! = nullptr ) & & ( SourceClass - > ClassGeneratedBy = = nullptr ) ;
FName const TooltipMetaKey ( TEXT ( " tooltip " ) ) ;
FText SubTooltip ;
if ( bIsNativeVariable )
{
FText const PropertyTooltip = VariableProperty - > GetToolTipText ( ) ;
if ( ! PropertyTooltip . IsEmpty ( ) )
{
// See if the native property has a tooltip
SubTooltip = PropertyTooltip ;
FString TooltipName = FString : : Printf ( TEXT ( " %s.%s " ) , * VarName . ToString ( ) , * TooltipMetaKey . ToString ( ) ) ;
FText : : FindText ( * VariableProperty - > GetFullGroupName ( true ) , * TooltipName , SubTooltip ) ;
}
}
else if ( UBlueprint * VarBlueprint = Cast < UBlueprint > ( SourceClass - > ClassGeneratedBy ) )
{
FString UserTooltipData ;
if ( FBlueprintEditorUtils : : GetBlueprintVariableMetaData ( VarBlueprint , VarName , /*InLocalVarScope =*/ nullptr , TooltipMetaKey , UserTooltipData ) )
{
SubTooltip = FText : : FromString ( UserTooltipData ) ;
}
}
if ( ! SubTooltip . IsEmpty ( ) )
{
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " VarName " ) , FText : : FromName ( VarName ) ) ;
Args . Add ( TEXT ( " PropertyTooltip " ) , SubTooltip ) ;
return FText : : Format ( LOCTEXT ( " GetVariableProperty_Tooltip " , " Read the value of variable {VarName} \n {PropertyTooltip} " ) , Args ) ;
}
}
return K2Node_VariableGetImpl : : GetBaseTooltip ( VarName ) ;
}
FText UK2Node_VariableGet : : GetBlueprintVarTooltip ( FBPVariableDescription const & VarDesc )
{
FName const TooltipMetaKey ( TEXT ( " tooltip " ) ) ;
int32 const MetaIndex = VarDesc . FindMetaDataEntryIndexForKey ( TooltipMetaKey ) ;
bool const bHasTooltipData = ( MetaIndex ! = INDEX_NONE ) ;
if ( bHasTooltipData )
{
FString UserTooltipData = VarDesc . GetMetaData ( TooltipMetaKey ) ;
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " VarName " ) , FText : : FromName ( VarDesc . VarName ) ) ;
Args . Add ( TEXT ( " UserTooltip " ) , FText : : FromString ( UserTooltipData ) ) ;
return FText : : Format ( LOCTEXT ( " GetVariableProperty_Tooltip " , " Read the value of variable {VarName} \n {UserTooltip} " ) , Args ) ;
}
return K2Node_VariableGetImpl : : GetBaseTooltip ( VarDesc . VarName ) ;
}
2014-09-03 18:14:09 -04:00
FText UK2Node_VariableGet : : GetTooltipText ( ) const
2014-03-14 14:13:41 -04:00
{
2014-09-24 14:15:13 -04:00
// @TODO: The variable name mutates as the user makes changes to the
// underlying property, so until we can catch all those cases, we're
// going to leave this optimization off
//if (CachedTooltip.IsOutOfDate())
2014-09-03 18:17:44 -04:00
{
2014-09-12 12:56:24 -04:00
if ( UProperty * Property = GetPropertyForVariable ( ) )
2014-03-14 14:13:41 -04:00
{
2014-09-12 12:56:24 -04:00
CachedTooltip = GetPropertyTooltip ( Property ) ;
}
else if ( FBPVariableDescription const * VarDesc = GetBlueprintVarDescription ( ) )
{
CachedTooltip = GetBlueprintVarTooltip ( * VarDesc ) ;
}
else
{
CachedTooltip = K2Node_VariableGetImpl : : GetBaseTooltip ( GetVarName ( ) ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-09-03 18:17:44 -04:00
return CachedTooltip ;
2014-03-14 14:13:41 -04:00
}
2014-04-23 18:30:37 -04:00
FText UK2Node_VariableGet : : GetNodeTitle ( ENodeTitleType : : Type TitleType ) const
2014-03-14 14:13:41 -04:00
{
2014-04-23 18:30:37 -04:00
// If there is only one variable being read, the title can be made the variable name
FString OutputPinName ;
int32 NumOutputsFound = 0 ;
for ( int32 PinIndex = 0 ; PinIndex < Pins . Num ( ) ; + + PinIndex )
{
UEdGraphPin * Pin = Pins [ PinIndex ] ;
if ( Pin - > Direction = = EGPD_Output )
{
+ + NumOutputsFound ;
OutputPinName = Pin - > PinName ;
}
}
2014-09-02 19:08:09 -04:00
if ( NumOutputsFound ! = 1 )
{
return LOCTEXT ( " Get " , " Get " ) ;
}
2014-09-24 14:15:13 -04:00
// @TODO: The variable name mutates as the user makes changes to the
// underlying property, so until we can catch all those cases, we're
// going to leave this optimization off
else //if (CachedNodeTitle.IsOutOfDate())
2014-04-23 18:30:37 -04:00
{
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " PinName " ) , FText : : FromString ( OutputPinName ) ) ;
2014-09-02 19:08:09 -04:00
// FText::Format() is slow, so we cache this to save on performance
CachedNodeTitle = FText : : Format ( LOCTEXT ( " GetPinName " , " Get {PinName} " ) , Args ) ;
2014-04-23 18:30:37 -04:00
}
2014-09-02 19:08:09 -04:00
return CachedNodeTitle ;
2014-04-23 18:30:37 -04:00
}
2014-03-14 14:13:41 -04:00
FNodeHandlingFunctor * UK2Node_VariableGet : : CreateNodeHandler ( FKismetCompilerContext & CompilerContext ) const
{
return new FKCHandler_VariableGet ( CompilerContext ) ;
}
2014-04-23 18:30:37 -04:00
# undef LOCTEXT_NAMESPACE