October3d55/M/BlobSerialization/Source/BlobSerializationEditor/Private/K2Node_BlobOperation.cpp

197 lines
5.6 KiB
C++

// Copyright (c) Samuel Kahn (samuel@kahncode.com). All Rights Reserved.
#include "K2Node_BlobOperation.h"
#include "Blob.h"
#include "BlueprintActionDatabaseRegistrar.h"
#include "BlueprintFieldNodeSpawner.h"
#include "EdGraphSchema_K2.h"
#include "EdGraphUtilities.h"
#include "EditorCategoryUtils.h"
#include "K2Node_CallFunction.h"
#include "KismetCompiler.h"
#define LOCTEXT_NAMESPACE "K2Node_BlobOperation"
//////////////////////////////////////////////////////////////////////////
// UK2Node_BlobOperation
void UK2Node_BlobOperation::AllocateDefaultPins()
{
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);
AdvancedPinDisplay = ENodeAdvancedPins::Hidden;
}
void UK2Node_BlobOperation::AllocateBehaviorPin()
{
UEdGraphPin* BehaviorPin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Byte, FName(TEXT("Behavior")));
BehaviorPin->bAdvancedView = true;
static UEnum* ArchiveTypeEnum = FindObjectChecked<UEnum>(ANY_PACKAGE, TEXT("EBlobArchivetype"), /*ExactClass*/ true);
BehaviorPin->PinType.PinSubCategoryObject = ArchiveTypeEnum;
BehaviorPin->DefaultValue = ArchiveTypeEnum->GetNameStringByValue((int8)EBlobArchiveType::Default);
BehaviorPin->bAdvancedView = true;
}
void UK2Node_BlobOperation::AllocateNetContextPin()
{
UEdGraphPin* Pin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Object, FName(TEXT("NetContext")));
Pin->PinType.PinSubCategoryObject = UObject::StaticClass();
Pin->bAdvancedView = true;
}
void UK2Node_BlobOperation::PreloadRequiredAssets()
{
if (StructType)
PreloadObject(StructType);
Super::PreloadRequiredAssets();
}
void UK2Node_BlobOperation::ValidateNodeDuringCompilation(class FCompilerResultsLog& MessageLog) const
{
Super::ValidateNodeDuringCompilation(MessageLog);
if (!StructType)
{
MessageLog.Error(*LOCTEXT("NoStruct_Error", "No Struct connected to @@").ToString(), this);
}
else if (StructType == FBlob::StaticStruct())
{
MessageLog.Error(*LOCTEXT("BlobToBlob_Error", "@@ cannot convert BinaryBlob into a BinaryBlob").ToString(), this);
}
}
FLinearColor UK2Node_BlobOperation::GetNodeTitleColor() const
{
if (const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>())
{
FEdGraphPinType PinType;
PinType.PinCategory = UEdGraphSchema_K2::PC_Struct;
PinType.PinSubCategoryObject = StructType;
return K2Schema->GetPinTypeColor(PinType);
}
return UK2Node::GetNodeTitleColor();
}
void UK2Node_BlobOperation::ConvertDeprecatedNode(UEdGraph* Graph, bool bOnlySafeChanges)
{
// User may have since deleted the struct type
if (StructType == nullptr)
{
return;
}
}
bool UK2Node_BlobOperation::HasExternalDependencies(TArray<class UStruct*>* OptionalOutput /*= nullptr*/) const
{
const bool bResult = nullptr != StructType;
if (bResult && OptionalOutput)
{
OptionalOutput->AddUnique(StructType);
}
const bool bSuperResult = Super::HasExternalDependencies(OptionalOutput);
return bSuperResult || bResult;
}
void UK2Node_BlobOperation::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
{
// actions get registered under specific object-keys; the idea is that
// actions might have to be updated (or deleted) if their object-key is
// mutated (or removed)... here we use the node's class (so if the node
// type disappears, then the action should go with it)
UClass* ActionKey = GetClass();
// to keep from needlessly instantiating a UBlueprintNodeSpawner, first
// check to make sure that the registrar is looking for actions of this type
// (could be regenerating actions for a specific asset, and therefore the
// registrar would only accept actions corresponding to that asset)
if (ActionRegistrar.IsOpenForRegistration(ActionKey))
{
UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
check(NodeSpawner != nullptr);
ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner);
}
}
void UK2Node_BlobOperation::PostReconstructNode()
{
Super::PostReconstructNode();
RefreshStructPinType();
}
FText UK2Node_BlobOperation::GetMenuCategory() const
{
return FText::FromString(TEXT("BlobSerialization"));
}
void UK2Node_BlobOperation::RefreshStructPinType()
{
UEdGraphPin* StructPin = GetStructPin();
if (StructPin->LinkedTo.Num() == 1)
{
UEdGraphPin* ConnectedPin = StructPin->LinkedTo[0];
StructType = Cast<UScriptStruct>(ConnectedPin->PinType.PinSubCategoryObject);
}
else
{
StructType = nullptr;
}
StructPin->PinType.PinSubCategoryObject = StructType;
StructPin->PinType.PinCategory = (StructType == nullptr) ? UEdGraphSchema_K2::PC_Wildcard : UEdGraphSchema_K2::PC_Struct;
}
void UK2Node_BlobOperation::NotifyPinConnectionListChanged(UEdGraphPin* Pin)
{
Super::NotifyPinConnectionListChanged(Pin);
if (Pin == GetStructPin())
{
RefreshStructPinType();
}
}
void UK2Node_BlobOperation::ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
{
Super::ExpandNode(CompilerContext, SourceGraph);
if (!StructType)
{
RefreshStructPinType();
}
}
UEdGraphPin* UK2Node_BlobOperation::GetThenPin() const
{
UEdGraphPin* Pin = FindPin(UEdGraphSchema_K2::PN_Then);
check(Pin == nullptr || Pin->Direction == EGPD_Output); // If pin exists, it must be output
return Pin;
}
UEdGraphPin* UK2Node_BlobOperation::GetStructPin() const
{
return FindPin(TEXT("Struct"));
}
UEdGraphPin* UK2Node_BlobOperation::GetBlobPin() const
{
return FindPin(TEXT("Blob"));
}
UEdGraphPin* UK2Node_BlobOperation::GetBehaviorPin() const
{
return FindPin(TEXT("Behavior"));
}
UEdGraphPin* UK2Node_BlobOperation::GetNetContextPin() const
{
return FindPin(TEXT("NetContext"));
}
#undef LOCTEXT_NAMESPACE