From eb00019c8669823de82049ffb6a3fadca4faea04 Mon Sep 17 00:00:00 2001 From: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Mon, 5 Dec 2022 23:21:23 -0800 Subject: [PATCH] fix passing numbers for string args in .net lua functions (old engine had this behavior, granted "bad user" if they relied on this), add appropriate test fix passing sbyte/char as args, add appropriate tests cleanup the lua auto unlock hack, using a nice ref struct + dispose to handle it --- Assets/dll/NLua.dll | Bin 83968 -> 83968 bytes References/NLua.dll | Bin 83968 -> 83968 bytes .../Api/Classes/GuiApi.cs | 19 ++- .../tools/Lua/Win32LuaLibraries.cs | 134 ++++++++++-------- .../Client.Common/lua/LuaTests.cs | 42 ++++-- 5 files changed, 113 insertions(+), 82 deletions(-) diff --git a/Assets/dll/NLua.dll b/Assets/dll/NLua.dll index 7a4fa5cbe279350d3171a127557380b799e9d4d0..542ab2f01a7316e826fda098adf22206a3ba8d07 100644 GIT binary patch delta 13991 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 VW<7R _guiApi = guiApi; + + public void Dispose() + { + _guiApi.UnlockSurface(DisplaySurfaceID.EmuCore); + _guiApi.UnlockSurface(DisplaySurfaceID.Client); + } } + public LuaAutoUnlockHack ThisIsTheLuaAutoUnlockHack() + => new(this); + public void DrawNew(string name, bool clear) { switch (name) diff --git a/src/BizHawk.Client.EmuHawk/tools/Lua/Win32LuaLibraries.cs b/src/BizHawk.Client.EmuHawk/tools/Lua/Win32LuaLibraries.cs index 1d2be896eb..eb6a632018 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Lua/Win32LuaLibraries.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Lua/Win32LuaLibraries.cs @@ -185,84 +185,92 @@ namespace BizHawk.Client.EmuHawk public void CallSaveStateEvent(string name) { - try + using (GuiAPI.ThisIsTheLuaAutoUnlockHack()) { - foreach (var lf in RegisteredFunctions.Where(static l => l.Event == NamedLuaFunction.EVENT_TYPE_SAVESTATE).ToList()) + try { - lf.Call(name); + foreach (var lf in RegisteredFunctions.Where(static l => l.Event == NamedLuaFunction.EVENT_TYPE_SAVESTATE).ToList()) + { + lf.Call(name); + } + } + catch (Exception e) + { + LogToLuaConsole($"error running function attached by lua function event.onsavestate\nError message: {e.Message}"); } - GuiAPI.ThisIsTheLuaAutounlockHack(); - } - catch (Exception e) - { - GuiAPI.ThisIsTheLuaAutounlockHack(); - LogToLuaConsole($"error running function attached by lua function event.onsavestate\nError message: {e.Message}"); } } public void CallLoadStateEvent(string name) { - try + using (GuiAPI.ThisIsTheLuaAutoUnlockHack()) { - foreach (var lf in RegisteredFunctions.Where(static l => l.Event == NamedLuaFunction.EVENT_TYPE_LOADSTATE).ToList()) + try { - lf.Call(name); + foreach (var lf in RegisteredFunctions.Where(static l => l.Event == NamedLuaFunction.EVENT_TYPE_LOADSTATE).ToList()) + { + lf.Call(name); + } + } + catch (Exception e) + { + LogToLuaConsole($"error running function attached by lua function event.onloadstate\nError message: {e.Message}"); } - GuiAPI.ThisIsTheLuaAutounlockHack(); - } - catch (Exception e) - { - GuiAPI.ThisIsTheLuaAutounlockHack(); - LogToLuaConsole($"error running function attached by lua function event.onloadstate\nError message: {e.Message}"); } } public void CallFrameBeforeEvent() { if (IsUpdateSupressed) return; - try + + using (GuiAPI.ThisIsTheLuaAutoUnlockHack()) { - foreach (var lf in RegisteredFunctions.Where(static l => l.Event == NamedLuaFunction.EVENT_TYPE_PREFRAME).ToList()) + try { - lf.Call(); + foreach (var lf in RegisteredFunctions.Where(static l => l.Event == NamedLuaFunction.EVENT_TYPE_PREFRAME).ToList()) + { + lf.Call(); + } + } + catch (Exception e) + { + LogToLuaConsole($"error running function attached by lua function event.onframestart\nError message: {e.Message}"); } - GuiAPI.ThisIsTheLuaAutounlockHack(); - } - catch (Exception e) - { - GuiAPI.ThisIsTheLuaAutounlockHack(); - LogToLuaConsole($"error running function attached by lua function event.onframestart\nError message: {e.Message}"); } } public void CallFrameAfterEvent() { if (IsUpdateSupressed) return; - try + + using (GuiAPI.ThisIsTheLuaAutoUnlockHack()) { - foreach (var lf in RegisteredFunctions.Where(static l => l.Event == NamedLuaFunction.EVENT_TYPE_POSTFRAME).ToList()) + try { - lf.Call(); + foreach (var lf in RegisteredFunctions.Where(static l => l.Event == NamedLuaFunction.EVENT_TYPE_POSTFRAME).ToList()) + { + lf.Call(); + } + } + catch (Exception e) + { + LogToLuaConsole($"error running function attached by lua function event.onframeend\nError message: {e.Message}"); } - GuiAPI.ThisIsTheLuaAutounlockHack(); - } - catch (Exception e) - { - GuiAPI.ThisIsTheLuaAutounlockHack(); - LogToLuaConsole($"error running function attached by lua function event.onframeend\nError message: {e.Message}"); } } public void CallExitEvent(LuaFile lf) { - foreach (var exitCallback in RegisteredFunctions - .Where(l => l.Event == NamedLuaFunction.EVENT_TYPE_ENGINESTOP - && (l.LuaFile.Path == lf.Path || ReferenceEquals(l.LuaFile.Thread, lf.Thread))) - .ToList()) + using (GuiAPI.ThisIsTheLuaAutoUnlockHack()) { - exitCallback.Call(); + foreach (var exitCallback in RegisteredFunctions + .Where(l => l.Event == NamedLuaFunction.EVENT_TYPE_ENGINESTOP + && (l.LuaFile.Path == lf.Path || ReferenceEquals(l.LuaFile.Thread, lf.Thread))) + .ToList()) + { + exitCallback.Call(); + } } - GuiAPI.ThisIsTheLuaAutounlockHack(); } public void Close() @@ -319,31 +327,31 @@ namespace BizHawk.Client.EmuHawk public (bool WaitForFrame, bool Terminated) ResumeScript(LuaFile lf) { - _currThread = lf.Thread; - - try + using (GuiAPI.ThisIsTheLuaAutoUnlockHack()) { - LuaLibraryBase.SetCurrentThread(lf); + _currThread = lf.Thread; - var execResult = _currThread.Resume(); - GuiAPI.ThisIsTheLuaAutounlockHack(); + try + { + LuaLibraryBase.SetCurrentThread(lf); - _currThread = null; - var result = execResult == KeraLua.LuaStatus.OK - ? (WaitForFrame: false, Terminated: true) // terminated - : (WaitForFrame: FrameAdvanceRequested, Terminated: false); // yielded + var execResult = _currThread.Resume(); - FrameAdvanceRequested = false; - return result; - } - catch (Exception) - { - GuiAPI.ThisIsTheLuaAutounlockHack(); - throw; - } - finally - { - LuaLibraryBase.ClearCurrentThread(); + _currThread = null; + var result = execResult switch + { + KeraLua.LuaStatus.OK => (WaitForFrame: false, Terminated: true), + KeraLua.LuaStatus.Yield => (WaitForFrame: FrameAdvanceRequested, Terminated: false), + _ => throw new InvalidOperationException($"{nameof(_currThread.Resume)}() returned {execResult}?") + }; + + FrameAdvanceRequested = false; + return result; + } + finally + { + LuaLibraryBase.ClearCurrentThread(); + } } } diff --git a/src/BizHawk.Tests/Client.Common/lua/LuaTests.cs b/src/BizHawk.Tests/Client.Common/lua/LuaTests.cs index 5a6cbe59a6..ae0c1d9cc7 100644 --- a/src/BizHawk.Tests/Client.Common/lua/LuaTests.cs +++ b/src/BizHawk.Tests/Client.Common/lua/LuaTests.cs @@ -591,7 +591,9 @@ namespace BizHawk.Tests.Client.Common.Lua public void Net_Return_Char() { ReturnValue = 'a'; - Assert.IsTrue((bool)LuaInstance.DoString($"return return_char() == {(byte)'a'}")[0]); + Assert.IsTrue((bool)LuaInstance.DoString($"return return_char() == {(ushort)'a'}")[0]); + ReturnValue = 'こ'; + Assert.IsTrue((bool)LuaInstance.DoString($"return return_char() == {(ushort)'こ'}")[0]); } [TestMethod] @@ -612,7 +614,7 @@ namespace BizHawk.Tests.Client.Common.Lua public void Net_Return_Color() { ReturnValue = ExpectedValue = Color.Aqua; - LuaInstance.DoString("return pass_color(return_color())"); + LuaInstance.DoString("pass_color(return_color())"); } [TestMethod] @@ -679,16 +681,14 @@ namespace BizHawk.Tests.Client.Common.Lua LuaInstance.DoString("pass_bool(true)"); } - // this doesn't work for some reason - // just results in an exception due to "Invalid arguments to method call" - /*[TestMethod] + [TestMethod] public void Net_Argument_S8() { ExpectedValue = (sbyte)123; LuaInstance.DoString("pass_s8(123)"); ExpectedValue = (sbyte)-123; LuaInstance.DoString("pass_s8(-123)"); - }*/ + } [TestMethod] public void Net_Argument_U8() @@ -772,13 +772,11 @@ namespace BizHawk.Tests.Client.Common.Lua LuaInstance.DoString("pass_decimal(-123.0)"); } - // these don't work either, although these make a bit more sense + // these don't work, although there is reasoning behind this // IntPtr/UIntPtr are meant as handles to "userdata" // so raw integers result in "Invalid arguments to method call" - // not sure why char doesn't work (same exception here) - /* - [TestMethod] + /*[TestMethod] public void Net_Argument_IntPtr() { ExpectedValue = (IntPtr)123; @@ -787,20 +785,21 @@ namespace BizHawk.Tests.Client.Common.Lua LuaInstance.DoString("pass_intptr(-123)"); }*/ - /* - [TestMethod] + /*[TestMethod] public void Net_Argument_UIntPtr() { ExpectedValue = (UIntPtr)123; LuaInstance.DoString("pass_uintptr(123)"); }*/ - /*[TestMethod] + [TestMethod] public void Net_Argument_Char() { ExpectedValue = 'a'; - LuaInstance.DoString($"pass_char({(byte)'a'})"); - }*/ + LuaInstance.DoString($"pass_char({(ushort)'a'})"); + ExpectedValue = 'こ'; + LuaInstance.DoString($"pass_char({(ushort)'こ'})"); + } [TestMethod] public void Net_Argument_String() @@ -816,6 +815,19 @@ namespace BizHawk.Tests.Client.Common.Lua LuaInstance.DoString($"pass_string(\"こんにちは\")"); } + [TestMethod] + public void Net_Argument_String_Implicit_Number_Conversion() + { + ExpectedValue = "123"; + LuaInstance.DoString("pass_string(123)"); + ExpectedValue = "-123"; + LuaInstance.DoString("pass_string(-123)"); + ExpectedValue = "0.321"; + LuaInstance.DoString("pass_string(0.321)"); + ExpectedValue = "-0.321"; + LuaInstance.DoString("pass_string(-0.321)"); + } + [TestMethod] public void Net_Argument_Color() {