Files
UnrealEngineUWP/Engine/Source/Editor/BlueprintGraph/Private/K2Node_StructOperation.cpp
jack cai 94ab4283b8 Control Rig: Added BlueprintInternalUseOnlyHierarchical tag that can be inherited by derived structs. Addded this tag to base rig unit to hide all raw rig unit structs from BP
previous change at CL 18866227 was backed out because it broke the bot1 cooks: https://horde.devtools.epicgames.com/log/61ffcf94676584e71ea0ab7e?lineindex=104697

Basically GetBoolMetaDataHierarchical returns the wrong thing and the return pin can no longer be broken up and so the blueprint won't compile.

#jira UE-141083
#rb helge.mathee sara.schvartzman ben.hoffman
#preflight https://horde.devtools.epicgames.com/job/62018bbd62420bfd0493e404

#ROBOMERGE-AUTHOR: jack.cai
#ROBOMERGE-SOURCE: CL 18907822 via CL 18907834 via CL 18907851 via CL 18918946 via CL 18919865
#ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v916-18915374)

[CL 18919918 by jack cai in ue5-main branch]
2022-02-09 12:15:30 -05:00

177 lines
6.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "K2Node_StructOperation.h"
#include "Engine/UserDefinedStruct.h"
#include "EdGraphSchema_K2.h"
#include "UserDefinedStructure/UserDefinedStructEditorData.h"
#include "Kismet2/StructureEditorUtils.h"
#include "BlueprintActionFilter.h"
#include "BlueprintFieldNodeSpawner.h"
#include "EditorCategoryUtils.h"
#include "BlueprintActionDatabaseRegistrar.h"
//////////////////////////////////////////////////////////////////////////
// UK2Node_StructOperation
UK2Node_StructOperation::UK2Node_StructOperation(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void UK2Node_StructOperation::ValidateNodeDuringCompilation(class FCompilerResultsLog& MessageLog) const
{
// Skip UK2Node_Variable's validation because it doesn't need a property (see CL# 1756451)
UK2Node::ValidateNodeDuringCompilation(MessageLog);
}
bool UK2Node_StructOperation::HasExternalDependencies(TArray<class UStruct*>* OptionalOutput) const
{
const bool bResult = nullptr != StructType;
if (bResult && OptionalOutput)
{
OptionalOutput->AddUnique(StructType);
}
const bool bSuperResult = Super::HasExternalDependencies(OptionalOutput);
return bSuperResult || bResult;
}
void UK2Node_StructOperation::FStructOperationOptionalPinManager::CustomizePinData(UEdGraphPin* Pin, FName SourcePropertyName, int32 ArrayIndex, FProperty* Property) const
{
FOptionalPinManager::CustomizePinData(Pin, SourcePropertyName, ArrayIndex, Property);
if (Pin && Property)
{
const UUserDefinedStruct* UDStructure = Cast<const UUserDefinedStruct>(Property->GetOwnerStruct());
if (UDStructure && UDStructure->EditorData)
{
const FStructVariableDescription* VarDesc = FStructureEditorUtils::GetVarDesc(UDStructure).FindByPredicate(
FStructureEditorUtils::FFindByNameHelper<FStructVariableDescription>(Property->GetFName()));
if (VarDesc)
{
Pin->PersistentGuid = VarDesc->VarGuid;
}
}
}
}
bool UK2Node_StructOperation::DoRenamedPinsMatch(const UEdGraphPin* NewPin, const UEdGraphPin* OldPin, bool bStructInVariablesOut) const
{
if (NewPin && OldPin && (OldPin->Direction == NewPin->Direction))
{
const EEdGraphPinDirection StructDirection = bStructInVariablesOut ? EGPD_Input : EGPD_Output;
const EEdGraphPinDirection VariablesDirection = bStructInVariablesOut ? EGPD_Output : EGPD_Input;
const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
const bool bCompatible = K2Schema && K2Schema->ArePinTypesCompatible(NewPin->PinType, OldPin->PinType);
if (bCompatible && (StructDirection == OldPin->Direction))
{
// Struct name was changed, which is fine
return true;
}
else if (bCompatible && (VariablesDirection == OldPin->Direction))
{
// Name of a member variable was changed, check guids and redirects
if ((NewPin->PersistentGuid == OldPin->PersistentGuid) && OldPin->PersistentGuid.IsValid())
{
return true;
}
if (DoesRenamedVariableMatch(OldPin->PinName, NewPin->PinName, StructType))
{
return true;
}
}
}
return false;
}
void UK2Node_StructOperation::SetupMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar, const FMakeStructSpawnerAllowedDelegate& AllowedDelegate, EEdGraphPinDirection PinDirectionToPromote) const
{
struct GetMenuActions_Utils
{
static void SetNodeStruct(UEdGraphNode* NewNode, FFieldVariant /*StructField*/, TWeakObjectPtr<UScriptStruct> NonConstStructPtr)
{
UK2Node_StructOperation* StructNode = CastChecked<UK2Node_StructOperation>(NewNode);
StructNode->StructType = NonConstStructPtr.Get();
}
static void OverrideCategory(FBlueprintActionContext const& Context, IBlueprintNodeBinder::FBindingSet const& /*Bindings*/, FBlueprintActionUiSpec* UiSpecOut, TWeakObjectPtr<UScriptStruct> StructPtr, EEdGraphPinDirection PinDirectionToPromote)
{
for (UEdGraphPin* Pin : Context.Pins)
{
UScriptStruct* PinStruct = Cast<UScriptStruct>(Pin->PinType.PinSubCategoryObject.Get());
if ((PinStruct != nullptr) && (StructPtr.Get() == PinStruct) && (Pin->Direction == PinDirectionToPromote))
{
UiSpecOut->Category = NSLOCTEXT("BlueprintFunctionNodeSpawner", "EmptyFunctionCategory", "|");
break;
}
}
}
};
UClass* NodeClass = GetClass();
ActionRegistrar.RegisterStructActions(FBlueprintActionDatabaseRegistrar::FMakeStructSpawnerDelegate::CreateLambda([NodeClass, AllowedDelegate, PinDirectionToPromote](const UScriptStruct* Struct)->UBlueprintNodeSpawner*
{
UBlueprintFieldNodeSpawner* NodeSpawner = nullptr;
if (AllowedDelegate.Execute(Struct, false))
{
NodeSpawner = UBlueprintFieldNodeSpawner::Create(NodeClass, const_cast<UScriptStruct*>(Struct));
check(NodeSpawner != nullptr);
TWeakObjectPtr<UScriptStruct> NonConstStructPtr = MakeWeakObjectPtr(const_cast<UScriptStruct*>(Struct));
NodeSpawner->SetNodeFieldDelegate = UBlueprintFieldNodeSpawner::FSetNodeFieldDelegate::CreateStatic(GetMenuActions_Utils::SetNodeStruct, NonConstStructPtr);
NodeSpawner->DynamicUiSignatureGetter = UBlueprintFieldNodeSpawner::FUiSpecOverrideDelegate::CreateStatic(GetMenuActions_Utils::OverrideCategory, NonConstStructPtr, PinDirectionToPromote);
}
return NodeSpawner;
}));
}
FString UK2Node_StructOperation::GetPinMetaData(FName InPinName, FName InKey)
{
for (TFieldIterator<FProperty> It(StructType); It; ++It)
{
const FProperty* Property = *It;
if(Property && Property->GetFName() == InPinName)
{
return Property->GetMetaData(InKey);
}
}
return Super::GetPinMetaData(InPinName, InKey);
}
FString UK2Node_StructOperation::GetFindReferenceSearchString() const
{
return UEdGraphNode::GetFindReferenceSearchString();
}
bool UK2Node_StructOperation::IsActionFilteredOut(const FBlueprintActionFilter& Filter)
{
bool bIsFiltered = false;
if (StructType)
{
if (StructType->GetBoolMetaData(FBlueprintMetadata::MD_BlueprintInternalUseOnly))
{
bIsFiltered = true;
}
else if (StructType->GetBoolMetaDataHierarchical(FBlueprintMetadata::MD_BlueprintInternalUseOnlyHierarchical))
{
bIsFiltered = true;
}
else if (!StructType->GetBoolMetaData(FBlueprintMetadata::MD_AllowableBlueprintVariableType))
{
bIsFiltered = true;
for (UEdGraphPin* ContextPin : Filter.Context.Pins)
{
if (ContextPin->PinType.PinCategory == UEdGraphSchema_K2::PC_Struct && ContextPin->PinType.PinSubCategoryObject == StructType)
{
bIsFiltered = false;
break;
}
}
}
}
return bIsFiltered;
}