Overhaul the handling of return values in LuaProbe

This commit is contained in:
2025-04-08 18:53:26 -04:00
parent a18d8e1f0b
commit 3423c01807
6 changed files with 100 additions and 194 deletions

View File

@@ -48,7 +48,7 @@
const FName UK2Node_LuaInvoke::FunctionPinName(TEXT("Lua Function Prototype"));
const FName UK2Node_LuaInvoke::PlacePinName(TEXT("Place Tangible"));
const FName UK2Node_LuaInvoke::ExtraResultsPinName(TEXT("Extra Results"));
const FName UK2Node_LuaInvoke::ErrorPinName(TEXT("Lua Error"));
const FName UK2Node_LuaInvoke::ErrorPinName(TEXT("Error"));
bool UK2Node_LuaInvoke::IsPrefix(const UEdGraphPin *Pin, char Prefix)
{
@@ -174,8 +174,9 @@ void UK2Node_LuaInvoke::CreateCorrectPins()
{
Pins.Emplace(*OldPin);
OldPins.Remove(Name);
return true;
}
return OldPin != nullptr;
return false;
};
if (!KeepPin(UEdGraphSchema_K2::PN_Execute))
@@ -239,7 +240,7 @@ void UK2Node_LuaInvoke::CreateCorrectPins()
ErrorMsg = FString::Printf(TEXT("Unknown return value type: %s"), *Pin.Type);
continue;
}
FEdGraphPinType PinType = GetPinType(Accessor->GetReturnProperty());
FEdGraphPinType PinType = GetPinType(Accessor->FindPropertyByName(TEXT("Result")));
if (!KeepPin(PrefixedName, PinType))
{
CreatePin(EGPD_Output, PinType, PrefixedName);
@@ -384,58 +385,70 @@ void UK2Node_LuaInvoke::ExpandNode(class FKismetCompilerContext& CompilerContext
}
// Add the invoke or probe node.
UEdGraphPin *ReturnArrayPin = nullptr;
if (IsInvoke())
{
UK2Node_CallFunction* ActionNode = MakeCallFunctionNode(LuaCallLibraryFunction(LuaCallInvoke));
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(PlacePinName, EGPD_Input), *ActionNode->FindPinChecked(TEXT("Place")));
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(PlacePinName), *ActionNode->FindPinChecked(TEXT("Place")));
ThenPin->MakeLinkTo(ActionNode->GetExecPin());
ThenPin = ActionNode->GetThenPin();
}
else
{
UK2Node_CallFunction* ActionNode = MakeCallFunctionNode(LuaCallLibraryFunction(LuaCallProbe));
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(PlacePinName, EGPD_Input), *ActionNode->FindPinChecked(TEXT("Place")));
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(ErrorPinName, EGPD_Output), *ActionNode->FindPinChecked(TEXT("False")));
CompilerContext.MovePinLinksToIntermediate(*FindPinChecked(PlacePinName), *ActionNode->FindPinChecked(TEXT("Place")));
CompilerContext.CopyPinLinksToIntermediate(*FindPinChecked(ErrorPinName), *ActionNode->FindPinChecked(TEXT("False")));
ReturnArrayPin = ActionNode->FindPinChecked(TEXT("ReturnArray"));
ThenPin->MakeLinkTo(ActionNode->GetExecPin());
ThenPin = ActionNode->FindPinChecked(TEXT("True"));
}
// Add Unpacking operations for all return value pins.
for (const FlxParsedProto::Pin &PinInfo : ParsedProto.ReturnValues)
if (IsInvoke())
{
UEdGraphPin *Pin = FindPinChecked(AddPrefix(PinInfo.Name, 'R'));
UFunction *UnpackingFunc = UlxLuaCallLibrary::GetReturnValueUnpacker(PinInfo.Type);
if (UnpackingFunc == nullptr)
// Make sure we didn't have return values for an invoke.
if (IsInvoke() && ((ParsedProto.ReturnValues.Num() > 0) || (ParsedProto.ExtraReturnValues)))
{
// This codepath should be unreachable, but just in case.
CompilerContext.MessageLog.Error(TEXT("All return value pins must have known types."));
continue;
CompilerContext.MessageLog.Error(TEXT("Lua Call in Invoke mode does not support return values"));
}
UK2Node_CallFunction *UnpackNode = MakeCallFunctionNode(UnpackingFunc);
CompilerContext.MovePinLinksToIntermediate(*Pin, *UnpackNode->FindPinChecked(UEdGraphSchema_K2::PN_ReturnValue));
ThenPin->MakeLinkTo(UnpackNode->GetExecPin());
ThenPin = UnpackNode->GetThenPin();
}
// If there is an extra results pin, hook it up.
if (ParsedProto.ExtraReturnValues)
else
{
UEdGraphPin *Pin = FindPinChecked(ExtraResultsPinName);
UK2Node_CallFunction *UnpackNode = MakeCallFunctionNode(LuaCallLibraryFunction(LuaCallGetRest));
CompilerContext.MovePinLinksToIntermediate(*Pin, *UnpackNode->FindPinChecked(UEdGraphSchema_K2::PN_ReturnValue));
ThenPin->MakeLinkTo(UnpackNode->GetExecPin());
ThenPin = UnpackNode->GetThenPin();
// Add Unpacking operations for all return value pins.
for (const FlxParsedProto::Pin &PinInfo : ParsedProto.ReturnValues)
{
UEdGraphPin *Pin = FindPinChecked(AddPrefix(PinInfo.Name, 'R'));
UFunction *UnpackingFunc = UlxLuaCallLibrary::GetReturnValueUnpacker(PinInfo.Type);
if (UnpackingFunc == nullptr)
{
// This codepath should be unreachable, but just in case.
CompilerContext.MessageLog.Error(TEXT("All return value pins must have known types."));
continue;
}
UK2Node_CallFunction *UnpackNode = MakeCallFunctionNode(UnpackingFunc);
ReturnArrayPin->MakeLinkTo(UnpackNode->FindPinChecked(UEdGraphSchema_K2::PN_Self));
CompilerContext.CopyPinLinksToIntermediate(*FindPinChecked(ErrorPinName), *UnpackNode->FindPinChecked(TEXT("Error")));
CompilerContext.MovePinLinksToIntermediate(*Pin, *UnpackNode->FindPinChecked(TEXT("Result")));
ThenPin->MakeLinkTo(UnpackNode->GetExecPin());
ThenPin = UnpackNode->FindPinChecked(TEXT("Success"));
}
// If there is an extra results pin, hook it up.
if (ParsedProto.ExtraReturnValues)
{
UEdGraphPin *ExtraPin = FindPinChecked(ExtraResultsPinName);
UFunction *DiscardFunc = UlxLuaValues::StaticClass()->FindFunctionByName(TEXT("DiscardBeforeCursor"));
UK2Node_CallFunction *DiscardNode = MakeCallFunctionNode(DiscardFunc);
ReturnArrayPin->MakeLinkTo(DiscardNode->FindPinChecked(UEdGraphSchema_K2::PN_Self));
ThenPin->MakeLinkTo(DiscardNode->GetExecPin());
ThenPin = DiscardNode->GetThenPin();
CompilerContext.MovePinLinksToIntermediate(*ExtraPin, *ReturnArrayPin);
}
}
// Link up the Exec pins.
CompilerContext.MovePinLinksToIntermediate(*GetExecPin(), *BeginNode->GetExecPin());
CompilerContext.MovePinLinksToIntermediate(*GetThenPin(), *ThenPin);
// Make sure we didn't have return values for an invoke.
if (IsInvoke() && ((ParsedProto.ReturnValues.Num() > 0) || (ParsedProto.ExtraReturnValues)))
{
CompilerContext.MessageLog.Error(TEXT("Lua Call in Invoke mode does not support return values"));
}
BreakAllNodeLinks();
}