Files
integration/Plugins/UEWingman/Source/UEWingman/Private/WingFunctionArgs.cpp

133 lines
3.7 KiB
C++

#include "WingFunctionArgs.h"
#include "K2Node_EditablePinBase.h"
#include "K2Node_FunctionResult.h"
#include "K2Node_Tunnel.h"
#include "WingTypes.h"
#include "WingUtils.h"
#include "WingServer.h"
#include "Kismet2/BlueprintEditorUtils.h"
bool WingFunctionArgs::HasArgs(UEdGraphNode* Node)
{
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
if (!Editable) return false;
return Editable->IsEditable();
}
FString WingFunctionArgs::GetArgs(UEdGraphNode* Node)
{
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
if (!Editable) return FString();
TStringBuilder<256> SB;
for (const TSharedPtr<FUserPinInfo>& Pin : Editable->UserDefinedPins)
{
if (SB.Len() > 0) SB << TEXT(",");
SB << UWingTypes::TypeToText(Pin->PinType) << TEXT(" ") << WingUtils::FormatName(*Pin);
}
return FString(SB);
}
EEdGraphPinDirection WingFunctionArgs::GetPinDirection(UK2Node_EditablePinBase* Node)
{
// FunctionResult takes inputs; Tunnel depends on its flags; everything else outputs.
if (Node->IsA<UK2Node_FunctionResult>())
return EGPD_Input;
if (UK2Node_Tunnel* Tunnel = Cast<UK2Node_Tunnel>(Node))
return Tunnel->bCanHaveInputs ? EGPD_Input : EGPD_Output;
return EGPD_Output;
}
bool WingFunctionArgs::ParseArgs(const FString& Args, TArray<FParsedArg>& OutArgs)
{
FString Trimmed = Args.TrimStartAndEnd();
if (Trimmed.IsEmpty()) return true;
TArray<FString> Parts;
Trimmed.ParseIntoArray(Parts, TEXT(","));
for (const FString& Part : Parts)
{
FString Token = Part.TrimStartAndEnd();
if (Token.IsEmpty()) continue;
// Split "type name"
FString TypeStr, NameStr;
if (!Token.Split(TEXT(" "), &TypeStr, &NameStr))
{
UWingServer::Printf(TEXT("ERROR: Malformed parameter list near '%s'\n"), *Token);
return false;
}
TypeStr.TrimStartAndEndInline();
NameStr.TrimStartAndEndInline();
if (TypeStr.IsEmpty() || NameStr.IsEmpty())
{
UWingServer::Printf(TEXT("ERROR: Malformed parameter list near '%s'\n"), *Token);
return false;
}
FParsedArg Arg;
UWingTypes::Requirements Req;
Req.BlueprintType = true;
Req.Blueprintable = false;
Req.AllowContainer = true;
if (!UWingTypes::TextToType(TypeStr, Arg.PinType, Req)) return false;
Arg.PinName = FName(*NameStr);
OutArgs.Add(MoveTemp(Arg));
}
return true;
}
bool WingFunctionArgs::SetArgs(UEdGraphNode* Node, const FString& Args)
{
UK2Node_EditablePinBase* Editable = Cast<UK2Node_EditablePinBase>(Node);
if (!Editable || !Editable->IsEditable())
{
UWingServer::Printf(TEXT("ERROR: Node does not contain an editable parameter list\n"));
return false;
}
// Parse the args string.
TArray<FParsedArg> NewArgs;
if (!ParseArgs(Args, NewArgs))
{
UWingServer::SuggestManual(WingManual::Section::ParameterLists);
UWingServer::SuggestManual(WingManual::Section::Types);
return false;
}
EEdGraphPinDirection Direction = GetPinDirection(Editable);
// Replace the UserDefinedPins array directly.
Editable->UserDefinedPins.Empty();
for (const FParsedArg& Arg : NewArgs)
{
TSharedPtr<FUserPinInfo> PinInfo = MakeShareable(new FUserPinInfo());
PinInfo->PinName = Arg.PinName;
PinInfo->PinType = Arg.PinType;
PinInfo->DesiredPinDirection = Direction;
Editable->UserDefinedPins.Add(PinInfo);
}
// ReconstructNode rebuilds real pins from UserDefinedPins
// and rewires old connections by matching pin names.
Editable->ReconstructNode();
return true;
}
bool WingFunctionArgs::CheckArgs(const FString &Args)
{
TArray<FParsedArg> NewArgs;
if (!ParseArgs(Args, NewArgs))
{
UWingServer::Printf(TEXT("ERROR: Invalid parameter list: %s\n"), *Args);
UWingServer::SuggestManual(WingManual::Section::ParameterLists);
UWingServer::SuggestManual(WingManual::Section::Types);
return false;
}
return true;
}