Files
UnrealEngineUWP/Engine/Source/Editor/BlueprintGraph/Private/K2Node_MakeStruct.cpp
Robert Manuszewski aa11e3bbbf Merging UE4-Pretest @ 2042161 to UE4
Change 1996384 by Andrew Brown:
	322252 - EDITOR: Asset picker displays incorrect text when there are no filter results.
Change 1996385 by Andrew Brown:
	321858 - CRASH: Assertion failed: (Index >= 0) Function: STransformViewportToolBar::GetLocationGridLabel() STextBlock::CacheDesiredSize()
Change 1996977 by Andrew Brown:
	309685 - UE4: Adding an event/renaming an event on an event track in Matinee does not update the MatineeActor node in blueprint
Change 2034873 by Jaroslaw Palczynski:
	More robust VS installation detection.
Change 2039693 by Jaroslaw Palczynski:
	327268 - RocketGDC: POSTLAUNCH: DEV: Make engine more robust against bad Visual Studio environment variables
Change 1978978 by Jaroslaw Surowiec:
	- Removed obsolete AllowEliminatingReferences from the FArchive
Change 2020326 by Maciej Mroz:
	pretest BP K2Node: RemovePinsFromOldPins function moved from K2Node to RemovePinsFromOldPins
Change 2017608 by Maciej Mroz:
	pretest Some changes in SFortMissionEventSelector caused by FPinTypeTreeInfo
Change 2017463 by Maciej Mroz:
	PinTypeSelector can lins unloaded UDStructs
Change 2019979 by Maciej Mroz:
	pretest BP: Crash when performing Diff against Depot with blueprints containing Format Text nodes
Change 2024469 by Maciej Mroz:
	MemberReference variable added to PinType. It's necessary for delegate's signature.
Change 2024049 by Maciej Mroz:
	HasExternalBlueprintDependencies added to UK2Node_DynamicCast
Change 2024586 by Maciej Mroz:
	FillSimpleMemberReference fix
Change 2024472 by Maciej Mroz:
	workaround for delegates signature in pintype removed.
Change 2023997 by Maciej Mroz:
	BP, UDStruc: Class UserDefinedStructEditorData added. It fixes many problems with undo/redo.
Change 2021934 by Maciej Mroz:
	typo in a comment
Change 2020355 by Maciej Mroz:
	Back out changelist 2020342
Change 2022178 by Maciej Mroz:
	CRASH: PRETEST: EDITOR: UDS: Crash when undo then redo new variable in struct that is used by blueprint
Change 2021958 by Maciej Mroz:
	CRASH: PRETEST: EDITOR: UDS: Crash using variable of a type of copied struct in blueprint
Change 1986247 by Maciej Mroz:
	User Defined Structures: circle dependency fixed. Early version.
Change 1985107 by Maciej Mroz:
	UserDefinedStruct cannot have a field of a non-native type
Change 1986278 by Maciej Mroz:
	pretest ensureMsgf in Struct::link
Change 1986250 by Maciej Mroz:
	User Defined Struct: Non native classes are accepted types od values in structures.
Change 1980955 by Maciej Mroz:
	Using AssetPtr and LazyPtr as UFunction parameter (intput or return) is explicitly disallowed.
Change 2041215 by Maciej Mroz:
	ttp331249 BLOCKER: PRETEST: UI: Survive the Storm is missing the Mission HUD.
Change 1984316 by Maciej Mroz:
	New User Defined Structure. WIP - there are still problems with circular dependencies.
Change 2011616 by Maciej Mroz:
	UserDefinedStructures - various problems fixed.
Change 2011609 by Maciej Mroz:
	more robust HasExternalBlueprintDependencies implementation
Change 2016697 by Maciej Mroz:
	pretest BP: UDStruct - default value propagation in cooked build
Change 2016288 by Maciej Mroz:
	pretest BP: UDStruct: Renaming variables wont break links from make/break nodes
Change 1987637 by Maciej Mroz:
	CustomStruct icons placeholders
Change 1987422 by Maciej Mroz:
	Better tooltips for variables in MyBlueprint
Change 1991387 by Maciej Mroz:
	UDStructures fixes:
Change 2029165 by Maciej Mroz:
	BP: better comment for incomatible pins
Change 2030016 by Maciej Mroz:
	8PRETEST: EDITOR: UDS: Defaults values aren't updated in struct type variables in blueprints
Change 2030017 by Maciej Mroz:
	Unused UDStructure code removed (PPF_UseDefaultsForUDStructures)
Change 2028856 by Maciej Mroz:
	BP: Pins with PC_Struct type are compatible only with exactly the same structure. (No derived structures are not handled as compatible).
Change 2026701 by Maciej Mroz:
	k2: odd error on an add item node within a function (see attached image in details)
Change 2028160 by Maciej Mroz:
	PRETEST: EDITOR: UDS: When deleting structures just after creating there is always some references in the memory
Change 2028165 by Maciej Mroz:
	BP: BreakHitResult function has proper icon.
Change 2033340 by Maciej Mroz:
	ttp330786 PRETEST: EDITOR: UDS: Changes of default values aren't apllied to breeak nodes for text type of variables
Change 2034255 by Maciej Mroz:
	EDITOR: UDS: Changes of default values aren't apllied to make nodes for text type of variables ttp#330620
Change 2037682 by Maciej Mroz:
	ttp331309 BLOCKER: PRETEST: CRASH: EDITOR: Crash occurs when performing Diff Against Depot on any Blueprint
Change 2033142 by Maciej Mroz:
	CreateDelegate Node uses internally FMemberReference. Refactor.
Change 2032329 by Maciej Mroz:
	ttp330608 CRASH: PRETEST: EDITOR: UDS: Crash when trying to use struct named 'Color' in blueprint
Change 2032420 by Maciej Mroz:
	ttp330620 PRETEST: EDITOR: UDS: Changes of default values aren't apllied to make nodes for text type of variables
Change 2033139 by Maciej Mroz:
	Functions generated from CustomEvents can be also identified by GUID
Change 2026631 by Maciej Mroz:
	BP. UDStruct: Invalid structs are handled better.
Change 2025344 by Maciej Mroz:
	UDStruct enabled by default
Change 2026672 by Maciej Mroz:
	EDITOR: BP: Can't easily remove 'pass-by-reference' pins on ReturnNodes
Change 2026411 by Maciej Mroz:
	ExposeOnSpawn updated, it supports UDStructs, custom native Structs, and it throws compiler error.
Change 2025342 by Maciej Mroz:
	GenerateBlueprintSkeleton moved from BLueprint::Serialize to RegenerateBlueprintClass, because SkeletonClass compilation requires all external dependencies to be loaded and linked.
Change 2025570 by Steve Robb:
	Moved dependency processing to its own function.
Change 2033235 by Steve Robb:
	String improvements
Change 2035830 by Steve Robb:
	Workaround for FriendsAndChat crash in Fortnite.
Change 2035115 by Steve Robb:
	UBT build time regression fixes.
Change 2034162 by Steve Robb:
	312775: UObject improvement: Ensure that *.generated.inl is included somewhere
Change 2034181 by Steve Robb:
	Removal of any references to .generated.inl
Change 2020165 by Steve Robb:
	BuildPublicAndPrivateUObjectHeaders factored out into its own function.
Change 2020187 by Steve Robb:
	CreateModuleCompileEnvironment function factored out.
Change 2020055 by Steve Robb:
	Refactoring of Unity.cs to remove complex and duplicate iteration.
Change 2020083 by Steve Robb:
	Another use of dictionary utilities.
Change 2031049 by Steve Robb:
	312775: UObject improvement: Ensure that *.generated.inl is included somewhere
Change 2025728 by Steve Robb:
	Refactored the application of a shared PCH file to multiple file into a single ApplySharedPCH function.
Change 2020068 by Steve Robb:
	A couple of helpful utility functions for populating dictionaries.
Change 2032307 by Steve Robb:
	312775: UObject improvement: Ensure that *.generated.inl is included somewhere

[CL 2054495 by Robert Manuszewski in Main branch]
2014-04-23 20:18:55 -04:00

313 lines
9.8 KiB
C++

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
#include "BlueprintGraphPrivatePCH.h"
#include "KismetCompiler.h"
#include "Editor/UnrealEd/Public/Kismet2/StructureEditorUtils.h"
#define LOCTEXT_NAMESPACE "K2Node_MakeStruct"
//////////////////////////////////////////////////////////////////////////
// FKCHandler_MakeStruct
class FKCHandler_MakeStruct : public FNodeHandlingFunctor
{
public:
UEdGraphPin* FindOutputStructPinChecked(UEdGraphNode* Node)
{
check(NULL != Node);
UEdGraphPin* OutputPin = NULL;
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (Pin && (EGPD_Output == Pin->Direction) && !CompilerContext.GetSchema()->IsMetaPin(*Pin))
{
OutputPin = Pin;
break;
}
}
check(NULL != OutputPin);
return OutputPin;
}
FKCHandler_MakeStruct(FKismetCompilerContext& InCompilerContext)
: FNodeHandlingFunctor(InCompilerContext)
{
}
virtual void RegisterNets(FKismetFunctionContext& Context, UEdGraphNode* InNode) OVERRIDE
{
UK2Node_MakeStruct* Node = CastChecked<UK2Node_MakeStruct>(InNode);
if (NULL == Node->StructType)
{
CompilerContext.MessageLog.Error(*LOCTEXT("MakeStruct_UnknownStructure_Error", "Unknown structure to break for @@").ToString(), Node);
return;
}
if(!UK2Node_MakeStruct::CanBeMade(Node->StructType))
{
CompilerContext.MessageLog.Warning(*LOCTEXT("MakeStruct_Error", "The structure contains read-only members @@. Try use specialized 'make' function if available. ").ToString(), Node);
}
FNodeHandlingFunctor::RegisterNets(Context, Node);
UEdGraphPin* OutputPin = FindOutputStructPinChecked(Node);
UEdGraphPin* Net = FEdGraphUtilities::GetNetFromPin(OutputPin);
check(NULL != Net);
FBPTerminal** FoundTerm = Context.NetMap.Find(Net);
FBPTerminal* Term = FoundTerm ? *FoundTerm : NULL;
check(NULL != Term);
UStruct* StructInTerm = Cast<UStruct>(Term->Type.PinSubCategoryObject.Get());
if (NULL == StructInTerm || !StructInTerm->IsChildOf(Node->StructType))
{
CompilerContext.MessageLog.Error(*LOCTEXT("MakeStruct_NoMatch_Error", "Structures don't match for @@").ToString(), Node);
}
}
virtual void RegisterNet(FKismetFunctionContext& Context, UEdGraphPin* Net) OVERRIDE
{
FBPTerminal* Term = new (Context.IsEventGraph() ? Context.EventGraphLocals : Context.Locals) FBPTerminal();
Term->CopyFromPin(Net, Context.NetNameMap->MakeValidName(Net));
Context.NetMap.Add(Net, Term);
}
virtual void Compile(FKismetFunctionContext& Context, UEdGraphNode* InNode) OVERRIDE
{
UK2Node_MakeStruct* Node = CastChecked<UK2Node_MakeStruct>(InNode);
if (NULL == Node->StructType)
{
CompilerContext.MessageLog.Error(*LOCTEXT("MakeStruct_UnknownStructure_Error", "Unknown structure to break for @@").ToString(), Node);
return;
}
UEdGraphPin* OutputStructNet = FEdGraphUtilities::GetNetFromPin(FindOutputStructPinChecked(Node));
FBPTerminal** FoundTerm = Context.NetMap.Find(OutputStructNet);
FBPTerminal* OutputStructTerm = FoundTerm ? *FoundTerm : NULL;
check(NULL != OutputStructTerm);
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (Pin && !CompilerContext.GetSchema()->IsMetaPin(*Pin) && (Pin->Direction == EGPD_Input))
{
FBPTerminal** FoundSrcTerm = Context.NetMap.Find(FEdGraphUtilities::GetNetFromPin(Pin));
FBPTerminal* SrcTerm = FoundSrcTerm ? *FoundSrcTerm : NULL;
check(NULL != SrcTerm);
UProperty* BoundProperty = FindField<UProperty>(Node->StructType, *(Pin->PinName));
check(NULL != BoundProperty);
FBPTerminal* DstTerm = new (Context.IsEventGraph() ? Context.EventGraphLocals : Context.Locals) FBPTerminal();
DstTerm->CopyFromPin(Pin, Context.NetNameMap->MakeValidName(Pin));
DstTerm->AssociatedVarProperty = BoundProperty;
DstTerm->Context = OutputStructTerm;
FBlueprintCompiledStatement& Statement = Context.AppendStatementForNode(Node);
Statement.Type = KCST_Assignment;
Statement.LHS = DstTerm;
Statement.RHS.Add(SrcTerm);
}
}
if(!Node->IsNodePure())
{
GenerateSimpleThenGoto(Context, *Node);
}
}
};
//////////////////////////////////////////////////////////////////////////
// UK2Node_MakeStruct
UK2Node_MakeStruct::FMakeStructPinManager::FMakeStructPinManager(const uint8* InSampleStructMemory)
: FStructOperationOptionalPinManager(), SampleStructMemory(InSampleStructMemory)
{
}
void UK2Node_MakeStruct::FMakeStructPinManager::CustomizePinData(UEdGraphPin* Pin, FName SourcePropertyName, int32 ArrayIndex, UProperty* Property) const
{
struct FPinDefaultValueHelper
{
static void Set(UEdGraphPin& Pin, const FString& Value, bool bIsText)
{
Pin.AutogeneratedDefaultValue = Value;
if (bIsText)
{
Pin.DefaultTextValue = FText::FromString(Value);
}
else
{
Pin.DefaultValue = Value;
}
}
};
UK2Node_StructOperation::FStructOperationOptionalPinManager::CustomizePinData(Pin, SourcePropertyName, ArrayIndex, Property);
if (Pin && Property)
{
const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>();
check(Schema);
const bool bIsText = Property->IsA<UTextProperty>();
checkSlow(bIsText == (Schema->PC_Text == Pin->PinType.PinCategory));
const FString& MetadataDefaultValue = Property->GetMetaData(TEXT("MakeStructureDefaultValue"));
if (!MetadataDefaultValue.IsEmpty())
{
FPinDefaultValueHelper::Set(*Pin, MetadataDefaultValue, bIsText);
return;
}
if (NULL != SampleStructMemory)
{
FString NewDefaultValue;
if (Property->ExportText_InContainer(0, NewDefaultValue, SampleStructMemory, SampleStructMemory, NULL, PPF_None))
{
if (Schema->IsPinDefaultValid(Pin, NewDefaultValue, NULL, FText::GetEmpty()).IsEmpty())
{
FPinDefaultValueHelper::Set(*Pin, NewDefaultValue, bIsText);
return;
}
}
}
Schema->SetPinDefaultValueBasedOnType(Pin);
}
}
bool UK2Node_MakeStruct::FMakeStructPinManager::CanTreatPropertyAsOptional(UProperty* TestProperty) const
{
return UK2Node_MakeStruct::CanBeExposed(TestProperty);
}
UK2Node_MakeStruct::UK2Node_MakeStruct(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
}
void UK2Node_MakeStruct::AllocateDefaultPins()
{
const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>();
if(Schema && StructType)
{
CreatePin(EGPD_Output, Schema->PC_Struct, TEXT(""), StructType, false, false, StructType->GetName());
{
FStructureEditorUtils::FStructOnScope StructOnScope(Cast<UScriptStruct>(StructType));
FMakeStructPinManager OptionalPinManager(StructOnScope.GetStructMemory());
OptionalPinManager.RebuildPropertyList(ShowPinForProperties, StructType);
OptionalPinManager.CreateVisiblePins(ShowPinForProperties, StructType, EGPD_Input, this);
}
// When struct has a lot of fields, mark their pins as advanced
if(Pins.Num() > 5)
{
if(ENodeAdvancedPins::NoPins == AdvancedPinDisplay)
{
AdvancedPinDisplay = ENodeAdvancedPins::Hidden;
}
for(int32 PinIndex = 3; PinIndex < Pins.Num(); ++PinIndex)
{
if(UEdGraphPin * EdGraphPin = Pins[PinIndex])
{
EdGraphPin->bAdvancedView = true;
}
}
}
}
}
void UK2Node_MakeStruct::ValidateNodeDuringCompilation(class FCompilerResultsLog& MessageLog) const
{
if(!StructType)
{
MessageLog.Error(*LOCTEXT("NoStruct_Error", "No Struct in @@").ToString(), this);
}
}
FText UK2Node_MakeStruct::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
FFormatNamedArguments Args;
Args.Add(TEXT("StructName"), FText::FromString(StructType ? StructType->GetName() : FString()));
return FText::Format(LOCTEXT("MakeNodeTitle", "Make {StructName}"), Args);
}
FString UK2Node_MakeStruct::GetNodeNativeTitle(ENodeTitleType::Type TitleType) const
{
// Do not setup this function for localization, intentionally left unlocalized!
return FString(TEXT("Make ")) + (StructType ? StructType->GetName() : FString());
}
FString UK2Node_MakeStruct::GetTooltip() const
{
return FString::Printf(
*LOCTEXT("MakeStruct_Tooltip", "Adds a node that create a '%s' from its members").ToString(),
*(StructType ? StructType->GetName() : FString())
);
}
FLinearColor UK2Node_MakeStruct::GetNodeTitleColor() const
{
if(const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>())
{
FEdGraphPinType PinType;
PinType.PinCategory = K2Schema->PC_Struct;
PinType.PinSubCategoryObject = StructType;
return K2Schema->GetPinTypeColor(PinType);
}
return UK2Node::GetNodeTitleColor();
}
bool UK2Node_MakeStruct::CanBeExposed(const UProperty* Property)
{
if(Property)
{
const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>();
check(Schema);
FEdGraphPinType DumbGraphPinType;
const bool bConvertable = Schema->ConvertPropertyToPinType(Property, /*out*/ DumbGraphPinType);
const bool bVisible = Property->HasAnyPropertyFlags(CPF_BlueprintVisible|CPF_Edit);
const bool bBlueprintReadOnly = Property->HasAllPropertyFlags(CPF_BlueprintReadOnly);
if(bVisible && bConvertable && !bBlueprintReadOnly)
{
return true;
}
}
return false;
}
bool UK2Node_MakeStruct::CanBeMade(const UScriptStruct* Struct)
{
if(!Struct->GetBoolMetaData(TEXT("HasNativeMakeBreak")))
{
for (TFieldIterator<UProperty> It(Struct); It; ++It)
{
if(CanBeExposed(*It))
{
return true;
}
}
}
return false;
}
FNodeHandlingFunctor* UK2Node_MakeStruct::CreateNodeHandler(FKismetCompilerContext& CompilerContext) const
{
return new FKCHandler_MakeStruct(CompilerContext);
}
UK2Node::ERedirectType UK2Node_MakeStruct::DoPinsMatchForReconstruction(const UEdGraphPin* NewPin, int32 NewPinIndex, const UEdGraphPin* OldPin, int32 OldPinIndex) const
{
ERedirectType Result = UK2Node::DoPinsMatchForReconstruction(NewPin, NewPinIndex, OldPin, OldPinIndex);
if ((ERedirectType_None == Result) && DoRenamedPinsMatch(NewPin, OldPin, false))
{
Result = ERedirectType_Custom;
}
return Result;
}
#undef LOCTEXT_NAMESPACE