diff --git a/src/BizHawk.Client.EmuHawk/Api/ApiManager.cs b/src/BizHawk.Client.Common/Api/ApiManager.cs
similarity index 76%
rename from src/BizHawk.Client.EmuHawk/Api/ApiManager.cs
rename to src/BizHawk.Client.Common/Api/ApiManager.cs
index 77e38d440d6..ae0310ab38d 100644
--- a/src/BizHawk.Client.EmuHawk/Api/ApiManager.cs
+++ b/src/BizHawk.Client.Common/Api/ApiManager.cs
@@ -4,27 +4,29 @@
using System.Linq;
using System.Reflection;
-using BizHawk.Client.Common;
using BizHawk.Emulation.Common;
-namespace BizHawk.Client.EmuHawk
+namespace BizHawk.Client.Common
{
public static class ApiManager
{
- private static readonly IReadOnlyList<(Type ImplType, Type InterfaceType, ConstructorInfo Ctor, Type[] CtorTypes)> _apiTypes;
+ private static readonly List<(Type ImplType, Type InterfaceType, ConstructorInfo Ctor, Type[] CtorTypes)> _apiTypes = new();
static ApiManager()
{
- var list = new List<(Type, Type, ConstructorInfo, Type[])>();
- foreach (var implType in ReflectionCache_Biz_Cli_Com.Types.Concat(ReflectionCache.Types)
+ foreach (var implType in ReflectionCache_Biz_Cli_Com.Types
.Where(t => /*t.IsClass &&*/t.IsSealed)) // small optimisation; api impl. types are all sealed classes
{
- var interfaceType = implType.GetInterfaces().FirstOrDefault(t => typeof(IExternalApi).IsAssignableFrom(t) && t != typeof(IExternalApi));
- if (interfaceType == null) continue; // if we couldn't determine what it's implementing, then it's not an api impl. type
- var ctor = implType.GetConstructors().Single();
- list.Add((implType, interfaceType, ctor, ctor.GetParameters().Select(pi => pi.ParameterType).ToArray()));
+ AddApiType(implType);
}
- _apiTypes = list.ToArray();
+ }
+
+ public static void AddApiType(Type type)
+ {
+ var interfaceType = type.GetInterfaces().FirstOrDefault(t => typeof(IExternalApi).IsAssignableFrom(t) && t != typeof(IExternalApi));
+ if (interfaceType == null) return; // if we couldn't determine what it's implementing, then it's not an api impl. type
+ var ctor = type.GetConstructors().Single();
+ _apiTypes.Add((type, interfaceType, ctor, ctor.GetParameters().Select(pi => pi.ParameterType).ToArray()));
}
private static ApiContainer? _container;
@@ -38,7 +40,7 @@ private static ApiContainer Register(
DisplayManagerBase displayManager,
InputManager inputManager,
IMovieSession movieSession,
- ToolManager toolManager,
+ IToolLoader toolManager,
Config config,
IEmulator emulator,
IGameInfo game,
@@ -52,7 +54,7 @@ private static ApiContainer Register(
[typeof(DisplayManagerBase)] = displayManager,
[typeof(InputManager)] = inputManager,
[typeof(IMovieSession)] = movieSession,
- [typeof(ToolManager)] = toolManager,
+ [typeof(IToolLoader)] = toolManager,
[typeof(Config)] = config,
[typeof(IEmulator)] = emulator,
[typeof(IGameInfo)] = game,
@@ -74,7 +76,7 @@ public static IExternalApiProvider Restart(
DisplayManagerBase displayManager,
InputManager inputManager,
IMovieSession movieSession,
- ToolManager toolManager,
+ IToolLoader toolManager,
Config config,
IEmulator emulator,
IGameInfo game,
@@ -92,7 +94,7 @@ public static ApiContainer RestartLua(
DisplayManagerBase displayManager,
InputManager inputManager,
IMovieSession movieSession,
- ToolManager toolManager,
+ IToolLoader toolManager,
Config config,
IEmulator emulator,
IGameInfo game,
diff --git a/src/BizHawk.Client.Common/IMainFormForTools.cs b/src/BizHawk.Client.Common/IMainFormForTools.cs
new file mode 100644
index 00000000000..5212a46cfdd
--- /dev/null
+++ b/src/BizHawk.Client.Common/IMainFormForTools.cs
@@ -0,0 +1,105 @@
+using BizHawk.Bizware.Graphics;
+using BizHawk.Emulation.Common;
+
+namespace BizHawk.Client.Common
+{
+ public interface IMainFormForTools : IDialogController
+ {
+ /// referenced by 3 or more tools
+ CheatCollection CheatList { get; }
+
+ /// referenced by 3 or more tools
+ string CurrentlyOpenRom { get; }
+
+ /// referenced from HexEditor and RetroAchievements
+ LoadRomArgs CurrentlyOpenRomArgs { get; }
+
+ /// only referenced from TAStudio
+ bool EmulatorPaused { get; }
+
+ /// only referenced from PlaybackBox
+ bool HoldFrameAdvance { get; set; }
+
+ /// only referenced from BasicBot
+ bool InvisibleEmulation { get; set; }
+
+ /// only referenced from LuaConsole
+ bool IsTurboing { get; }
+
+ /// only referenced from TAStudio
+ bool IsFastForwarding { get; }
+
+ /// referenced from PlayMovie and TAStudio
+ int? PauseOnFrame { get; set; }
+
+ /// only referenced from PlaybackBox
+ bool PressRewind { get; set; }
+
+ /// referenced from BookmarksBranchesBox and VideoWriterChooserForm
+ BitmapBuffer CaptureOSD();
+
+ /// only referenced from TAStudio
+ void DisableRewind();
+
+ /// only referenced from TAStudio
+ void EnableRewind(bool enabled);
+
+ /// only referenced from TAStudio
+ bool EnsureCoreIsAccurate();
+
+ /// only referenced from TAStudio
+ void FrameAdvance(bool discardApiHawkSurfaces = true);
+
+ /// only referenced from LuaConsole
+ /// Override
+ void FrameBufferResized(bool forceWindowResize = false);
+
+ /// only referenced from BasicBot
+ bool LoadQuickSave(int slot, bool suppressOSD = false);
+
+ /// referenced from MultiDiskBundler and RetroAchievements
+ bool LoadRom(string path, LoadRomArgs args);
+
+ /// only referenced from BookmarksBranchesBox
+ BitmapBuffer MakeScreenshotImage();
+
+ /// referenced from ToolFormBase
+ void MaybePauseFromMenuOpened();
+
+ /// referenced from ToolFormBase
+ void MaybeUnpauseFromMenuClosed();
+
+ /// referenced by 3 or more tools
+ void PauseEmulator();
+
+ /// only referenced from TAStudio
+ bool BlockFrameAdvance { get; set; }
+
+ /// referenced from PlaybackBox and TAStudio
+ void SetMainformMovieInfo();
+
+ /// referenced by 3 or more tools
+ bool StartNewMovie(IMovie movie, bool newMovie);
+
+ /// only referenced from BasicBot
+ void Throttle();
+
+ /// only referenced from TAStudio
+ void TogglePause();
+
+ /// referenced by 3 or more tools
+ void UnpauseEmulator();
+
+ /// only referenced from BasicBot
+ void Unthrottle();
+
+ /// only referenced from LogWindow
+ void UpdateDumpInfo(RomStatus? newStatus = null);
+
+ /// only referenced from BookmarksBranchesBox
+ void UpdateStatusSlots();
+
+ /// only referenced from TAStudio
+ void UpdateWindowTitle();
+ }
+}
diff --git a/src/BizHawk.Client.Common/lua/CommonLibs/ClientLuaLibrary.cs b/src/BizHawk.Client.Common/lua/CommonLibs/ClientLuaLibrary.cs
index 1dfe7c9688f..34edc54e2c2 100644
--- a/src/BizHawk.Client.Common/lua/CommonLibs/ClientLuaLibrary.cs
+++ b/src/BizHawk.Client.Common/lua/CommonLibs/ClientLuaLibrary.cs
@@ -17,6 +17,8 @@ namespace BizHawk.Client.Common
[Description("A library for manipulating the EmuHawk client UI")]
public sealed class ClientLuaLibrary : LuaLibraryBase
{
+ public Lazy AllAPINames { get; set; }
+
[OptionalService]
private IVideoProvider VideoProvider { get; set; }
@@ -111,6 +113,11 @@ public void SeekFrame(int frame)
public int GetApproxFramerate()
=> APIs.EmuClient.GetApproxFramerate();
+ [LuaMethodExample("local stconget = client.getluafunctionslist( );")]
+ [LuaMethod("getluafunctionslist", "returns a list of implemented functions")]
+ public string GetLuaFunctionsList()
+ => AllAPINames.Value;
+
[LuaMethodExample("local incliget = client.gettargetscanlineintensity( );")]
[LuaMethod("gettargetscanlineintensity", "Gets the current scanline intensity setting, used for the scanline display filter")]
public int GetTargetScanlineIntensity()
diff --git a/src/BizHawk.Client.Common/lua/ILuaLibraries.cs b/src/BizHawk.Client.Common/lua/ILuaLibraries.cs
index 6825004aafd..e44a905cd36 100644
--- a/src/BizHawk.Client.Common/lua/ILuaLibraries.cs
+++ b/src/BizHawk.Client.Common/lua/ILuaLibraries.cs
@@ -2,6 +2,8 @@ namespace BizHawk.Client.Common
{
public interface ILuaLibraries
{
+ LuaFile CurrentFile { get; }
+
/// pretty hacky... we don't want a lua script to be able to restart itself by rebooting the core
bool IsRebootingCore { get; set; }
@@ -13,5 +15,7 @@ public interface ILuaLibraries
PathEntryCollection PathEntries { get; }
NLuaTableHelper GetTableHelper();
+
+ void Sandbox(LuaFile luaFile, Action callback, Action exceptionCallback = null);
}
}
\ No newline at end of file
diff --git a/src/BizHawk.Client.Common/lua/INamedLuaFunction.cs b/src/BizHawk.Client.Common/lua/INamedLuaFunction.cs
index 22b1c778b83..30dc884affa 100644
--- a/src/BizHawk.Client.Common/lua/INamedLuaFunction.cs
+++ b/src/BizHawk.Client.Common/lua/INamedLuaFunction.cs
@@ -1,25 +1,27 @@
-using BizHawk.Emulation.Common;
-
namespace BizHawk.Client.Common
{
public interface INamedLuaFunction
{
- Action InputCallback { get; }
-
Guid Guid { get; }
string GuidStr { get; }
- MemoryCallbackDelegate MemCallback { get; }
-
- /// for doom.on_prandom; single param: caller of RNG, per categories in source
- Action RandomCallback { get; }
-
- /// for doom.on_use and doom.on_cross; two params: pointers to activated line and to mobj that triggered it
- Action LineCallback { get; }
-
string Name { get; }
+ ///
+ /// Will be called when the Lua function is unregistered / removed from the list of active callbacks.
+ /// The intended use case is to support callback systems that don't directly support Lua.
+ /// Here's what that looks like:
+ /// 1) A NamedLuaFunction is created and added to it's owner's list of registered functions, as normal with all Lua functions.
+ /// 2) A C# function is created for this specific NamedLuaFunction, which calls the Lua function via and possibly does other related Lua setup and cleanup tasks.
+ /// 3) That C# function is added to the non-Lua callback system.
+ /// 4) is assigned an that removes the C# function from the non-Lua callback.
+ ///
Action OnRemove { get; set; }
+
+ ///
+ /// Calls the Lua function with the given arguments.
+ ///
+ object[] Call(object[] args);
}
}
diff --git a/src/BizHawk.Client.Common/lua/IPrintingLibrary.cs b/src/BizHawk.Client.Common/lua/IPrintingLibrary.cs
new file mode 100644
index 00000000000..77ad10c5242
--- /dev/null
+++ b/src/BizHawk.Client.Common/lua/IPrintingLibrary.cs
@@ -0,0 +1,7 @@
+namespace BizHawk.Client.Common
+{
+ public interface IPrintingLibrary
+ {
+ void Log(params object[] outputs);
+ }
+}
diff --git a/src/BizHawk.Client.Common/lua/IRegisterFunctions.cs b/src/BizHawk.Client.Common/lua/IRegisterFunctions.cs
new file mode 100644
index 00000000000..d15ee1f30f8
--- /dev/null
+++ b/src/BizHawk.Client.Common/lua/IRegisterFunctions.cs
@@ -0,0 +1,7 @@
+namespace BizHawk.Client.Common
+{
+ public interface IRegisterFunctions
+ {
+ LuaLibraryBase.NLFAddCallback CreateAndRegisterNamedFunction { get; set; }
+ }
+}
diff --git a/src/BizHawk.Client.Common/lua/LuaFile.cs b/src/BizHawk.Client.Common/lua/LuaFile.cs
index 0d777f186a9..5e6dc8f5c91 100644
--- a/src/BizHawk.Client.Common/lua/LuaFile.cs
+++ b/src/BizHawk.Client.Common/lua/LuaFile.cs
@@ -1,54 +1,63 @@
-using NLua;
+using System.Collections.Generic;
+using System.Linq;
+
+using NLua;
namespace BizHawk.Client.Common
{
+ ///
+ /// If a owns an instance of this interface, it will not stop until all such instances are removed.
+ /// This is similar to how a script with registered callbacks does not stop until all callbacks are removed.
+ ///
+ public interface IKeepFileRunning : IDisposable { }
+
public class LuaFile
{
- public LuaFile(string path)
+ public LuaFile(string path, Action onFunctionListChange)
{
- Name = "";
Path = path;
- State = RunState.Running;
- FrameWaiting = false;
- }
-
- public LuaFile(string name, string path)
- {
- Name = name;
- Path = path;
- IsSeparator = false;
-
- // the current directory for the lua task will start off wherever the lua file is located
- CurrentDirectory = System.IO.Path.GetDirectoryName(path);
+ State = RunState.Disabled;
+ Functions = new(onFunctionListChange);
}
- private LuaFile(bool isSeparator)
+ private LuaFile(bool isSeparator) : this("", () => { })
{
IsSeparator = isSeparator;
- Name = "";
- Path = "";
- State = RunState.Disabled;
}
public static LuaFile SeparatorInstance => new(true);
- public string Name { get; set; }
public string Path { get; }
public bool Enabled => State != RunState.Disabled;
public bool Paused => State == RunState.Paused;
public bool IsSeparator { get; }
- public LuaThread Thread { get; set; }
+ public LuaThread Thread { get; private set; }
public bool FrameWaiting { get; set; }
- public string CurrentDirectory { get; set; }
+ public bool RunningEventsOnly { get; set; } = false;
+
+ public LuaFunctionList Functions { get; }
+
+ private List _disposables = new();
public enum RunState
{
Disabled,
Running,
Paused,
+ AwaitingStart,
}
- public RunState State { get; set; }
+ public RunState State { get; private set; }
+
+ public void AddDisposable(IDisposable disposable) => _disposables.Add(disposable);
+
+ public void RemoveDisposable(IDisposable disposable) => _disposables.Remove(disposable);
+
+ public bool ShouldKeepRunning()
+ {
+ return _disposables.Exists((d) => d is IKeepFileRunning)
+ || Functions.Any(f => f.Event != NamedLuaFunction.EVENT_TYPE_ENGINESTOP);
+ }
public void Stop()
{
@@ -58,25 +67,40 @@ public void Stop()
}
State = RunState.Disabled;
+
+ foreach (NamedLuaFunction func in Functions
+ .Where(l => l.Event == NamedLuaFunction.EVENT_TYPE_ENGINESTOP)
+ .ToList())
+ {
+ func.Call();
+ }
+ Functions.Clear();
+
+ foreach (IDisposable disposable in _disposables.ToList())
+ disposable.Dispose();
+ _disposables.Clear();
+
Thread.Dispose();
Thread = null;
}
- public void Toggle()
+ public void Start(LuaThread thread)
{
- switch (State)
- {
- case RunState.Paused:
- State = RunState.Running;
- break;
- case RunState.Disabled:
- State = RunState.Running;
- FrameWaiting = false;
- break;
- default:
- State = RunState.Disabled;
- break;
- }
+ if (Thread is not null) throw new InvalidOperationException("Cannot start an already started Lua file.");
+
+ Thread = thread;
+ State = RunState.Running;
+ FrameWaiting = false;
+ RunningEventsOnly = false;
+
+ // Execution will not actually begin until the client calls LuaConsole.ResumeScripts
+ }
+
+ public void ScheduleStart()
+ {
+ if (State != RunState.Disabled) throw new InvalidOperationException("A Lua file that wasn't stopped was scheduled to start.");
+
+ State = RunState.AwaitingStart;
}
public void TogglePause()
diff --git a/src/BizHawk.Client.Common/lua/LuaFileList.cs b/src/BizHawk.Client.Common/lua/LuaFileList.cs
index 15b2493c0a0..fceb0620c44 100644
--- a/src/BizHawk.Client.Common/lua/LuaFileList.cs
+++ b/src/BizHawk.Client.Common/lua/LuaFileList.cs
@@ -36,7 +36,7 @@ public LuaFileList(IReadOnlyCollection collection, Action onChanged)
public void StopAllScripts()
{
- ForEach(lf => lf.State = LuaFile.RunState.Disabled);
+ ForEach(lf => lf.Stop());
}
public new void Clear()
@@ -65,7 +65,7 @@ public void StopAllScripts()
return base.Remove(item);
}
- public bool Load(string path, bool disableOnLoad)
+ public bool Load(string path, bool disableOnLoad, Action onFunctionListChange)
{
var file = new FileInfo(path);
if (!file.Exists)
@@ -91,10 +91,10 @@ public bool Load(string path, bool disableOnLoad)
scriptPath = Path.GetFullPath(Path.Combine(directory ?? "", scriptPath));
}
- Add(new LuaFile(scriptPath)
- {
- State = !disableOnLoad && line.StartsWith('1') ? LuaFile.RunState.Running : LuaFile.RunState.Disabled,
- });
+ LuaFile lf = new LuaFile(scriptPath, onFunctionListChange);
+ Add(lf);
+ if (!disableOnLoad && line.StartsWith('1'))
+ lf.ScheduleStart();
}
}
diff --git a/src/BizHawk.Client.Common/lua/LuaFunctionList.cs b/src/BizHawk.Client.Common/lua/LuaFunctionList.cs
index 780d061af8e..71126508c01 100644
--- a/src/BizHawk.Client.Common/lua/LuaFunctionList.cs
+++ b/src/BizHawk.Client.Common/lua/LuaFunctionList.cs
@@ -1,6 +1,5 @@
using System.Collections;
using System.Collections.Generic;
-using System.Linq;
namespace BizHawk.Client.Common
{
@@ -40,21 +39,6 @@ private bool RemoveInner(NamedLuaFunction function)
return true;
}
- public void RemoveForFile(LuaFile file)
- {
- var functionsToRemove = _functions.Where(l => l.LuaFile.Path == file.Path || ReferenceEquals(l.LuaFile.Thread, file.Thread)).ToList();
-
- foreach (var function in functionsToRemove)
- {
- _ = RemoveInner(function);
- }
-
- if (functionsToRemove.Count != 0)
- {
- Changed();
- }
- }
-
public void Clear()
{
if (Count is 0) return;
diff --git a/src/BizHawk.Client.Common/lua/LuaHelperLibs/DoomLuaLibrary.cs b/src/BizHawk.Client.Common/lua/LuaHelperLibs/DoomLuaLibrary.cs
index 2016d741406..0fb7759cadc 100644
--- a/src/BizHawk.Client.Common/lua/LuaHelperLibs/DoomLuaLibrary.cs
+++ b/src/BizHawk.Client.Common/lua/LuaHelperLibs/DoomLuaLibrary.cs
@@ -11,7 +11,7 @@
namespace BizHawk.Client.Common
{
[Description("Functions specific to Doom games (functions may not run when a Doom game is not loaded)")]
- public sealed class DoomLuaLibrary : LuaLibraryBase
+ public sealed class DoomLuaLibrary : LuaLibraryBase, IRegisterFunctions
{
public NLFAddCallback CreateAndRegisterNamedFunction { get; set; }
@@ -43,9 +43,16 @@ public string OnPrandom(LuaFunction luaf, string name = null)
}
var callbacks = dsda.RandomCallbacks;
- var nlf = CreateAndRegisterNamedFunction(luaf, "OnPrandom", LogOutputCallback, CurrentFile, name: name);
- callbacks.Add(nlf.RandomCallback);
- nlf.OnRemove += () => callbacks.Remove(nlf.RandomCallback);
+ var nlf = CreateAndRegisterNamedFunction(luaf, "OnPrandom", name: name);
+ Action RandomCallback = pr_class =>
+ {
+ _luaLibsImpl.IsInInputOrMemoryCallback = true;
+ nlf.Call([ pr_class ]);
+ _luaLibsImpl.IsInInputOrMemoryCallback = false;
+ };
+
+ callbacks.Add(RandomCallback);
+ nlf.OnRemove += () => callbacks.Remove(RandomCallback);
return nlf.GuidStr;
}
@@ -68,9 +75,16 @@ public string OnUse(LuaFunction luaf, string name = null)
}
var callbacks = dsda.UseCallbacks;
- var nlf = CreateAndRegisterNamedFunction(luaf, "OnUse", LogOutputCallback, CurrentFile, name: name);
- callbacks.Add(nlf.LineCallback);
- nlf.OnRemove += () => callbacks.Remove(nlf.LineCallback);
+ var nlf = CreateAndRegisterNamedFunction(luaf, "OnUse", name: name);
+ Action LineCallback = (line, thing) =>
+ {
+ _luaLibsImpl.IsInInputOrMemoryCallback = true;
+ nlf.Call([ line, thing ]);
+ _luaLibsImpl.IsInInputOrMemoryCallback = false;
+ };
+
+ callbacks.Add(LineCallback);
+ nlf.OnRemove += () => callbacks.Remove(LineCallback);
return nlf.GuidStr;
}
@@ -93,9 +107,16 @@ public string OnCross(LuaFunction luaf, string name = null)
}
var callbacks = dsda.CrossCallbacks;
- var nlf = CreateAndRegisterNamedFunction(luaf, "OnCross", LogOutputCallback, CurrentFile, name: name);
- callbacks.Add(nlf.LineCallback);
- nlf.OnRemove += () => callbacks.Remove(nlf.LineCallback);
+ var nlf = CreateAndRegisterNamedFunction(luaf, "OnCross", name: name);
+ Action LineCallback = (line, thing) =>
+ {
+ _luaLibsImpl.IsInInputOrMemoryCallback = true;
+ nlf.Call([ line, thing ]);
+ _luaLibsImpl.IsInInputOrMemoryCallback = false;
+ };
+
+ callbacks.Add(LineCallback);
+ nlf.OnRemove += () => callbacks.Remove(LineCallback);
return nlf.GuidStr;
}
}
diff --git a/src/BizHawk.Client.Common/lua/LuaHelperLibs/EventsLuaLibrary.cs b/src/BizHawk.Client.Common/lua/LuaHelperLibs/EventsLuaLibrary.cs
index 706fd9dcbbe..7507cee6a8c 100644
--- a/src/BizHawk.Client.Common/lua/LuaHelperLibs/EventsLuaLibrary.cs
+++ b/src/BizHawk.Client.Common/lua/LuaHelperLibs/EventsLuaLibrary.cs
@@ -8,7 +8,7 @@
namespace BizHawk.Client.Common
{
[Description("A library for registering lua functions to emulator events.\n All events support multiple registered methods.\nAll registered event methods can be named and return a Guid when registered")]
- public sealed class EventsLuaLibrary : LuaLibraryBase
+ public sealed class EventsLuaLibrary : LuaLibraryBase, IRegisterFunctions
{
private static readonly string EMPTY_UUID_STR = Guid.Empty.ToString("D");
@@ -36,14 +36,22 @@ public EventsLuaLibrary(ILuaLibraries luaLibsImpl, ApiContainer apiContainer, Ac
private void AddMemCallbackOnCore(INamedLuaFunction nlf, MemoryCallbackType kind, string/*?*/ scope, uint? address)
{
var memCallbackImpl = DebuggableCore.MemoryCallbacks;
+ MemoryCallbackDelegate memCallback = (addr, val, flags) =>
+ {
+ _luaLibsImpl.IsInInputOrMemoryCallback = true;
+ uint? ret = nlf.Call([ addr, val, flags ]) is [ long n ] ? unchecked((uint) n) : null;
+ _luaLibsImpl.IsInInputOrMemoryCallback = false;
+ return ret;
+ };
+
memCallbackImpl.Add(new MemoryCallback(
ProcessScope(scope),
kind,
"Lua Hook",
- nlf.MemCallback,
+ memCallback,
address,
null));
- nlf.OnRemove += () => memCallbackImpl.Remove(nlf.MemCallback);
+ nlf.OnRemove += () => memCallbackImpl.Remove(memCallback);
}
private void LogMemoryCallbacksNotImplemented(bool isWildcard)
@@ -65,20 +73,20 @@ public bool CanUseCallbackParams(string subset = null)
[LuaMethodExample("local steveonf = event.onframeend(\r\n\tfunction()\r\n\t\tconsole.log( \"Calls the given lua function at the end of each frame, after all emulation and drawing has completed. Note: this is the default behavior of lua scripts\" );\r\n\tend\r\n\t, \"Frame name\" );")]
[LuaMethod("onframeend", "Calls the given lua function at the end of each frame, after all emulation and drawing has completed. Note: this is the default behavior of lua scripts")]
public string OnFrameEnd(LuaFunction luaf, string name = null)
- => CreateAndRegisterNamedFunction(luaf, NamedLuaFunction.EVENT_TYPE_POSTFRAME, LogOutputCallback, CurrentFile, name: name)
+ => CreateAndRegisterNamedFunction(luaf, NamedLuaFunction.EVENT_TYPE_POSTFRAME, name: name)
.GuidStr;
[LuaMethodExample("local steveonf = event.onframestart(\r\n\tfunction()\r\n\t\tconsole.log( \"Calls the given lua function at the beginning of each frame before any emulation and drawing occurs\" );\r\n\tend\r\n\t, \"Frame name\" );")]
[LuaMethod("onframestart", "Calls the given lua function at the beginning of each frame before any emulation and drawing occurs")]
public string OnFrameStart(LuaFunction luaf, string name = null)
- => CreateAndRegisterNamedFunction(luaf, NamedLuaFunction.EVENT_TYPE_PREFRAME, LogOutputCallback, CurrentFile, name: name)
+ => CreateAndRegisterNamedFunction(luaf, NamedLuaFunction.EVENT_TYPE_PREFRAME, name: name)
.GuidStr;
[LuaMethodExample("local steveoni = event.oninputpoll(\r\n\tfunction()\r\n\t\tconsole.log( \"Calls the given lua function after each time the emulator core polls for input\" );\r\n\tend\r\n\t, \"Frame name\" );")]
[LuaMethod("oninputpoll", "Calls the given lua function after each time the emulator core polls for input")]
public string OnInputPoll(LuaFunction luaf, string name = null)
{
- var nlf = CreateAndRegisterNamedFunction(luaf, NamedLuaFunction.EVENT_TYPE_INPUTPOLL, LogOutputCallback, CurrentFile, name: name);
+ var nlf = CreateAndRegisterNamedFunction(luaf, NamedLuaFunction.EVENT_TYPE_INPUTPOLL, name: name);
//TODO should we bother registering the function if the service isn't supported? none of the other events work this way --yoshi
if (InputPollableCore != null)
@@ -86,8 +94,14 @@ public string OnInputPoll(LuaFunction luaf, string name = null)
try
{
var inputCallbackImpl = InputPollableCore.InputCallbacks;
- inputCallbackImpl.Add(nlf.InputCallback);
- nlf.OnRemove += () => inputCallbackImpl.Remove(nlf.InputCallback);
+ Action InputCallback = () =>
+ {
+ _luaLibsImpl.IsInInputOrMemoryCallback = true;
+ nlf.Call(Array.Empty