You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
However: function searches will do a quoted search by native function name. The previous behavior was unquoted search by node title (usually function display name). As a result, the previous behavior for Find References would fail in functions with special characters in their name. Now that the name is surrounded in quotes, all function names are supported. The new Find References behavior now searches for correct function name for parent call nodes, interface implementations, event overrides, where the previous behavior failed due to searching for node title. #rb Phillip.Kavan [CL 30854644 by zhikang shao in ue5-main branch]
227 lines
7.0 KiB
C++
227 lines
7.0 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
#include "K2Node_FunctionTerminator.h"
|
|
|
|
#include "Containers/EnumAsByte.h"
|
|
#include "Containers/UnrealString.h"
|
|
#include "EdGraph/EdGraph.h"
|
|
#include "EdGraph/EdGraphPin.h"
|
|
#include "EdGraphSchema_K2.h"
|
|
#include "Engine/Blueprint.h"
|
|
#include "FindInBlueprints.h"
|
|
#include "GraphEditorSettings.h"
|
|
#include "HAL/Platform.h"
|
|
#include "HAL/PlatformCrt.h"
|
|
#include "Internationalization/Internationalization.h"
|
|
#include "Internationalization/Text.h"
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
|
#include "Kismet2/CompilerResultsLog.h"
|
|
#include "Misc/AssertionMacros.h"
|
|
#include "Serialization/Archive.h"
|
|
#include "Templates/Casts.h"
|
|
#include "Templates/SharedPointer.h"
|
|
#include "UObject/Class.h"
|
|
#include "UObject/FrameworkObjectVersion.h"
|
|
#include "UObject/Object.h"
|
|
#include "UObject/UnrealType.h"
|
|
#include "UObject/WeakObjectPtrTemplates.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "K2Node"
|
|
|
|
UK2Node_FunctionTerminator::UK2Node_FunctionTerminator(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
}
|
|
|
|
void UK2Node_FunctionTerminator::Serialize(FArchive& Ar)
|
|
{
|
|
Super::Serialize(Ar);
|
|
|
|
Ar.UsingCustomVersion(FFrameworkObjectVersion::GUID);
|
|
|
|
if (Ar.IsLoading())
|
|
{
|
|
if (Ar.CustomVer(FFrameworkObjectVersion::GUID) < FFrameworkObjectVersion::FunctionTerminatorNodesUseMemberReference)
|
|
{
|
|
FunctionReference.SetExternalMember(SignatureName_DEPRECATED, SignatureClass_DEPRECATED);
|
|
}
|
|
}
|
|
}
|
|
|
|
FLinearColor UK2Node_FunctionTerminator::GetNodeTitleColor() const
|
|
{
|
|
return GetDefault<UGraphEditorSettings>()->FunctionTerminatorNodeTitleColor;
|
|
}
|
|
|
|
FString UK2Node_FunctionTerminator::GetFindReferenceSearchString_Impl(EGetFindReferenceSearchStringFlags InFlags) const
|
|
{
|
|
if (EnumHasAnyFlags(InFlags, EGetFindReferenceSearchStringFlags::UseSearchSyntax))
|
|
{
|
|
// Resolve the function
|
|
if (const UFunction* Function = FFunctionFromNodeHelper::FunctionFromNode(this))
|
|
{
|
|
// Attempt to construct an advanced search syntax query from the function
|
|
FString SearchTerm;
|
|
if (FindInBlueprintsHelpers::ConstructSearchTermFromFunction(Function, SearchTerm))
|
|
{
|
|
return SearchTerm;
|
|
}
|
|
else
|
|
{
|
|
// Fallback behavior: function was found but failed to construct a search term from it
|
|
// Just search for the function's friendly name
|
|
return UEdGraphSchema_K2::GetFriendlySignatureName(Function).ToString();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// When searching by name, return function native name in quotes.
|
|
// The quotes guarantee that the whole function name is used as single search term.
|
|
// This avoids function names with special characters being interpreted as operators.
|
|
if (const UFunction* Function = FFunctionFromNodeHelper::FunctionFromNode(this))
|
|
{
|
|
const FString NativeName = Function->GetName();
|
|
return FString::Printf(TEXT("\"%s\""), *NativeName);
|
|
}
|
|
}
|
|
|
|
// Fallback behavior: function was not resolved
|
|
return Super::GetFindReferenceSearchString_Impl(InFlags);
|
|
}
|
|
|
|
FName UK2Node_FunctionTerminator::CreateUniquePinName(FName InSourcePinName) const
|
|
{
|
|
const UFunction* FoundFunction = FFunctionFromNodeHelper::FunctionFromNode(this);
|
|
|
|
FName ResultName = InSourcePinName;
|
|
int UniqueNum = 0;
|
|
// Prevent the unique name from being the same as another of the UFunction's properties
|
|
while(FindPin(ResultName) || FindFProperty<const FProperty>(FoundFunction, ResultName) != nullptr)
|
|
{
|
|
ResultName = *FString::Printf(TEXT("%s%d"), *InSourcePinName.ToString(), ++UniqueNum);
|
|
}
|
|
return ResultName;
|
|
}
|
|
|
|
bool UK2Node_FunctionTerminator::CanCreateUserDefinedPin(const FEdGraphPinType& InPinType, EEdGraphPinDirection InDesiredDirection, FText& OutErrorMessage)
|
|
{
|
|
const bool bIsNodeEditable = IsEditable();
|
|
|
|
// Make sure that if this is an exec node we are allowed one.
|
|
if (bIsNodeEditable && InPinType.PinCategory == UEdGraphSchema_K2::PC_Exec && !CanModifyExecutionWires())
|
|
{
|
|
OutErrorMessage = LOCTEXT("MultipleExecPinError", "Cannot support more exec pins!");
|
|
return false;
|
|
}
|
|
else if (!bIsNodeEditable)
|
|
{
|
|
OutErrorMessage = LOCTEXT("NotEditableError", "Cannot edit this node!");
|
|
}
|
|
|
|
return bIsNodeEditable;
|
|
}
|
|
|
|
bool UK2Node_FunctionTerminator::HasExternalDependencies(TArray<class UStruct*>* OptionalOutput) const
|
|
{
|
|
const UBlueprint* SourceBlueprint = GetBlueprint();
|
|
|
|
UClass* SourceClass = FunctionReference.GetMemberParentClass(GetBlueprintClassFromNode());
|
|
bool bResult = (SourceClass != nullptr) && (SourceClass->ClassGeneratedBy.Get() != SourceBlueprint);
|
|
if (bResult && OptionalOutput)
|
|
{
|
|
OptionalOutput->AddUnique(SourceClass);
|
|
}
|
|
|
|
// All structures, that are required for the BP compilation, should be gathered
|
|
for (auto Pin : Pins)
|
|
{
|
|
UStruct* DepStruct = Pin ? Cast<UStruct>(Pin->PinType.PinSubCategoryObject.Get()) : nullptr;
|
|
|
|
UClass* DepClass = Cast<UClass>(DepStruct);
|
|
if (DepClass && (DepClass->ClassGeneratedBy.Get() == SourceBlueprint))
|
|
{
|
|
//Don't include self
|
|
continue;
|
|
}
|
|
|
|
if (DepStruct && !DepStruct->IsNative())
|
|
{
|
|
if (OptionalOutput)
|
|
{
|
|
OptionalOutput->AddUnique(DepStruct);
|
|
}
|
|
bResult = true;
|
|
}
|
|
}
|
|
|
|
const bool bSuperResult = Super::HasExternalDependencies(OptionalOutput);
|
|
return bSuperResult || bResult;
|
|
}
|
|
|
|
void UK2Node_FunctionTerminator::PostPasteNode()
|
|
{
|
|
Super::PostPasteNode();
|
|
|
|
UEdGraph* Graph = GetGraph();
|
|
if (ensure(Graph))
|
|
{
|
|
FunctionReference.SetExternalMember(Graph->GetFName(), nullptr);
|
|
}
|
|
}
|
|
|
|
void UK2Node_FunctionTerminator::PromoteFromInterfaceOverride(bool bIsPrimaryTerminator)
|
|
{
|
|
// Remove the signature class, that is not relevant.
|
|
FunctionReference.SetSelfMember(FunctionReference.GetMemberName());
|
|
|
|
// For every pin that has been defined, make it a user defined pin if we can
|
|
for (UEdGraphPin* const Pin : Pins)
|
|
{
|
|
if (Pin->PinType.PinCategory != UEdGraphSchema_K2::PC_Exec && !UserDefinedPinExists(Pin->PinName))
|
|
{
|
|
TSharedPtr<FUserPinInfo> NewPinInfo = MakeShareable(new FUserPinInfo());
|
|
NewPinInfo->PinName = Pin->PinName;
|
|
NewPinInfo->PinType = Pin->PinType;
|
|
NewPinInfo->DesiredPinDirection = Pin->Direction;
|
|
UserDefinedPins.Add(NewPinInfo);
|
|
}
|
|
}
|
|
const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>();
|
|
Schema->ReconstructNode(*this, true);
|
|
}
|
|
|
|
UFunction* UK2Node_FunctionTerminator::FindSignatureFunction() const
|
|
{
|
|
UClass* FoundClass = GetBlueprintClassFromNode();
|
|
UFunction* FoundFunction = FunctionReference.ResolveMember<UFunction>(FoundClass);
|
|
|
|
if (!FoundFunction && FoundClass && GetOuter())
|
|
{
|
|
// The resolve will fail if this is a locally-created function, so search using the event graph name
|
|
FoundFunction = FindUField<UFunction>(FoundClass, *GetOuter()->GetName());
|
|
}
|
|
|
|
return FoundFunction;
|
|
}
|
|
|
|
void UK2Node_FunctionTerminator::ValidateNodeDuringCompilation(FCompilerResultsLog& MessageLog) const
|
|
{
|
|
Super::ValidateNodeDuringCompilation(MessageLog);
|
|
|
|
for (UEdGraphPin* Pin : Pins)
|
|
{
|
|
if (Pin && Pin->PinType.bIsWeakPointer && !Pin->PinType.IsContainer())
|
|
{
|
|
const FString ErrorString = FText::Format(
|
|
LOCTEXT("WeakPtrNotSupportedErrorFmt", "Weak pointers are not supported as function parameters. Pin '{0}' @@"),
|
|
FText::FromString(Pin->GetName())
|
|
).ToString();
|
|
MessageLog.Error(*ErrorString, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|