diff --git a/BizHawk.Client.Common/lua/EmuLuaLibrary.String.cs b/BizHawk.Client.Common/lua/EmuLuaLibrary.String.cs index cb291111d9..bdc5d82275 100644 --- a/BizHawk.Client.Common/lua/EmuLuaLibrary.String.cs +++ b/BizHawk.Client.Common/lua/EmuLuaLibrary.String.cs @@ -1,6 +1,5 @@ using System; using System.ComponentModel; -using System.Linq; using NLua; diff --git a/BizHawk.Client.Common/lua/LuaHelper.cs b/BizHawk.Client.Common/lua/LuaHelper.cs index 52864be0d2..918fd02aa6 100644 --- a/BizHawk.Client.Common/lua/LuaHelper.cs +++ b/BizHawk.Client.Common/lua/LuaHelper.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using System.Reflection; using NLua; @@ -8,6 +7,8 @@ namespace BizHawk.Client.Common { public static class LuaExtensions { + public static LuaTable EnumerateToLuaTable(this IEnumerable list, Lua lua) => list.ToList().ToLuaTable(lua); + public static LuaTable ToLuaTable(this IList list, Lua lua, int indexFrom = 0) { var table = lua.NewTable(); @@ -34,26 +35,16 @@ namespace BizHawk.Client.Common public static LuaTable TableFromObject(this Lua lua, object obj) { var table = lua.NewTable(); - - var type = obj.GetType(); - - var methods = type.GetMethods(); - foreach (var method in methods) + foreach (var method in obj.GetType().GetMethods()) { - if (method.IsPublic) - { - string luaName = ""; // Empty will default to the actual method name; - - var luaMethodAttr = (LuaMethodAttribute)method.GetCustomAttributes(typeof(LuaMethodAttribute)).FirstOrDefault(); - if (luaMethodAttr != null) - { - luaName = luaMethodAttr.Name; - } - - table[method.Name] = lua.RegisterFunction(luaName, obj, method); - } + if (!method.IsPublic) continue; + var foundAttrs = method.GetCustomAttributes(typeof(LuaMethodAttribute), false); + table[method.Name] = lua.RegisterFunction( + foundAttrs.Length == 0 ? string.Empty : ((LuaMethodAttribute) foundAttrs[0]).Name, // empty string will default to the actual method name + obj, + method + ); } - return table; } } diff --git a/BizHawk.Client.Common/lua/LuaLibraryBase.cs b/BizHawk.Client.Common/lua/LuaLibraryBase.cs index bc044f5652..8538e26e33 100644 --- a/BizHawk.Client.Common/lua/LuaLibraryBase.cs +++ b/BizHawk.Client.Common/lua/LuaLibraryBase.cs @@ -1,6 +1,5 @@ using System; using System.Drawing; -using System.Linq; using System.Threading; using NLua; @@ -86,19 +85,11 @@ namespace BizHawk.Client.Common public void LuaRegister(Type callingLibrary, LuaDocumentation docs = null) { Lua.NewTable(Name); - - var luaAttr = typeof(LuaMethodAttribute); - - var methods = GetType() - .GetMethods() - .Where(m => m.GetCustomAttributes(luaAttr, false).Any()); - - foreach (var method in methods) + foreach (var method in GetType().GetMethods()) { - var luaMethodAttr = (LuaMethodAttribute)method.GetCustomAttributes(luaAttr, false).First(); - var luaName = $"{Name}.{luaMethodAttr.Name}"; - Lua.RegisterFunction(luaName, this, method); - + var foundAttrs = method.GetCustomAttributes(typeof(LuaMethodAttribute), false); + if (foundAttrs.Length == 0) continue; + Lua.RegisterFunction($"{Name}.{((LuaMethodAttribute) foundAttrs[0]).Name}", this, method); docs?.Add(new LibraryFunction(Name, callingLibrary.Description(), method)); } } diff --git a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Client.cs b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Client.cs index b2bfd96b62..48894b3672 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Client.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Client.cs @@ -417,16 +417,7 @@ namespace BizHawk.Client.EmuHawk [LuaMethodExample("local nlcliget = client.getavailabletools( );")] [LuaMethod("getavailabletools", "Returns a list of the tools currently open")] - public LuaTable GetAvailableTools() - { - var xx = GlobalWin.Tools.AvailableTools.ToList(); - var x = GlobalWin.Tools.AvailableTools - .Select(t => t.Name.ToLower()) - .ToList() - .ToLuaTable(Lua); - - return x; - } + public LuaTable GetAvailableTools() => GlobalWin.Tools.AvailableTools.Select(tool => tool.Name.ToLower()).EnumerateToLuaTable(Lua); [LuaMethodExample("local nlcliget = client.gettool( \"Tool name\" );")] [LuaMethod("gettool", "Returns an object that represents a tool of the given name (not case sensitive). If the tool is not open, it will be loaded if available. Use gettools to get a list of names")] diff --git a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Console.cs b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Console.cs index 4639245f21..248a74442e 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Console.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Console.cs @@ -71,6 +71,26 @@ namespace BizHawk.Client.EmuHawk // Outputs the given object to the output box on the Lua Console dialog. Note: Can accept a LuaTable private static void LogWithSeparator(string separator, string terminator, params object[] outputs) { + static string SerialiseTable(LuaTable lti) + { + var keyObjs = lti.Keys; + var valueObjs = lti.Values; + if (keyObjs.Count != valueObjs.Count) throw new IndexOutOfRangeException("each value must be paired with one key, they differ in number"); + var values = new List(keyObjs.Count); + var kvpIndex = 0; + foreach (var valueObj in valueObjs) values[kvpIndex++] = valueObj; + return string.Concat(keyObjs.Cast() + .Select((kObj, i) => $"\"{kObj}\": \"{values[i]}\"\n") + .OrderBy(s => s) + ); + } + + static void SerialiseAndWrite(object output) => GlobalWin.Tools.LuaConsole.WriteToOutputWindow( + output is LuaTable table + ? SerialiseTable(table) + : output?.ToString() ?? "nil" + ); + if (!GlobalWin.Tools.Has()) { return; @@ -82,55 +102,11 @@ namespace BizHawk.Client.EmuHawk return; } - for (var outIndex = 0; outIndex < outputs.Length; outIndex++) + SerialiseAndWrite(outputs[0]); + for (int outIndex = 1, indexAfterLast = outputs.Length; outIndex != indexAfterLast; outIndex++) { - var output = outputs[outIndex]; - - if (outIndex != 0) - { - GlobalWin.Tools.LuaConsole.WriteToOutputWindow(separator); - } - - if (output == null) - { - GlobalWin.Tools.LuaConsole.WriteToOutputWindow("nil"); - } - else - { - if (output is LuaTable lti) - { - var sb = new StringBuilder(); - - var keys = (from object key in lti.Keys select key.ToString()).ToList(); - var values = (from object value in lti.Values select value.ToString()).ToList(); - - var kvps = new List>(); - for (var i = 0; i < keys.Count; i++) - { - if (i < values.Count) - { - kvps.Add(new KeyValuePair(keys[i], values[i])); - } - } - - foreach (var kvp in kvps.OrderBy(x => x.Key)) - { - sb - .Append("\"") - .Append(kvp.Key) - .Append("\": \"") - .Append(kvp.Value) - .Append("\"") - .AppendLine(); - } - - GlobalWin.Tools.LuaConsole.WriteToOutputWindow(sb.ToString()); - } - else - { - GlobalWin.Tools.LuaConsole.WriteToOutputWindow(output.ToString()); - } - } + GlobalWin.Tools.LuaConsole.WriteToOutputWindow(separator); + SerialiseAndWrite(outputs[outIndex]); } if (!string.IsNullOrEmpty(terminator)) diff --git a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Tastudio.cs b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Tastudio.cs index 0294eda60f..20ba2565ad 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Tastudio.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.Tastudio.cs @@ -160,22 +160,7 @@ namespace BizHawk.Client.EmuHawk [LuaMethodExample("local nltasget = tastudio.getselection( );")] [LuaMethod("getselection", "gets the currently selected frames")] - public LuaTable GetSelection() - { - LuaTable table = Lua.NewTable(); - - if (Engaged()) - { - var selection = Tastudio.GetSelection().ToList(); - - for (int i = 0; i < selection.Count; i++) - { - table[i] = selection[i]; - } - } - - return table; - } + public LuaTable GetSelection() => Engaged() ? Tastudio.GetSelection().EnumerateToLuaTable(Lua) : Lua.NewTable(); [LuaMethodExample("")] [LuaMethod("submitinputchange", "")] @@ -377,8 +362,7 @@ namespace BizHawk.Client.EmuHawk b.Frame, Text = b.UserText }) - .ToList() - .ToLuaTable(Lua); + .EnumerateToLuaTable(Lua); } return Lua.NewTable(); @@ -392,29 +376,24 @@ namespace BizHawk.Client.EmuHawk if (Engaged()) { - if (Tastudio.CurrentTasMovie.Branches.Any(b => b.UniqueIdentifier.ToString() == branchId)) + var branch = Tastudio.CurrentTasMovie.Branches.FirstOrDefault(b => b.UniqueIdentifier.ToString() == branchId); + if (branch != null && frame < branch.InputLog.Count) { - var branch = Tastudio.CurrentTasMovie.Branches.First(b => b.UniqueIdentifier.ToString() == branchId); - if (frame < branch.InputLog.Count) + var adapter = new Bk2ControllerAdapter { - var input = branch.InputLog[frame]; + Definition = Global.MovieSession.MovieControllerAdapter.Definition + }; - var adapter = new Bk2ControllerAdapter - { - Definition = Global.MovieSession.MovieControllerAdapter.Definition - }; + adapter.SetControllersAsMnemonic(branch.InputLog[frame]); - adapter.SetControllersAsMnemonic(input); + foreach (var button in adapter.Definition.BoolButtons) + { + table[button] = adapter.IsPressed(button); + } - foreach (var button in adapter.Definition.BoolButtons) - { - table[button] = adapter.IsPressed(button); - } - - foreach (var button in adapter.Definition.FloatControls) - { - table[button] = adapter.GetFloat(button); - } + foreach (var button in adapter.Definition.FloatControls) + { + table[button] = adapter.GetFloat(button); } } } diff --git a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.cs b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.cs index d4be3dfe35..10943833e5 100644 --- a/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.cs +++ b/BizHawk.Client.EmuHawk/tools/Lua/Libraries/EmuLuaLibrary.cs @@ -45,20 +45,9 @@ namespace BizHawk.Client.EmuHawk Docs.Clear(); // Register lua libraries - var libs = Assembly - .Load("BizHawk.Client.Common") - .GetTypes() - .Where(t => typeof(LuaLibraryBase).IsAssignableFrom(t)) - .Where(t => t.IsSealed) - .Where(t => ServiceInjector.IsAvailable(serviceProvider, t)) - .Concat(Assembly - .GetAssembly(typeof(EmuLuaLibrary)) - .GetTypes() - .Where(t => typeof(LuaLibraryBase).IsAssignableFrom(t)) - .Where(t => t.IsSealed) - .Where(t => ServiceInjector.IsAvailable(serviceProvider, t))); - - foreach (var lib in libs) + foreach (var lib in Assembly.Load("BizHawk.Client.Common").GetTypes() + .Concat(Assembly.GetAssembly(typeof(EmuLuaLibrary)).GetTypes()) + .Where(t => typeof(LuaLibraryBase).IsAssignableFrom(t) && t.IsSealed && ServiceInjector.IsAvailable(serviceProvider, t))) { bool addLibrary = true; var attributes = lib.GetCustomAttributes(typeof(LuaLibraryAttribute), false); @@ -90,13 +79,12 @@ namespace BizHawk.Client.EmuHawk // Add LuaCanvas to Docs Type luaCanvas = typeof(LuaCanvas); - var methods = luaCanvas - .GetMethods() - .Where(m => m.GetCustomAttributes(typeof(LuaMethodAttribute), false).Any()); - - foreach (var method in methods) + foreach (var method in luaCanvas.GetMethods()) { - Docs.Add(new LibraryFunction(nameof(LuaCanvas), luaCanvas.Description(), method)); + if (method.GetCustomAttributes(typeof(LuaMethodAttribute), false).Length != 0) + { + Docs.Add(new LibraryFunction(nameof(LuaCanvas), luaCanvas.Description(), method)); + } } } @@ -122,7 +110,7 @@ namespace BizHawk.Client.EmuHawk public override void StartLuaDrawing() { - if (ScriptList.Any() && GuiLibrary.SurfaceIsNull) + if (ScriptList.Count != 0 && GuiLibrary.SurfaceIsNull) { GuiLibrary.DrawNew("emu"); } @@ -130,7 +118,7 @@ namespace BizHawk.Client.EmuHawk public override void EndLuaDrawing() { - if (ScriptList.Any()) + if (ScriptList.Count != 0) { GuiLibrary.DrawFinish(); }