Files
UnrealEngineUWP/Engine/Source/Editor/BlueprintGraph/Private/StructMemberNodeHandlers.cpp

121 lines
4.4 KiB
C++
Raw Normal View History

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "BlueprintGraphPrivatePCH.h"
#include "StructMemberNodeHandlers.h"
static FBPTerminal* RegisterStructVar(FCompilerResultsLog& MessageLog, FKismetFunctionContext& Context, UK2Node_StructOperation* MemberSetNode)
{
// Find the self pin
const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>();
UEdGraphPin* SelfPin = Schema->FindSelfPin(*MemberSetNode, EGPD_Input);
// Determine the search scope for the struct property (not the member)
UStruct* SearchScope = (SelfPin != NULL) ? Context.GetScopeFromPinType(SelfPin->PinType, Context.NewClass) : Context.Function;
// Now find the variable
if (UProperty* BoundProperty = FKismetCompilerUtilities::FindNamedPropertyInScope(SearchScope, MemberSetNode->GetVarName()))
{
// Create the term in the list
FBPTerminal* Term = new (Context.VariableReferences) FBPTerminal();
Schema->ConvertPropertyToPinType(BoundProperty, /*out*/ Term->Type);
Term->Source = MemberSetNode;
Term->Name = MemberSetNode->GetVarNameString();
Term->bIsStructContext = true;
Term->AssociatedVarProperty = BoundProperty;
//@TODO: Needed? Context.NetMap.Add(Net, Term);
// Read-only variables and variables in const classes are both const
[UE-2345] BP - enforce const-correctness in native const class method overrides this change introduces enforcement of 'const-correctness' into implemented function graphs. summary: if you have a function declared in C++ like this: UFUNCTION(BlueprintImplementableEvent) int32 MyFunctionThatReturnsSomeValue() const; if you implement that (BPIE) function in a Blueprint that's parented to that native class, it will now be flagged as 'const'. this makes any properties of 'self' read-only within the context of that graph, which means the compiler will emit an error if you try to set a property or otherwise call a non-const, non-static function with 'self' as the target. if there happens to already be an implemented const function in a Blueprint that was in place prior to this change, the compiler will emit a warning instead of an error, in order to allow existing Blueprints that may currently be "violating" const within the context of a const BPIE function to still compile, while still alerting to issues that should probably be addressed. notes: 1) this also applies to BlueprintNativeEvent (BPNE) implementations, and also when implementing BPIE/BPNE interface methods that are also declared as const 2) a const BPIE/BPNE function with no return value and no output parameters will be implemented as a "normal" impure function, and not as an event as in the non-const case 3) a const BPIE/BPNE function with a return value and/or output parameters will currently be implemented as a pure function, regardless of whether or not BlueprintCallable is specified 4) this CL also retains some consolidation of static function validation code that i had previously done, mostly to allow static functions to more easily be whitelisted for const function graphs #codereview Nick.Whiting, Michael.Noland [CL 2368059 by Phillip Kavan in Main branch]
2014-11-21 17:47:17 -05:00
if (BoundProperty->HasAnyPropertyFlags(CPF_BlueprintReadOnly) || (Context.IsConstFunction() && Context.NewClass->IsChildOf(SearchScope)))
{
Term->bIsConst = true;
}
// Resolve the context term
if (SelfPin != NULL)
{
FBPTerminal** pContextTerm = Context.NetMap.Find(FEdGraphUtilities::GetNetFromPin(SelfPin));
Term->Context = (pContextTerm != NULL) ? *pContextTerm : NULL;
}
return Term;
}
else
{
MessageLog.Error(TEXT("Failed to find struct variable used in @@"), MemberSetNode);
return NULL;
}
}
static void ResolveAndRegisterScopedStructTerm(FCompilerResultsLog& MessageLog, FKismetFunctionContext& Context, UScriptStruct* StructType, UEdGraphPin* Net, FBPTerminal* ContextTerm)
{
// Find the property for the struct
UProperty* BoundProperty = FindField<UProperty>(StructType, *(Net->PinName));
if (BoundProperty != NULL)
{
// Create the term in the list
FBPTerminal* Term = new (Context.VariableReferences) FBPTerminal();
Term->CopyFromPin(Net, Net->PinName);
Term->AssociatedVarProperty = BoundProperty;
Context.NetMap.Add(Net, Term);
Term->Context = ContextTerm;
// Read-only variables and variables in const classes are both const
[UE-2345] BP - enforce const-correctness in native const class method overrides this change introduces enforcement of 'const-correctness' into implemented function graphs. summary: if you have a function declared in C++ like this: UFUNCTION(BlueprintImplementableEvent) int32 MyFunctionThatReturnsSomeValue() const; if you implement that (BPIE) function in a Blueprint that's parented to that native class, it will now be flagged as 'const'. this makes any properties of 'self' read-only within the context of that graph, which means the compiler will emit an error if you try to set a property or otherwise call a non-const, non-static function with 'self' as the target. if there happens to already be an implemented const function in a Blueprint that was in place prior to this change, the compiler will emit a warning instead of an error, in order to allow existing Blueprints that may currently be "violating" const within the context of a const BPIE function to still compile, while still alerting to issues that should probably be addressed. notes: 1) this also applies to BlueprintNativeEvent (BPNE) implementations, and also when implementing BPIE/BPNE interface methods that are also declared as const 2) a const BPIE/BPNE function with no return value and no output parameters will be implemented as a "normal" impure function, and not as an event as in the non-const case 3) a const BPIE/BPNE function with a return value and/or output parameters will currently be implemented as a pure function, regardless of whether or not BlueprintCallable is specified 4) this CL also retains some consolidation of static function validation code that i had previously done, mostly to allow static functions to more easily be whitelisted for const function graphs #codereview Nick.Whiting, Michael.Noland [CL 2368059 by Phillip Kavan in Main branch]
2014-11-21 17:47:17 -05:00
if (BoundProperty->HasAnyPropertyFlags(CPF_BlueprintReadOnly) || (Context.IsConstFunction() && Context.NewClass->IsChildOf(StructType)))
{
Term->bIsConst = true;
}
}
else
{
MessageLog.Error(TEXT("Failed to find a struct member for @@"), Net);
}
}
void FKCHandler_StructMemberVariableGet::RegisterNet(FKismetFunctionContext& Context, UEdGraphPin* Net)
{
// This net is a variable read
ResolveAndRegisterScopedTerm(Context, Net, Context.VariableReferences);
}
void FKCHandler_StructMemberVariableGet::RegisterNets(FKismetFunctionContext& Context, UEdGraphNode* InNode)
{
UK2Node_StructMemberGet* MemberGetNode = CastChecked<UK2Node_StructMemberGet>(InNode);
MemberGetNode->CheckForErrors(CompilerContext.GetSchema(), Context.MessageLog);
if (FBPTerminal* ContextTerm = RegisterStructVar(CompilerContext.MessageLog, Context, MemberGetNode))
{
// Register a term for each output pin
for (int32 PinIndex = 0; PinIndex < MemberGetNode->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Net = MemberGetNode->Pins[PinIndex];
ResolveAndRegisterScopedStructTerm(CompilerContext.MessageLog, Context, MemberGetNode->StructType, Net, ContextTerm);
}
}
}
void FKCHandler_StructMemberVariableSet::RegisterNets(FKismetFunctionContext& Context, UEdGraphNode* InNode)
{
UK2Node_StructMemberSet* MemberSetNode = CastChecked<UK2Node_StructMemberSet>(InNode);
MemberSetNode->CheckForErrors(CompilerContext.GetSchema(), Context.MessageLog);
if (FBPTerminal* ContextTerm = RegisterStructVar(CompilerContext.MessageLog, Context, MemberSetNode))
{
// Register a term for each input pin
for (int32 PinIndex = 0; PinIndex < MemberSetNode->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Net = MemberSetNode->Pins[PinIndex];
if (!CompilerContext.GetSchema()->IsMetaPin(*Net) && (Net->Direction == EGPD_Input))
{
if (ValidateAndRegisterNetIfLiteral(Context, Net))
{
ResolveAndRegisterScopedStructTerm(CompilerContext.MessageLog, Context, MemberSetNode->StructType, Net, ContextTerm);
}
}
}
}
}