From 6e3d55372fa884b40dc40ccd068a9b54f320fae0 Mon Sep 17 00:00:00 2001 From: adelikat Date: Thu, 31 Oct 2013 00:31:25 +0000 Subject: [PATCH] a better way to set up lua libraries, including a proof of concept for callbacks (in this case passing in a method for logging to an output window, but there can be other applications as well) --- .../BizHawk.MultiClient.csproj | 1 + .../tools/Lua/Libraries/EmuLuaLibrary.Bit.cs | 50 +++++++------ .../Lua/Libraries/EmuLuaLibrary.Client.cs | 75 ++++++++++++------- .../Lua/Libraries/EmuLuaLibrary.Console.cs | 31 ++++---- .../tools/Lua/Libraries/EmuLuaLibrary.NES.cs | 44 ++++++----- .../tools/Lua/Libraries/EmuLuaLibrary.SNES.cs | 46 +++++++----- .../tools/Lua/Libraries/EmuLuaLibrary.cs | 49 ++---------- .../tools/Lua/Libraries/LuaLibraryBase.cs | 43 +++++++++++ .../tools/Lua/LuaDocumentation.cs | 36 +++++---- .../tools/Lua/LuaFunctionsForm.cs | 14 ++-- 10 files changed, 221 insertions(+), 168 deletions(-) create mode 100644 BizHawk.MultiClient/tools/Lua/Libraries/LuaLibraryBase.cs diff --git a/BizHawk.MultiClient/BizHawk.MultiClient.csproj b/BizHawk.MultiClient/BizHawk.MultiClient.csproj index 57782b02fc..212b1b9cb7 100644 --- a/BizHawk.MultiClient/BizHawk.MultiClient.csproj +++ b/BizHawk.MultiClient/BizHawk.MultiClient.csproj @@ -460,6 +460,7 @@ + Component diff --git a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Bit.cs b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Bit.cs index 8a0219272b..9558634460 100644 --- a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Bit.cs +++ b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Bit.cs @@ -2,61 +2,67 @@ namespace BizHawk.MultiClient { - public static class BitLuaLibrary + public class BitLuaLibrary : LuaLibraryBase { - public static string Name = "bit"; - public static string[] Functions = new[] + public override string Name { get { return "bit"; } } + public override string[] Functions { - "band", - "bnot", - "bor", - "bxor", - "lshift", - "rol", - "ror", - "rshift", - }; + get + { + return new[] + { + "band", + "bnot", + "bor", + "bxor", + "lshift", + "rol", + "ror", + "rshift", + }; + } + } public static uint bit_band(object val, object amt) { - return (uint)(LuaCommon.LuaInt(val) & LuaCommon.LuaInt(amt)); + return (uint)(LuaInt(val) & LuaInt(amt)); } public static uint bit_bnot(object val) { - return (uint)(~LuaCommon.LuaInt(val)); + return (uint)(~LuaInt(val)); } public static uint bit_bor(object val, object amt) { - return (uint)(LuaCommon.LuaInt(val) | LuaCommon.LuaInt(amt)); + return (uint)(LuaInt(val) | LuaInt(amt)); } public static uint bit_bxor(object val, object amt) { - return (uint)(LuaCommon.LuaInt(val) ^ LuaCommon.LuaInt(amt)); + return (uint)(LuaInt(val) ^ LuaInt(amt)); } public static uint bit_lshift(object val, object amt) { - return (uint)(LuaCommon.LuaInt(val) << LuaCommon.LuaInt(amt)); + return (uint)(LuaInt(val) << LuaInt(amt)); } public static uint bit_rol(object val, object amt) { - return (uint)((LuaCommon.LuaInt(val) << LuaCommon.LuaInt(amt)) - | (LuaCommon.LuaInt(val) >> (32 - LuaCommon.LuaInt(amt)))); + return (uint)((LuaInt(val) << LuaInt(amt)) + | (LuaInt(val) >> (32 - LuaInt(amt)))); } public static uint bit_ror(object val, object amt) { - return (uint)((LuaCommon.LuaInt(val) >> LuaCommon.LuaInt(amt)) - | (LuaCommon.LuaInt(val) << (32 - LuaCommon.LuaInt(amt)))); + return (uint)((LuaInt(val) >> LuaInt(amt)) + | (LuaInt(val) << (32 - LuaInt(amt)))); } public static uint bit_rshift(object val, object amt) { - return (uint)(LuaCommon.LuaInt(val) >> LuaCommon.LuaInt(amt)); + return (uint)(LuaInt(val) >> LuaInt(amt)); } } } diff --git a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Client.cs b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Client.cs index 703239a86b..61806c612e 100644 --- a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Client.cs +++ b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Client.cs @@ -3,33 +3,49 @@ using BizHawk.Client.Common; namespace BizHawk.MultiClient { - public static class MultiClientLuaLibrary + public class MultiClientLuaLibrary : LuaLibraryBase { - public static string Name = "client"; - public static string[] Functions = new[] + public MultiClientLuaLibrary(Action logOutputCallback) + : this() { - "closerom", - "getwindowsize", - "opencheats", - "openhexeditor", - "openramwatch", - "openramsearch", - "openrom", - "opentasstudio", - "opentoolbox", - "opentracelogger", - "pause_av", - "reboot_core", - "screenheight", - "screenshot", - "screenshottoclipboard", - "screenwidth", - "setscreenshotosd", - "setwindowsize", - "unpause_av", - "xpos", - "ypos", - }; + LogOutputCallback = logOutputCallback; + } + + public MultiClientLuaLibrary() : base() { } + + public override string Name { get { return "client"; } } + public override string[] Functions + { + get + { + return new [] + { + "closerom", + "getwindowsize", + "opencheats", + "openhexeditor", + "openramwatch", + "openramsearch", + "openrom", + "opentasstudio", + "opentoolbox", + "opentracelogger", + "pause_av", + "reboot_core", + "screenheight", + "screenshot", + "screenshottoclipboard", + "screenwidth", + "setscreenshotosd", + "setwindowsize", + "unpause_av", + "xpos", + "ypos", + }; + } + } + + public Action LogOutputCallback = null; public static void client_closerom() { @@ -123,7 +139,7 @@ namespace BizHawk.MultiClient return GlobalWinF.RenderPanel.NativeSize.Width; } - public static void client_setwindowsize(object window_size) + public void client_setwindowsize(object window_size) { try { @@ -137,12 +153,15 @@ namespace BizHawk.MultiClient } else { - ConsoleLuaLibrary.console_log("Invalid window size"); + if (LogOutputCallback != null) + { + LogOutputCallback("Invalid window size"); + } } } catch { - ConsoleLuaLibrary.console_log("Invalid window size"); + LogOutputCallback("Invalid window size"); } } diff --git a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Console.cs b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Console.cs index 2b0f456267..91f6fa2ba6 100644 --- a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Console.cs +++ b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.Console.cs @@ -6,16 +6,22 @@ using LuaInterface; namespace BizHawk.MultiClient { - public static class ConsoleLuaLibrary + public class ConsoleLuaLibrary : LuaLibraryBase { - public static string Name = "console"; - public static string[] Functions = new[] + public override string Name { get { return "console"; } } + public override string[] Functions { - "clear", - "getluafunctionslist", - "log", - "output", - }; + get + { + return new[] + { + "clear", + "getluafunctionslist", + "log", + "output", + }; + } + } public static void console_clear() { @@ -24,13 +30,12 @@ namespace BizHawk.MultiClient public static string console_getluafunctionslist() { - string list = ""; - foreach (LuaDocumentation.LibraryFunction l in GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList) + StringBuilder list = new StringBuilder(); + foreach (var function in GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList) { - list += l.name + "\n"; + list.AppendLine(function.Name); } - - return list; + return list.ToString(); } public static void console_log(object lua_input) diff --git a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.NES.cs b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.NES.cs index bdc7cca640..2405f77f35 100644 --- a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.NES.cs +++ b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.NES.cs @@ -4,25 +4,31 @@ using BizHawk.Emulation.Consoles.Nintendo; namespace BizHawk.MultiClient { - public static class NESLuaLibrary + public class NESLuaLibrary : LuaLibraryBase { - public static string Name = "nes"; - public static string[] Functions = new[] + public override string Name { get { return "nes"; } } + public override string[] Functions { - "addgamegenie", - "getallowmorethaneightsprites", - "getbottomscanline", - "getclipleftandright", - "getdispbackground", - "getdispsprites", - "gettopscanline", - "removegamegenie", - "setallowmorethaneightsprites", - "setclipleftandright", - "setdispbackground", - "setdispsprites", - "setscanlines", - }; + get + { + return new[] + { + "addgamegenie", + "getallowmorethaneightsprites", + "getbottomscanline", + "getclipleftandright", + "getdispbackground", + "getdispsprites", + "gettopscanline", + "removegamegenie", + "setallowmorethaneightsprites", + "setclipleftandright", + "setdispbackground", + "setdispsprites", + "setscanlines", + }; + } + } public static void nes_addgamegenie(string code) { @@ -145,8 +151,8 @@ namespace BizHawk.MultiClient public static void nes_setscanlines(object top, object bottom, bool pal = false) { - int first = LuaCommon.LuaInt(top); - int last = LuaCommon.LuaInt(bottom); + int first = LuaInt(top); + int last = LuaInt(bottom); if (first > 127) { first = 127; diff --git a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.SNES.cs b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.SNES.cs index 700b15b2f8..1c049a38ba 100644 --- a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.SNES.cs +++ b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.SNES.cs @@ -2,28 +2,34 @@ namespace BizHawk.MultiClient { - public static class SNESLuaLibrary + public class SNESLuaLibrary : LuaLibraryBase { - public static string Name = "snes"; - public static string[] Functions = new[] + public override string Name { get { return "snes"; } } + public override string[] Functions { - "getlayer_bg_1", - "getlayer_bg_2", - "getlayer_bg_3", - "getlayer_bg_4", - "getlayer_obj_1", - "getlayer_obj_2", - "getlayer_obj_3", - "getlayer_obj_4", - "setlayer_bg_1", - "setlayer_bg_2", - "setlayer_bg_3", - "setlayer_bg_4", - "setlayer_obj_1", - "setlayer_obj_2", - "setlayer_obj_3", - "setlayer_obj_4", - }; + get + { + return new[] + { + "getlayer_bg_1", + "getlayer_bg_2", + "getlayer_bg_3", + "getlayer_bg_4", + "getlayer_obj_1", + "getlayer_obj_2", + "getlayer_obj_3", + "getlayer_obj_4", + "setlayer_bg_1", + "setlayer_bg_2", + "setlayer_bg_3", + "setlayer_bg_4", + "setlayer_obj_1", + "setlayer_obj_2", + "setlayer_obj_3", + "setlayer_obj_4", + }; + } + } public static bool snes_getlayer_bg_1() { diff --git a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.cs b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.cs index a9d15a1019..4a58c66d46 100644 --- a/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.cs +++ b/BizHawk.MultiClient/tools/Lua/Libraries/EmuLuaLibrary.cs @@ -231,50 +231,11 @@ namespace BizHawk.MultiClient { lua.RegisterFunction("print", this, GetType().GetMethod("print")); - lua.NewTable("bit"); - foreach (var funcName in BitLuaLibrary.Functions) - { - string libName = BitLuaLibrary.Name + "." + funcName; - var method = (typeof(BitLuaLibrary)).GetMethod(BitLuaLibrary.Name + "_" + funcName); - lua.RegisterFunction(libName, this, method); - Docs.Add(BitLuaLibrary.Name, funcName, method); - } - - lua.NewTable("client"); - foreach (var funcName in MultiClientLuaLibrary.Functions) - { - string libName = MultiClientLuaLibrary.Name + "." + funcName; - var method = (typeof(MultiClientLuaLibrary)).GetMethod(MultiClientLuaLibrary.Name + "_" + funcName); - lua.RegisterFunction(libName, this, method); - Docs.Add(MultiClientLuaLibrary.Name, funcName, method); - } - - lua.NewTable("console"); - foreach (var funcName in ConsoleLuaLibrary.Functions) - { - string libName = ConsoleLuaLibrary.Name + "." + funcName; - var method = (typeof(ConsoleLuaLibrary)).GetMethod(ConsoleLuaLibrary.Name + "_" + funcName); - lua.RegisterFunction(libName, this, method); - Docs.Add(ConsoleLuaLibrary.Name, funcName, method); - } - - lua.NewTable("nes"); - foreach (var funcName in NESLuaLibrary.Functions) - { - string libName = NESLuaLibrary.Name + "." + funcName; - var method = (typeof(NESLuaLibrary)).GetMethod(NESLuaLibrary.Name + "_" + funcName); - lua.RegisterFunction(libName, this, method); - Docs.Add(NESLuaLibrary.Name, funcName, method); - } - - lua.NewTable("snes"); - foreach (var funcName in SNESLuaLibrary.Functions) - { - string libName = SNESLuaLibrary.Name + "." + funcName; - var method = (typeof(SNESLuaLibrary)).GetMethod(SNESLuaLibrary.Name + "_" + funcName); - lua.RegisterFunction(libName, this, method); - Docs.Add(SNESLuaLibrary.Name, funcName, method); - } + new BitLuaLibrary().LuaRegister(lua, Docs); + new MultiClientLuaLibrary(ConsoleLuaLibrary.console_log).LuaRegister(lua, Docs); + new ConsoleLuaLibrary().LuaRegister(lua, Docs); + new NESLuaLibrary().LuaRegister(lua, Docs); + new SNESLuaLibrary().LuaRegister(lua, Docs); lua.NewTable("gui"); foreach (string t in GuiFunctions) diff --git a/BizHawk.MultiClient/tools/Lua/Libraries/LuaLibraryBase.cs b/BizHawk.MultiClient/tools/Lua/Libraries/LuaLibraryBase.cs new file mode 100644 index 0000000000..42af94d7b0 --- /dev/null +++ b/BizHawk.MultiClient/tools/Lua/Libraries/LuaLibraryBase.cs @@ -0,0 +1,43 @@ +using System; + +using LuaInterface; + +namespace BizHawk.MultiClient +{ + public abstract class LuaLibraryBase + { + public abstract string Name { get; } + public abstract string[] Functions { get; } + + public virtual void LuaRegister(Lua lua, ILuaDocumentation docs = null) + { + lua.NewTable(Name); + foreach (string methodName in Functions) + { + string func = Name + "." + methodName; + var method = GetType().GetMethod(Name + "_" + methodName); + + lua.RegisterFunction( + Name + "." + methodName, + this, + GetType().GetMethod(Name + "_" + methodName) + ); + + if (docs != null) + { + docs.Add(Name, methodName, method); + } + } + } + + protected static int LuaInt(object lua_arg) + { + return Convert.ToInt32((double)lua_arg); + } + + protected static uint LuaUInt(object lua_arg) + { + return Convert.ToUInt32((double)lua_arg); + } + } +} diff --git a/BizHawk.MultiClient/tools/Lua/LuaDocumentation.cs b/BizHawk.MultiClient/tools/Lua/LuaDocumentation.cs index 8397789852..e4da749a54 100644 --- a/BizHawk.MultiClient/tools/Lua/LuaDocumentation.cs +++ b/BizHawk.MultiClient/tools/Lua/LuaDocumentation.cs @@ -1,11 +1,17 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; namespace BizHawk.MultiClient { - public class LuaDocumentation + public interface ILuaDocumentation + { + void Add(string method_lib, string method_name, System.Reflection.MethodInfo method); + } + + public class LuaDocumentation : ILuaDocumentation { public List FunctionList = new List(); @@ -22,7 +28,7 @@ namespace BizHawk.MultiClient public void Sort() { - FunctionList = FunctionList.OrderBy(x => x.library).ThenBy(x => x.name).ToList(); + FunctionList = FunctionList.OrderBy(x => x.Library).ThenBy(x => x.Name).ToList(); } public List GetLibraryList() @@ -30,7 +36,7 @@ namespace BizHawk.MultiClient HashSet libs = new HashSet(); foreach (LibraryFunction function in FunctionList) { - libs.Add(function.library); + libs.Add(function.Library); } return libs.ToList(); @@ -38,27 +44,27 @@ namespace BizHawk.MultiClient public List GetFunctionsByLibrary(string library) { - return (from t in FunctionList where t.library == library select t.name).ToList(); + return (from t in FunctionList where t.Library == library select t.Name).ToList(); } public class LibraryFunction { public LibraryFunction(string method_lib, string method_name, System.Reflection.MethodInfo method) { - library = method_lib; - name = method_name; + Library = method_lib; + Name = method_name; System.Reflection.ParameterInfo[] info = method.GetParameters(); foreach (System.Reflection.ParameterInfo p in info) { - parameters.Add(p.ToString()); + Parameters.Add(p.ToString()); } return_type = method.ReturnType.ToString(); } - public string library = ""; - public string name = ""; - public List parameters = new List(); - public string return_type = ""; + public string Library = String.Empty; + public string Name = String.Empty; + public List Parameters = new List(); + public string return_type = String.Empty; public string ParameterList { @@ -66,11 +72,11 @@ namespace BizHawk.MultiClient { StringBuilder list = new StringBuilder(); list.Append('('); - for (int i = 0; i < parameters.Count; i++) + for (int i = 0; i < Parameters.Count; i++) { - string param = parameters[i].Replace("System", "").Replace("Object", "").Replace(" ", "").Replace(".", "").Replace("LuaInterface", ""); + string param = Parameters[i].Replace("System", "").Replace("Object", "").Replace(" ", "").Replace(".", "").Replace("LuaInterface", ""); list.Append(param); - if (i < parameters.Count - 1) + if (i < Parameters.Count - 1) { list.Append(','); } diff --git a/BizHawk.MultiClient/tools/Lua/LuaFunctionsForm.cs b/BizHawk.MultiClient/tools/Lua/LuaFunctionsForm.cs index 5e3bbc831d..e9bcd57b2e 100644 --- a/BizHawk.MultiClient/tools/Lua/LuaFunctionsForm.cs +++ b/BizHawk.MultiClient/tools/Lua/LuaFunctionsForm.cs @@ -26,8 +26,8 @@ namespace BizHawk.MultiClient foreach (LuaDocumentation.LibraryFunction l in GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList) { ListViewItem item = new ListViewItem {Text = l.ReturnType}; - item.SubItems.Add(l.library + "."); - item.SubItems.Add(l.name); + item.SubItems.Add(l.Library + "."); + item.SubItems.Add(l.Name); item.SubItems.Add(l.ParameterList); FunctionView.Items.Add(item); } @@ -44,10 +44,10 @@ namespace BizHawk.MultiClient GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderByDescending(x => x.ReturnType).ToList(); break; case 1: //Library - GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderByDescending(x => x.library).ToList(); + GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderByDescending(x => x.Library).ToList(); break; case 2: //Name - GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderByDescending(x => x.name).ToList(); + GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderByDescending(x => x.Name).ToList(); break; case 3: //Parameters GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderByDescending(x => x.ParameterList).ToList(); @@ -62,10 +62,10 @@ namespace BizHawk.MultiClient GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderBy(x => x.ReturnType).ToList(); break; case 1: //Library - GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderBy(x => x.library).ToList(); + GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderBy(x => x.Library).ToList(); break; case 2: //Name - GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderBy(x => x.name).ToList(); + GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderBy(x => x.Name).ToList(); break; case 3: //Parameters GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList.OrderBy(x => x.ParameterList).ToList(); @@ -133,7 +133,7 @@ namespace BizHawk.MultiClient foreach (int index in indexes) { var library_function = GlobalWinF.MainForm.LuaConsole1.LuaImp.Docs.FunctionList[index]; - sb.Append(library_function.library).Append('.').Append(library_function.name).Append("()\n"); + sb.Append(library_function.Library).Append('.').Append(library_function.Name).Append("()\n"); } if (sb.Length > 0)