Clean up code for LuaCallNode

This commit is contained in:
2026-03-04 01:38:19 -05:00
parent 528a7b14df
commit b81a2a8685
3 changed files with 50 additions and 188 deletions

3
.gitignore vendored
View File

@@ -46,3 +46,6 @@ luprex/ext/eris-master/test/persist
luprex/ext/eris-master/test/unpersist
GPF-output/**
__pycache__/
.clangd-query.pid

View File

@@ -77,22 +77,9 @@ FString UK2Node_LuaInvoke::RemovePrefix(FName Name, char Prefix)
return FString(pname + 2);
}
static FEdGraphPinType GetPinType(const FProperty *Property)
{
FEdGraphPinType PinType;
bool IsWeak;
FName PinCat, PinSubCat;
UObject *PinSubCatObj = nullptr;
UEdGraphSchema_K2::GetPropertyCategoryInfo(Property, PinCat, PinSubCat, PinSubCatObj, IsWeak);
PinType.PinCategory = PinCat;
PinType.PinSubCategory = PinSubCat;
PinType.PinSubCategoryObject = PinSubCatObj;
return PinType;
}
UK2Node_LuaInvoke::UK2Node_LuaInvoke(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer), NodeTooltip(MakeTooltip())
: Super(ObjectInitializer)
{
}
@@ -102,47 +89,42 @@ UK2Node_LuaProbe::UK2Node_LuaProbe(const FObjectInitializer& ObjectInitializer)
}
FText UK2Node_LuaInvoke::MakeTooltip() const
FText UK2Node_LuaInvoke::GetTooltipText() const
{
// TODO: replace this string manipulation with text manipulation.
FString ArgTypes = UlxLuaCallLibrary::AllKnownArgumentTypes();
FString RetTypes = UlxLuaCallLibrary::AllKnownReturnValueTypes();
return FText::FromString(FString::Printf(TEXT(
static FText Tooltip = FText::FromString(FString::Printf(TEXT(
"Call a Lua function.\n"
"\n"
"The lua function prototype must be a hardwired string which must look like\n"
"one of the following:\n"
"one of the following:\n"
"\n"
" classname.funcname(int arg1, int arg2)\n"
" classname.funcname(int arg1, int arg2) : int ret1, int ret2\n"
" classname.funcname(int arg1, int arg2) : int ret1, int ret2, ...\n"
" classname.funcname(int arg1, int arg2)\n"
" classname.funcname(int arg1, int arg2) : int ret1, int ret2\n"
" classname.funcname(int arg1, int arg2) : int ret1, int ret2, ...\n"
"\n"
"You must specify types for the argument and return value pins. The:\n"
"types that you may specify are:\n"
"You must specify types for the argument and return value pins. The\n"
"types that you may specify are:\n"
"\n"
"Arguments: %s\n"
"Arguments: %s\n"
"Return Values: %s\n"
"\n"
"The prototype is parsed to determine what lua function to call.\n"
"The lua call node will automatically add pins for the arguments and\n"
"return values. If the function has no return values, you can omit those\n"
"from the proto. If you put an ellipsis at the end of the return values,\n"
"then any additional return values will be collected into a\n"
"dynamically typed array of values which you can iterate over later.\n"
"\n"
"The lua call node will automatically add pins for the arguments and\n"
"return values. If the function has no return values, you can omit those\n"
"from the proto. If you put an ellipsis at the end of the return values,\n"
"then any additional return values will be collected into a\n"
"dynamically typed array of values which you can iterate over later.\n"
"\n"
"Optionally, you may use the * wildcard for the classname. In that\n"
"case, the class of the 'place' tangible will be used.\n"
"\n"), *ArgTypes, *RetTypes));
"\n"), *UlxLuaCallLibrary::AllKnownArgumentTypes(), *UlxLuaCallLibrary::AllKnownReturnValueTypes()));
return Tooltip;
}
void UK2Node_LuaInvoke::AllocateDefaultPins()
{
Pins.Reset();
Super::AllocateDefaultPins();
CreateCorrectPins();
}
void UK2Node_LuaInvoke::CreateCorrectPins()
{
if (LuaFunctionPrototype.IsEmpty())
{
LuaFunctionPrototype = TEXT("class.func(int arg1, int arg2) : int ret1, int ret2");
@@ -157,62 +139,20 @@ void UK2Node_LuaInvoke::CreateCorrectPins()
ErrorMsg = FString::Printf(TEXT("Syntax error in lua function prototype: %s"), *ParsedProto.ErrorMessage);
}
// Transfer all pins to the old pins map and clear the pin list.
TMap<FName, UEdGraphPin *> OldPins;
for (auto It = Pins.CreateIterator(); It; ++It)
{
UEdGraphPin* CheckPin = *It;
OldPins.Add(CheckPin->PinName, CheckPin);
}
Pins.Empty();
// KeepPin is a function that moves a pin from the old pins
// map back onto the pins list.
auto KeepPin = [&](FName Name, FEdGraphPinType Type = FEdGraphPinType()) -> bool
{
UEdGraphPin **OldPin = OldPins.Find(Name);
if ((OldPin != nullptr) && (((*OldPin)->PinType == Type) || (Type.PinCategory == FName())))
{
Pins.Emplace(*OldPin);
OldPins.Remove(Name);
return true;
}
return false;
};
if (!KeepPin(UEdGraphSchema_K2::PN_Execute))
{
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);
}
if (!KeepPin(UEdGraphSchema_K2::PN_Then))
{
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);
}
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then);
if (!IsInvoke())
{
if (!KeepPin(ErrorPinName))
{
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, ErrorPinName);
}
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, ErrorPinName);
}
if (!KeepPin(FunctionPinName))
{
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, FunctionPinName);
}
if (!KeepPin(PlacePinName))
{
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Object, AActor::StaticClass(), PlacePinName);
}
// Copy the property names into the pins.
UEdGraphPin *FunctionPin = FindPinChecked(FunctionPinName);
UEdGraphPin *FunctionPin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, FunctionPinName);
FunctionPin->DefaultValue = LuaFunctionPrototype;
// Create Argument pins in the correct order, reusing old pins where possible.
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Object, AActor::StaticClass(), PlacePinName);
// Create argument pins.
for (const FlxParsedProto::Pin & Pin : ParsedProto.Arguments)
{
FName PrefixedName = AddPrefix(Pin.Name, 'A');
@@ -223,14 +163,12 @@ void UK2Node_LuaInvoke::CreateCorrectPins()
ErrorMsg = FString::Printf(TEXT("Unknown argument type: %s"), *Pin.Type);
continue;
}
FEdGraphPinType PinType = GetPinType(Accessor->FindPropertyByName(TEXT("Value")));
if (!KeepPin(PrefixedName, PinType))
{
CreatePin(EGPD_Input, PinType, PrefixedName);
}
FEdGraphPinType PinType;
GetDefault<UEdGraphSchema_K2>()->ConvertPropertyToPinType(Accessor->FindPropertyByName(TEXT("Value")), PinType);
CreatePin(EGPD_Input, PinType, PrefixedName);
}
// Create ReturnValue pins in the correct order, reusing old pins where possible.
// Create return value pins.
for (const FlxParsedProto::Pin & Pin : ParsedProto.ReturnValues)
{
FName PrefixedName = AddPrefix(Pin.Name, 'R');
@@ -241,28 +179,15 @@ void UK2Node_LuaInvoke::CreateCorrectPins()
ErrorMsg = FString::Printf(TEXT("Unknown return value type: %s"), *Pin.Type);
continue;
}
FEdGraphPinType PinType = GetPinType(Accessor->FindPropertyByName(TEXT("Result")));
if (!KeepPin(PrefixedName, PinType))
{
CreatePin(EGPD_Output, PinType, PrefixedName);
}
FEdGraphPinType PinType;
GetDefault<UEdGraphSchema_K2>()->ConvertPropertyToPinType(Accessor->FindPropertyByName(TEXT("Result")), PinType);
CreatePin(EGPD_Output, PinType, PrefixedName);
}
if (ParsedProto.ExtraReturnValues)
{
if (!KeepPin(ExtraResultsPinName))
{
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Object, UlxLuaValues::StaticClass(), ExtraResultsPinName);
}
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Object, UlxLuaValues::StaticClass(), ExtraResultsPinName);
}
// Delete any unused pins.
for (auto &iter : OldPins)
{
iter.Value->Modify();
iter.Value->MarkAsGarbage();
}
OldPins.Empty();
}
@@ -280,21 +205,14 @@ FText UK2Node_LuaInvoke::GetNodeTitle(ENodeTitleType::Type TitleType) const
FText UK2Node_LuaInvoke::GetPinDisplayName(const UEdGraphPin* Pin) const
{
// The exec pins don't need labels.
if ((Pin->PinName == UEdGraphSchema_K2::PN_Execute) || (Pin->PinName == UEdGraphSchema_K2::PN_Then))
// These pins don't need labels.
if ((Pin->PinName == UEdGraphSchema_K2::PN_Execute) ||
(Pin->PinName == UEdGraphSchema_K2::PN_Then) ||
(Pin->PinName == FunctionPinName))
{
return FText::GetEmpty();
}
// Many pins can go unlabeled if they have default values.
if (Pin->PinName == FunctionPinName)
{
if (Pin->LinkedTo.Num() == 0)
{
return FText::GetEmpty();
}
}
// For argument pins, we must strip off the Argument Pin Prefix.
if (IsPrefix(Pin, 'A'))
{
@@ -314,34 +232,18 @@ FText UK2Node_LuaInvoke::GetPinDisplayName(const UEdGraphPin* Pin) const
void UK2Node_LuaInvoke::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
GetGraph()->NotifyNodeChanged(this);
}
void UK2Node_LuaInvoke::PinConnectionListChanged(UEdGraphPin* Pin)
{
Modify();
// GetGraph()->NotifyNodeChanged(this);
}
void UK2Node_LuaInvoke::PinDefaultValueChanged(UEdGraphPin* Pin)
{
if(Pin->PinName == FunctionPinName)
if ((Pin->PinName == FunctionPinName) && (Pin->DefaultValue != LuaFunctionPrototype))
{
LuaFunctionPrototype = Pin->DefaultValue;
CreateCorrectPins();
GetGraph()->NotifyNodeChanged(this);
ReconstructNode();
}
}
FText UK2Node_LuaInvoke::GetTooltipText() const
{
return NodeTooltip;
}
void UK2Node_LuaInvoke::PostReconstructNode()
{
Super::PostReconstructNode();
CreateCorrectPins();
}
#define LuaCallLibraryFunction(name) (UlxLuaCallLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxLuaCallLibrary, name)))
@@ -407,7 +309,7 @@ void UK2Node_LuaInvoke::ExpandNode(class FKismetCompilerContext& CompilerContext
if (IsInvoke())
{
// Make sure we didn't have return values for an invoke.
if (IsInvoke() && ((ParsedProto.ReturnValues.Num() > 0) || (ParsedProto.ExtraReturnValues)))
if ((ParsedProto.ReturnValues.Num() > 0) || (ParsedProto.ExtraReturnValues))
{
CompilerContext.MessageLog.Error(TEXT("Lua Call in Invoke mode does not support return values"));
}
@@ -457,47 +359,13 @@ void UK2Node_LuaInvoke::ExpandNode(class FKismetCompilerContext& CompilerContext
UK2Node::ERedirectType UK2Node_LuaInvoke::DoPinsMatchForReconstruction(const UEdGraphPin* NewPin, int32 NewPinIndex, const UEdGraphPin* OldPin, int32 OldPinIndex) const
{
ERedirectType RedirectType = ERedirectType_None;
// if the pin names do match
if (NewPin->PinName.ToString().Equals(OldPin->PinName.ToString(), ESearchCase::CaseSensitive))
if ((NewPin->PinName == OldPin->PinName) &&
(NewPin->Direction == OldPin->Direction) &&
(NewPin->PinType == OldPin->PinType))
{
// Make sure we're not dealing with a menu node
UEdGraph* OuterGraph = GetGraph();
if( OuterGraph && OuterGraph->Schema )
{
const UEdGraphSchema_K2* K2Schema = Cast<const UEdGraphSchema_K2>(GetSchema());
if( !K2Schema || K2Schema->IsSelfPin(*NewPin) || K2Schema->ArePinTypesCompatible(OldPin->PinType, NewPin->PinType) )
{
RedirectType = ERedirectType_Name;
}
else
{
RedirectType = ERedirectType_None;
}
}
return ERedirectType_Name;
}
else
{
// try looking for a redirect if it's a K2 node
if (UK2Node* Node = Cast<UK2Node>(NewPin->GetOwningNode()))
{
// if you don't have matching pin, now check if there is any redirect param set
TArray<FString> OldPinNames;
GetRedirectPinNames(*OldPin, OldPinNames);
FName NewPinName;
RedirectType = ShouldRedirectParam(OldPinNames, /*out*/ NewPinName, Node);
// make sure they match
if ((RedirectType != ERedirectType_None) && (!NewPin->PinName.ToString().Equals(NewPinName.ToString(), ESearchCase::CaseSensitive)))
{
RedirectType = ERedirectType_None;
}
}
}
return RedirectType;
return ERedirectType_None;
}
bool UK2Node_LuaInvoke::IsConnectionDisallowed(const UEdGraphPin* MyPin, const UEdGraphPin* OtherPin, FString& OutReason) const

View File

@@ -36,7 +36,6 @@ class UK2Node_LuaInvoke : public UK2Node
virtual void AllocateDefaultPins() override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual bool ShouldShowNodeProperties() const override { return true; }
virtual void PinConnectionListChanged(UEdGraphPin* Pin) override;
virtual void PinDefaultValueChanged(UEdGraphPin* Pin) override;
virtual FText GetTooltipText() const override;
virtual FText GetPinDisplayName(const UEdGraphPin* Pin) const override;
@@ -44,7 +43,6 @@ class UK2Node_LuaInvoke : public UK2Node
//~ Begin UK2Node Interface.
virtual bool IsNodePure() const override { return false; }
virtual void PostReconstructNode() override;
virtual bool NodeCausesStructuralBlueprintChange() const override { return true; }
virtual void ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) override;
virtual ERedirectType DoPinsMatchForReconstruction(const UEdGraphPin* NewPin, int32 NewPinIndex, const UEdGraphPin* OldPin, int32 OldPinIndex) const override;
@@ -58,11 +56,6 @@ private:
virtual bool IsInvoke() const { return true; }
FText MakeTooltip() const;
/** Create all necessary pins. */
void CreateCorrectPins();
/** Pin Names for the three built-in Pins **/
static const FName FunctionPinName;
static const FName PlacePinName;
@@ -79,8 +72,6 @@ private:
UPROPERTY()
FString LuaFunctionPrototype;
/** Tooltip text for this node. */
FText NodeTooltip;
};
UCLASS(MinimalAPI)