Raise Error node now actually prints its own error message
This commit is contained in:
Binary file not shown.
@@ -40,24 +40,26 @@
|
|||||||
|
|
||||||
#define LOCTEXT_NAMESPACE "K2Node_RaiseError"
|
#define LOCTEXT_NAMESPACE "K2Node_RaiseError"
|
||||||
|
|
||||||
// It simplifies everything if we can identify pins by name, but to do this
|
// All argument pins will have Names that start with "A:"
|
||||||
// we need for pin names to be unique. To ensure that there's no overlap
|
|
||||||
// between the hardwired names and the scripter's names, we add a single
|
|
||||||
// whitespace to any pin name specified in the format string.
|
|
||||||
|
|
||||||
static const FName FormatPinName(TEXT("Format"));
|
|
||||||
static const FName ResultPinName(TEXT("Result"));
|
|
||||||
|
|
||||||
static bool IsFormatPin(const UEdGraphPin *Pin) {
|
|
||||||
return (Pin->PinName == FormatPinName);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsResultPin(const UEdGraphPin *Pin) {
|
|
||||||
return (Pin->PinName == ResultPinName);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsArgumentPin(const UEdGraphPin *Pin) {
|
static bool IsArgumentPin(const UEdGraphPin *Pin) {
|
||||||
return ((Pin->PinName != FormatPinName) && (Pin->Direction == EGPD_Input));
|
TCHAR pname[FName::StringBufferSize];
|
||||||
|
Pin->PinName.ToString(pname);
|
||||||
|
return pname[0] == 'A' && pname[1] == ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
static FName ArgumentNameAddPrefix(const FString &name) {
|
||||||
|
FString Prefixed = FString("A:") + name;
|
||||||
|
return FName(*Prefixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FString ArgumentNameRemovePrefix(const FName &name) {
|
||||||
|
return name.ToString().Mid(2, FName::StringBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const FName FormatPinName(TEXT("Format"));
|
||||||
|
static bool IsFormatPin(const UEdGraphPin *Pin) {
|
||||||
|
return (Pin->PinName == FormatPinName);
|
||||||
}
|
}
|
||||||
|
|
||||||
UK2Node_RaiseError::UK2Node_RaiseError(const FObjectInitializer& ObjectInitializer)
|
UK2Node_RaiseError::UK2Node_RaiseError(const FObjectInitializer& ObjectInitializer)
|
||||||
@@ -74,14 +76,16 @@ void UK2Node_RaiseError::AllocateDefaultPins()
|
|||||||
|
|
||||||
void UK2Node_RaiseError::CreateCorrectPins()
|
void UK2Node_RaiseError::CreateCorrectPins()
|
||||||
{
|
{
|
||||||
// Create the Format Pin if it doesn't already exist.
|
if (FindPin(UEdGraphSchema_K2::PN_Execute) == nullptr) {
|
||||||
if (FindPin(FormatPinName, EGPD_Input) == nullptr) {
|
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);
|
||||||
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Text, FormatPinName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Result Pin if it doesn't already exist.
|
if (FindPin(UEdGraphSchema_K2::PN_Then) == nullptr) {
|
||||||
if (FindPin(ResultPinName, EGPD_Output) == nullptr) {
|
UEdGraphPin *P = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);
|
||||||
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Text, ResultPinName);
|
}
|
||||||
|
|
||||||
|
if (FindPin(FormatPinName, EGPD_Input) == nullptr) {
|
||||||
|
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Text, FormatPinName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer all Existing Argument pins to the Old Pins Map.
|
// Transfer all Existing Argument pins to the Old Pins Map.
|
||||||
@@ -91,20 +95,21 @@ void UK2Node_RaiseError::CreateCorrectPins()
|
|||||||
UEdGraphPin* CheckPin = *It;
|
UEdGraphPin* CheckPin = *It;
|
||||||
if (IsArgumentPin(CheckPin))
|
if (IsArgumentPin(CheckPin))
|
||||||
{
|
{
|
||||||
OldPins.Add(CheckPin->PinName.ToString(), CheckPin);
|
OldPins.Add(ArgumentNameRemovePrefix(CheckPin->PinName), CheckPin);
|
||||||
It.RemoveCurrent();
|
It.RemoveCurrent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Argument pins in the correct order, reusing old pins where possible.
|
// Create Argument pins in the correct order, reusing old pins where possible.
|
||||||
for (const FName& PinName : PinNames)
|
for (const FString& Name : PinNames)
|
||||||
{
|
{
|
||||||
UEdGraphPin **OldPin = OldPins.Find(PinName.ToString());
|
UEdGraphPin **OldPin = OldPins.Find(Name);
|
||||||
if (OldPin != nullptr) {
|
if (OldPin != nullptr) {
|
||||||
Pins.Emplace(*OldPin);
|
Pins.Emplace(*OldPin);
|
||||||
OldPins.Remove(PinName.ToString());
|
OldPins.Remove(Name);
|
||||||
} else {
|
} else {
|
||||||
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Wildcard, PinName);
|
FName PrefixedName = ArgumentNameAddPrefix(Name);
|
||||||
|
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Wildcard, PrefixedName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +174,17 @@ FText UK2Node_RaiseError::GetNodeTitle(ENodeTitleType::Type TitleType) const
|
|||||||
|
|
||||||
FText UK2Node_RaiseError::GetPinDisplayName(const UEdGraphPin* Pin) const
|
FText UK2Node_RaiseError::GetPinDisplayName(const UEdGraphPin* Pin) const
|
||||||
{
|
{
|
||||||
|
// These pins should be unlabeled.
|
||||||
|
if ((Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) || (IsFormatPin(Pin))) {
|
||||||
|
return FText::GetEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// For argument pins, we must strip off the Argument Pin Prefix.
|
||||||
|
if (IsArgumentPin(Pin)) {
|
||||||
|
return FText::FromString(ArgumentNameRemovePrefix(Pin->PinName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probably should never get here.
|
||||||
return FText::FromName(Pin->PinName);
|
return FText::FromName(Pin->PinName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,15 +209,8 @@ void UK2Node_RaiseError::PinDefaultValueChanged(UEdGraphPin* Pin)
|
|||||||
{
|
{
|
||||||
if(IsFormatPin(Pin))
|
if(IsFormatPin(Pin))
|
||||||
{
|
{
|
||||||
TArray< FString > ArgumentParams;
|
PinNames.Empty();
|
||||||
FText::GetFormatPatternParameters(Pin->DefaultTextValue, ArgumentParams);
|
FText::GetFormatPatternParameters(Pin->DefaultTextValue, PinNames);
|
||||||
|
|
||||||
PinNames.Reset();
|
|
||||||
for (const FString& Param : ArgumentParams)
|
|
||||||
{
|
|
||||||
FString WithWhite = Param + TEXT(" ");
|
|
||||||
PinNames.Add(FName(*WithWhite));
|
|
||||||
}
|
|
||||||
CreateCorrectPins();
|
CreateCorrectPins();
|
||||||
GetGraph()->NotifyNodeChanged(this);
|
GetGraph()->NotifyNodeChanged(this);
|
||||||
}
|
}
|
||||||
@@ -265,29 +274,39 @@ void UK2Node_RaiseError::ExpandNode(class FKismetCompilerContext& CompilerContex
|
|||||||
MakeArrayNode->AllocateDefaultPins();
|
MakeArrayNode->AllocateDefaultPins();
|
||||||
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(MakeArrayNode, this);
|
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(MakeArrayNode, this);
|
||||||
|
|
||||||
UEdGraphPin* ArrayOut = MakeArrayNode->GetOutputPin();
|
|
||||||
|
|
||||||
// This is the node that does all the Format work.
|
// This is the node that does all the Format work.
|
||||||
UK2Node_CallFunction* CallFormatFunction = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
|
UK2Node_CallFunction* CallFormatFunction = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
|
||||||
CallFormatFunction->SetFromFunction(UKismetTextLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UKismetTextLibrary, Format)));
|
CallFormatFunction->SetFromFunction(UKismetTextLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UKismetTextLibrary, Format)));
|
||||||
CallFormatFunction->AllocateDefaultPins();
|
CallFormatFunction->AllocateDefaultPins();
|
||||||
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(CallFormatFunction, this);
|
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(CallFormatFunction, this);
|
||||||
|
|
||||||
|
// This is the node that outputs the text.
|
||||||
|
UK2Node_CallFunction* CallPrintFunction = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
|
||||||
|
CallPrintFunction->SetFromFunction(UKismetSystemLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UKismetSystemLibrary, PrintText)));
|
||||||
|
CallPrintFunction->AllocateDefaultPins();
|
||||||
|
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(CallPrintFunction, this);
|
||||||
|
|
||||||
// Connect the output of the "Make Array" pin to the function's "InArgs" pin
|
// Connect the output of the "Make Array" pin to the function's "InArgs" pin
|
||||||
|
UEdGraphPin* ArrayOut = MakeArrayNode->GetOutputPin();
|
||||||
ArrayOut->MakeLinkTo(CallFormatFunction->FindPinChecked(TEXT("InArgs")));
|
ArrayOut->MakeLinkTo(CallFormatFunction->FindPinChecked(TEXT("InArgs")));
|
||||||
|
|
||||||
// This will set the "Make Array" node's type, only works if one pin is connected.
|
// This will set the "Make Array" node's type, only works if one pin is connected.
|
||||||
MakeArrayNode->PinConnectionListChanged(ArrayOut);
|
MakeArrayNode->PinConnectionListChanged(ArrayOut);
|
||||||
|
|
||||||
|
// Connect the output of the "Format" node to the PrintText function's "InText" pin
|
||||||
|
UEdGraphPin* FormatOut = CallFormatFunction->GetReturnValuePin();
|
||||||
|
FormatOut->MakeLinkTo(CallPrintFunction->FindPinChecked(TEXT("InText")));
|
||||||
|
|
||||||
|
// Configure the Print function to keep the text onscreen for 30 seconds.
|
||||||
|
UEdGraphPin* DurationIn = CallPrintFunction->FindPinChecked(TEXT("Duration"));
|
||||||
|
CallPrintFunction->GetSchema()->TrySetDefaultValue(*DurationIn, "30");
|
||||||
|
|
||||||
// For each argument, we will need to add in a "Make Struct" node.
|
// For each argument, we will need to add in a "Make Struct" node.
|
||||||
for(int32 ArgIdx = 0; ArgIdx < PinNames.Num(); ++ArgIdx)
|
for(int32 ArgIdx = 0; ArgIdx < PinNames.Num(); ++ArgIdx)
|
||||||
{
|
{
|
||||||
UEdGraphPin* ArgumentPin = FindPin(PinNames[ArgIdx], EGPD_Input);
|
FString OriginalName = PinNames[ArgIdx];
|
||||||
|
UEdGraphPin* ArgumentPin = FindPin(ArgumentNameAddPrefix(OriginalName), EGPD_Input);
|
||||||
// All argument pins have a whitespace appended to their pin names.
|
|
||||||
// We need the original name before the whitespace was appended.
|
|
||||||
FString OriginalName = ArgumentPin->PinName.ToString().LeftChop(1);
|
|
||||||
|
|
||||||
static UScriptStruct* FormatArgumentDataStruct = FindObjectChecked<UScriptStruct>(FindObjectChecked<UPackage>(nullptr, TEXT("/Script/Engine")), TEXT("FormatArgumentData"));
|
static UScriptStruct* FormatArgumentDataStruct = FindObjectChecked<UScriptStruct>(FindObjectChecked<UPackage>(nullptr, TEXT("/Script/Engine")), TEXT("FormatArgumentData"));
|
||||||
|
|
||||||
// Spawn a "Make Struct" node to create the struct needed for formatting the text.
|
// Spawn a "Make Struct" node to create the struct needed for formatting the text.
|
||||||
@@ -410,7 +429,7 @@ void UK2Node_RaiseError::ExpandNode(class FKismetCompilerContext& CompilerContex
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Unexpected pin type!
|
// Unexpected pin type!
|
||||||
CompilerContext.MessageLog.Error(*FText::Format(LOCTEXT("Error_UnexpectedPinType", "Pin '{0}' has an unexpected type: {1}"), FText::FromName(PinNames[ArgIdx]), FText::FromName(ArgumentPinCategory)).ToString());
|
CompilerContext.MessageLog.Error(*FText::Format(LOCTEXT("Error_UnexpectedPinType", "Pin '{0}' has an unexpected type: {1}"), FText::FromString(OriginalName), FText::FromName(ArgumentPinCategory)).ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -434,11 +453,13 @@ void UK2Node_RaiseError::ExpandNode(class FKismetCompilerContext& CompilerContex
|
|||||||
FindOutputStructPinChecked(MakeFormatArgumentDataStruct)->MakeLinkTo(InputPin);
|
FindOutputStructPinChecked(MakeFormatArgumentDataStruct)->MakeLinkTo(InputPin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move connection of RaiseError's "Result" pin to the call function's return value pin.
|
|
||||||
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(ResultPinName, EGPD_Output), *CallFormatFunction->GetReturnValuePin());
|
|
||||||
// Move connection of RaiseError's "Format" pin to the call function's "InPattern" pin
|
// Move connection of RaiseError's "Format" pin to the call function's "InPattern" pin
|
||||||
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(FormatPinName, EGPD_Input), *CallFormatFunction->FindPinChecked(TEXT("InPattern")));
|
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(FormatPinName), *CallFormatFunction->FindPinChecked(TEXT("InPattern")));
|
||||||
|
|
||||||
|
// Link up the Exec pins.
|
||||||
|
CompilerContext.MovePinLinksToIntermediate(*GetExecPin(), *CallPrintFunction->GetExecPin());
|
||||||
|
CompilerContext.MovePinLinksToIntermediate(*GetThenPin(), *CallPrintFunction->GetThenPin());
|
||||||
|
|
||||||
BreakAllNodeLinks();
|
BreakAllNodeLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class UK2Node_RaiseError : public UK2Node
|
|||||||
//~ End UEdGraphNode Interface.
|
//~ End UEdGraphNode Interface.
|
||||||
|
|
||||||
//~ Begin UK2Node Interface.
|
//~ Begin UK2Node Interface.
|
||||||
virtual bool IsNodePure() const override { return true; }
|
virtual bool IsNodePure() const override { return false; }
|
||||||
virtual void PostReconstructNode() override;
|
virtual void PostReconstructNode() override;
|
||||||
virtual bool NodeCausesStructuralBlueprintChange() const override { return true; }
|
virtual bool NodeCausesStructuralBlueprintChange() const override { return true; }
|
||||||
virtual void ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) override;
|
virtual void ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) override;
|
||||||
@@ -62,7 +62,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
/** When adding arguments to the node, their names are placed here and are generated as pins during construction */
|
/** When adding arguments to the node, their names are placed here and are generated as pins during construction */
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
TArray<FName> PinNames;
|
TArray<FString> PinNames;
|
||||||
|
|
||||||
/** Tooltip text for this node. */
|
/** Tooltip text for this node. */
|
||||||
FText NodeTooltip;
|
FText NodeTooltip;
|
||||||
|
|||||||
Reference in New Issue
Block a user