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

Binary file not shown.

View File

@@ -169,16 +169,14 @@ void FlxParsedProto::Parse(const FString &str) {
UFunction *UlxLuaCallLibrary::GetArgumentPacker(const FString &Type) UFunction *UlxLuaCallLibrary::GetArgumentPacker(const FString &Type)
{ {
FString LType = Type.ToLower(); FName PackerName(FString::Printf(TEXT("LuaCallArgument_%s"), *Type));
FName PackerName(FString::Printf(TEXT("LuaCallArgument_%s"), *LType));
return UlxLuaCallLibrary::StaticClass()->FindFunctionByName(PackerName); return UlxLuaCallLibrary::StaticClass()->FindFunctionByName(PackerName);
} }
UFunction *UlxLuaCallLibrary::GetReturnValueUnpacker(const FString &Type) UFunction *UlxLuaCallLibrary::GetReturnValueUnpacker(const FString &Type)
{ {
FString LType = Type.ToLower(); FName PackerName(FString::Printf(TEXT("Read%s"), *Type));
FName PackerName(FString::Printf(TEXT("LuaCallReturnValue_%s"), *LType)); return UlxLuaValues::StaticClass()->FindFunctionByName(PackerName);
return UlxLuaCallLibrary::StaticClass()->FindFunctionByName(PackerName);
} }
FString UlxLuaCallLibrary::AllFunctionsWithPrefix(const TCHAR *Prefix) FString UlxLuaCallLibrary::AllFunctionsWithPrefix(const TCHAR *Prefix)
@@ -223,41 +221,36 @@ void UlxLuaCallLibrary::LuaCallInvoke(UObject *context, AActor *place)
} }
bool UlxLuaCallLibrary::LuaCallProbe(UObject *context, AActor *place) bool UlxLuaCallLibrary::LuaCallProbe(UObject *context, AActor *place, UlxLuaValues *&ReturnArray)
{ {
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context); ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetBuffer(); FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
if (NotInitialized(sb)) return false; if (NotInitialized(sb)) return false;
mode->LuaCallEnd(InvocationKind::LUA_PROBE, place); ReturnArray = mode->LuaCallEnd(InvocationKind::LUA_PROBE, place);
FlxStreamBuffer &result = mode->LuaCallGetResult(); if ((ReturnArray == nullptr) || (ReturnArray->Length() < 1))
SimpleDynamicTag tag = result.read_simple_dynamic_tag(); {
if (tag != SimpleDynamicTag::STRING)
{
UE_LOG(LogLuprexIntegration, Error, TEXT("corruption in lua_probe")); UE_LOG(LogLuprexIntegration, Error, TEXT("corruption in lua_probe"));
ReturnArray = nullptr;
return false; return false;
} }
FString ErrorMessage = result.read_fstring(); ElxSuccessOrError Status;
FString ErrorMessage;
ReturnArray->ReadString(Status, ErrorMessage);
if (Status != ElxSuccessOrError::Success)
{
UE_LOG(LogLuprexIntegration, Error, TEXT("corruption in lua_probe"));
ReturnArray = nullptr;
return false;
}
if (!ErrorMessage.IsEmpty()) if (!ErrorMessage.IsEmpty())
{ {
UE_LOG(LogLuprex, Error, TEXT("%s"), *ErrorMessage); UE_LOG(LogLuprex, Error, TEXT("%s"), *ErrorMessage);
ReturnArray = nullptr;
return false; return false;
} }
return true; return true;
} }
UlxLuaValues *UlxLuaCallLibrary::LuaCallGetRest(UObject *context)
{
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetResult();
UlxLuaValues *Values = NewObject<UlxLuaValues>(context);
if (!Values->Initialize(sb.view()))
{
UE_LOG(LogBlueprint, Error, TEXT("Lua call returned corrupt data"));
return nullptr;
}
return Values;
}
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// //
// Argument Packing functions // Argument Packing functions
@@ -330,98 +323,6 @@ void UlxLuaCallLibrary::LuaCallArgument_boolean(UObject *context, bool pbool) {
} }
/////////////////////////////////////////////////////////////////
//
// Return Value Unpacking functions
//
/////////////////////////////////////////////////////////////////
FString UlxLuaCallLibrary::LuaCallReturnValue_string(UObject *context) {
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetResult();
SimpleDynamicTag tag = sb.read_simple_dynamic_tag();
if (tag != SimpleDynamicTag::STRING)
{
UE_LOG(LogBlueprint, Error, TEXT("expected lua to return a string"));
return TEXT("");
}
return sb.read_fstring();
}
FName UlxLuaCallLibrary::LuaCallReturnValue_name(UObject *context) {
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetResult();
SimpleDynamicTag tag = sb.read_simple_dynamic_tag();
if (tag != SimpleDynamicTag::TOKEN)
{
UE_LOG(LogBlueprint, Error, TEXT("expected lua to return a name"));
return FName();
}
return sb.read_fname();
}
double UlxLuaCallLibrary::LuaCallReturnValue_float(UObject *context) {
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetResult();
SimpleDynamicTag tag = sb.read_simple_dynamic_tag();
if (tag != SimpleDynamicTag::NUMBER)
{
UE_LOG(LogBlueprint, Error, TEXT("expected lua to return a float"));
return 0.0;
}
return sb.read_double();
}
int UlxLuaCallLibrary::LuaCallReturnValue_int(UObject *context) {
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetResult();
SimpleDynamicTag tag = sb.read_simple_dynamic_tag();
if (tag != SimpleDynamicTag::NUMBER)
{
UE_LOG(LogBlueprint, Error, TEXT("expected lua to return a number"));
return 0;
}
return int(sb.read_double());
}
FVector UlxLuaCallLibrary::LuaCallReturnValue_vector(UObject *context) {
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetResult();
SimpleDynamicTag tag = sb.read_simple_dynamic_tag();
if (tag != SimpleDynamicTag::VECTOR)
{
UE_LOG(LogBlueprint, Error, TEXT("expected lua to return a vector"));
return FVector();
}
return sb.read_fvector();
}
FVector2D UlxLuaCallLibrary::LuaCallReturnValue_vector2d(UObject *context) {
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetResult();
SimpleDynamicTag tag = sb.read_simple_dynamic_tag();
if (tag != SimpleDynamicTag::VECTOR)
{
UE_LOG(LogBlueprint, Error, TEXT("expected lua to return a vector"));
return FVector2D();
}
FVector v = sb.read_fvector();
return FVector2D(v.X, v.Y);
}
bool UlxLuaCallLibrary::LuaCallReturnValue_boolean(UObject *context) {
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetResult();
SimpleDynamicTag tag = sb.read_simple_dynamic_tag();
if (tag != SimpleDynamicTag::BOOLEAN)
{
UE_LOG(LogBlueprint, Error, TEXT("expected lua to return a boolean"));
return false;
}
return sb.read_bool();
}
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// //
// Returning the rest of the lua return values as an array. // Returning the rest of the lua return values as an array.
@@ -478,6 +379,8 @@ FString UlxLuaValues::DebugString() const
{ {
if (i > 0) Output << TEXT(", "); if (i > 0) Output << TEXT(", ");
if (i == Cursor) Output << TEXT("^ ");
ElxLuaValueType Type = Types[i]; ElxLuaValueType Type = Types[i];
FlxStreamBuffer Decoder(Data[i]); FlxStreamBuffer Decoder(Data[i]);
switch (Type) switch (Type)
@@ -517,6 +420,16 @@ ElxSuccessOrError UlxLuaValues::CheckType(ElxLuaValueType Type, ElxLuaValueType
return ElxSuccessOrError::Success; return ElxSuccessOrError::Success;
} }
void UlxLuaValues::DiscardBeforeCursor()
{
if (Cursor <= 0) return;
int Discard = Cursor;
if (Discard > Types.Num()) Discard = Types.Num();
Types.RemoveAt(0, Discard);
Data.RemoveAt(0, Discard);
Cursor -= Discard;
}
ElxLuaValueType UlxLuaValues::NextType() const ElxLuaValueType UlxLuaValues::NextType() const
{ {
if (Cursor < 0) return ElxLuaValueType::End; if (Cursor < 0) return ElxLuaValueType::End;

View File

@@ -149,10 +149,7 @@ public:
static void LuaCallInvoke(UObject *context, AActor *Place); static void LuaCallInvoke(UObject *context, AActor *Place);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", ExpandBoolAsExecs="ReturnValue", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function") UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", ExpandBoolAsExecs="ReturnValue", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static bool LuaCallProbe(UObject *context, AActor *Place); static bool LuaCallProbe(UObject *context, AActor *Place, UlxLuaValues *&ReturnArray);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static UlxLuaValues *LuaCallGetRest(UObject *context);
// //
// Functions that pack arguments into the call buffer. // Functions that pack arguments into the call buffer.
@@ -178,31 +175,6 @@ public:
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function") UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static void LuaCallArgument_boolean(UObject *context, bool Value); static void LuaCallArgument_boolean(UObject *context, bool Value);
//
// Functions that extract return values from the return buffer.
//
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static FString LuaCallReturnValue_string(UObject *context);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static FName LuaCallReturnValue_name(UObject *context);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static double LuaCallReturnValue_float(UObject *context);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static int LuaCallReturnValue_int(UObject *context);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static FVector LuaCallReturnValue_vector(UObject *context);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static FVector2D LuaCallReturnValue_vector2d(UObject *context);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context", BlueprintInternalUseOnly = "true"), Category = "Luprex|Call Lua Function")
static bool LuaCallReturnValue_boolean(UObject *context);
}; };
@@ -253,6 +225,9 @@ public:
// //
bool Initialize(std::string_view data); bool Initialize(std::string_view data);
UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array")
void DiscardBeforeCursor();
UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array")
FString DebugString() const; FString DebugString() const;

View File

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

View File

@@ -6,6 +6,7 @@
#include "ConsoleOutput.h" #include "ConsoleOutput.h"
#include "Tangible.h" #include "Tangible.h"
#include "TangibleManager.h" #include "TangibleManager.h"
#include "LuaCall.h"
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
@@ -168,29 +169,35 @@ void ALuprexGameModeBase::UpdatePossessedTangible() {
} }
} }
void ALuprexGameModeBase::LuaCallEnd(InvocationKind kind, int64 place_id) { UlxLuaValues *ALuprexGameModeBase::LuaCallEnd(InvocationKind kind, int64 place_id) {
std::string_view datapk = LuaCallBuffer.view(); std::string_view datapk = LuaCallBuffer.view();
FlxLockedWrapper w(LockableWrapper); FlxLockedWrapper w(LockableWrapper);
if (place_id == 0) place_id = w.GetActor(); if (place_id == 0) place_id = w.GetActor();
uint32_t retpklen; uint32_t retpklen;
const char *retpk; const char *retpk;
w->play_call_function(w.Get(), kind, place_id, datapk.size(), datapk.data(), &retpklen, &retpk); w->play_call_function(w.Get(), kind, place_id, datapk.size(), datapk.data(), &retpklen, &retpk);
LuaCallResult.open(std::string_view(retpk, retpklen)); if (kind == InvocationKind::LUA_PROBE)
{
UlxLuaValues *Result = NewObject<UlxLuaValues>(this);
Result->Initialize(std::string_view(retpk, retpklen));
return Result;
}
else return nullptr;
} }
void ALuprexGameModeBase::LuaCallEnd(InvocationKind kind) { UlxLuaValues *ALuprexGameModeBase::LuaCallEnd(InvocationKind kind) {
LuaCallEnd(kind, int64(0)); return LuaCallEnd(kind, int64(0));
} }
void ALuprexGameModeBase::LuaCallEnd(InvocationKind kind, AActor *place) { UlxLuaValues *ALuprexGameModeBase::LuaCallEnd(InvocationKind kind, AActor *place) {
if (place == nullptr) { if (place == nullptr) {
LuaCallEnd(kind, int64(0)); return LuaCallEnd(kind, int64(0));
} else { } else {
UlxTangible *tan = UlxTangible::GetActorTangibleOrLog(place); UlxTangible *tan = UlxTangible::GetActorTangibleOrLog(place);
if (tan == nullptr) { if (tan == nullptr) {
LuaCallResult.clear(); return NewObject<UlxLuaValues>(this);
} else { } else {
LuaCallEnd(kind, tan->TangibleId); return LuaCallEnd(kind, tan->TangibleId);
} }
} }
} }

View File

@@ -124,11 +124,10 @@ public:
// //
FlxStreamBuffer &LuaCallBegin() { LuaCallBuffer.clear(); return LuaCallBuffer; } FlxStreamBuffer &LuaCallBegin() { LuaCallBuffer.clear(); return LuaCallBuffer; }
FlxStreamBuffer &LuaCallGetBuffer() { return LuaCallBuffer; } FlxStreamBuffer &LuaCallGetBuffer() { return LuaCallBuffer; }
void LuaCallEnd(InvocationKind kind); UlxLuaValues *LuaCallEnd(InvocationKind kind);
void LuaCallEnd(InvocationKind kind, int64 place_id); UlxLuaValues *LuaCallEnd(InvocationKind kind, int64 place_id);
void LuaCallEnd(InvocationKind kind, AActor *place); UlxLuaValues *LuaCallEnd(InvocationKind kind, AActor *place);
FlxStreamBuffer &LuaCallGetResult() { return LuaCallResult; } void LuaCallClear() { LuaCallBuffer.clear(); }
void LuaCallClear() { LuaCallBuffer.clear(); LuaCallResult.clear(); }
// Execute a debugging command, typed on the GUI. // Execute a debugging command, typed on the GUI.
void ExecuteDebuggingCommand(FlxLockedWrapper &w, const FString &fs); void ExecuteDebuggingCommand(FlxLockedWrapper &w, const FString &fs);
@@ -191,9 +190,8 @@ public:
// To access it, construct a FlxLockedWrapper. // To access it, construct a FlxLockedWrapper.
FlxLockableWrapper LockableWrapper; FlxLockableWrapper LockableWrapper;
// The Lua Call assembly buffer. // The Lua Call Assembly Buffer.
FlxStreamBuffer LuaCallBuffer; FlxStreamBuffer LuaCallBuffer;
FlxStreamBuffer LuaCallResult;
// This utility runs the luprex update and socket update in a thread. // This utility runs the luprex update and socket update in a thread.
FTriggeredTask LuprexUpdateTask; FTriggeredTask LuprexUpdateTask;