prevent various apis from being used while in an input/memory callback
This commit is contained in:
parent
986299c52b
commit
5bf9d387b4
|
@ -74,6 +74,11 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethod("closerom", "Closes the loaded Rom")]
|
||||
public void CloseRom()
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("client.closerom() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsRebootingCore = true;
|
||||
APIs.EmuClient.CloseRom();
|
||||
_luaLibsImpl.IsRebootingCore = false;
|
||||
|
@ -102,6 +107,11 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethod("seekframe", "Makes the emulator seek to the frame specified")]
|
||||
public void SeekFrame(int frame)
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("client.seekframe() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
if (frame < Emulator.Frame)
|
||||
{
|
||||
Log("client.seekframe: cannot seek backwards");
|
||||
|
@ -200,6 +210,11 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethod("openrom", "Loads a ROM from the given path. Returns true if the ROM was successfully loaded, otherwise false.")]
|
||||
public bool OpenRom(string path)
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("client.openrom() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsRebootingCore = true;
|
||||
var success = APIs.EmuClient.OpenRom(path);
|
||||
_luaLibsImpl.IsRebootingCore = false;
|
||||
|
@ -235,6 +250,11 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethod("reboot_core", "Reboots the currently loaded core")]
|
||||
public void RebootCore()
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("client.reboot_core() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsRebootingCore = true;
|
||||
APIs.EmuClient.RebootCore();
|
||||
_luaLibsImpl.IsRebootingCore = false;
|
||||
|
|
|
@ -14,21 +14,35 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethodExample("local mmsvstsvcst = memorysavestate.savecorestate( );")]
|
||||
[LuaMethod("savecorestate", "creates a core savestate and stores it in memory. Note: a core savestate is only the raw data from the core, and not extras such as movie input logs, or framebuffers. Returns a unique identifer for the savestate")]
|
||||
public string SaveCoreStateToMemory()
|
||||
=> APIs.MemorySaveState.SaveCoreStateToMemory();
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("memorysavestate.savecorestate() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
return APIs.MemorySaveState!.SaveCoreStateToMemory();
|
||||
}
|
||||
|
||||
[LuaMethodExample("memorysavestate.loadcorestate( \"3fcf120f-0778-43fd-b2c5-460fb7d34184\" );")]
|
||||
[LuaMethod("loadcorestate", "loads an in memory state with the given identifier")]
|
||||
public void LoadCoreStateFromMemory(string identifier)
|
||||
=> APIs.MemorySaveState.LoadCoreStateFromMemory(identifier);
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("memorysavestate.loadcorestate() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
APIs.MemorySaveState!.LoadCoreStateFromMemory(identifier);
|
||||
}
|
||||
|
||||
[LuaMethodExample("memorysavestate.removestate( \"3fcf120f-0778-43fd-b2c5-460fb7d34184\" );")]
|
||||
[LuaMethod("removestate", "removes the savestate with the given identifier from memory")]
|
||||
public void DeleteState(string identifier)
|
||||
=> APIs.MemorySaveState.DeleteState(identifier);
|
||||
=> APIs.MemorySaveState!.DeleteState(identifier);
|
||||
|
||||
[LuaMethodExample("memorysavestate.clearstatesfrommemory( );")]
|
||||
[LuaMethod("clearstatesfrommemory", "clears all savestates stored in memory")]
|
||||
public void ClearInMemoryStates()
|
||||
=> APIs.MemorySaveState.ClearInMemoryStates();
|
||||
=> APIs.MemorySaveState!.ClearInMemoryStates();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,11 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethod("play_from_start", "Resets the core to frame 0 with the currently loaded movie in playback mode. If a path to a movie is specified, attempts to load it, then continues with playback if it was successful. Returns true iff successful.")]
|
||||
public bool PlayFromStart(string path = "")
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("movie.play_from_start() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsRebootingCore = true;
|
||||
var success = APIs.Movie.PlayFromStart(path);
|
||||
_luaLibsImpl.IsRebootingCore = false;
|
||||
|
|
|
@ -13,6 +13,11 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethod("load", "Loads a savestate with the given path. Returns true iff succeeded. If EmuHawk is deferring quicksaves, to TAStudio for example, that form will do what it likes (and the path is ignored).")]
|
||||
public bool Load(string path, bool suppressOSD = false)
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("savestate.load() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsUpdateSupressed = true;
|
||||
var success = APIs.SaveState.Load(path, suppressOSD);
|
||||
_luaLibsImpl.IsUpdateSupressed = false;
|
||||
|
@ -23,6 +28,11 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethod("loadslot", "Loads the savestate at the given slot number (must be an integer between 1 and 10). Returns true iff succeeded. If EmuHawk is deferring quicksaves, to TAStudio for example, that form will do what it likes with the slot number.")]
|
||||
public bool LoadSlot(int slotNum, bool suppressOSD = false)
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("savestate.loadslot() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsUpdateSupressed = true;
|
||||
var success = APIs.SaveState.LoadSlot(slotNum, suppressOSD: suppressOSD);
|
||||
_luaLibsImpl.IsUpdateSupressed = false;
|
||||
|
@ -32,11 +42,25 @@ namespace BizHawk.Client.Common
|
|||
[LuaMethodExample("savestate.save( \"C:\\state.bin\" );")]
|
||||
[LuaMethod("save", "Saves a state at the given path. If EmuHawk is deferring quicksaves, to TAStudio for example, that form will do what it likes (and the path is ignored).")]
|
||||
public void Save(string path, bool suppressOSD = false)
|
||||
=> APIs.SaveState.Save(path, suppressOSD);
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("savestate.save() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
APIs.SaveState.Save(path, suppressOSD);
|
||||
}
|
||||
|
||||
[LuaMethodExample("savestate.saveslot( 7 );")]
|
||||
[LuaMethod("saveslot", "Saves a state at the given save slot (must be an integer between 1 and 10). If EmuHawk is deferring quicksaves, to TAStudio for example, that form will do what it likes with the slot number.")]
|
||||
public void SaveSlot(int slotNum, bool suppressOSD = false)
|
||||
=> APIs.SaveState.SaveSlot(slotNum, suppressOSD);
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("savestate.saveslot() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
APIs.SaveState.SaveSlot(slotNum, suppressOSD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ namespace BizHawk.Client.Common
|
|||
|
||||
bool IsUpdateSupressed { get; set; }
|
||||
|
||||
/// <remarks>not really sure if this is the right place to put it, multiple different places need this...</remarks>
|
||||
bool IsInInputOrMemoryCallback { get; set; }
|
||||
|
||||
LuaFunctionList RegisteredFunctions { get; }
|
||||
|
||||
public PathEntryCollection PathEntries { get; }
|
||||
|
|
|
@ -31,12 +31,14 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private readonly LuaFunction _function;
|
||||
|
||||
public NamedLuaFunction(LuaFunction function, string theEvent, Action<string> logCallback, LuaFile luaFile, Func<LuaThread> createThreadCallback, string name = null)
|
||||
public NamedLuaFunction(LuaFunction function, string theEvent, Action<string> logCallback, LuaFile luaFile,
|
||||
Func<LuaThread> createThreadCallback, ILuaLibraries luaLibraries, string name = null)
|
||||
{
|
||||
_function = function;
|
||||
Name = name ?? "Anonymous";
|
||||
Event = theEvent;
|
||||
CreateThreadCallback = createThreadCallback;
|
||||
LuaLibraries = luaLibraries;
|
||||
|
||||
// When would a file be null?
|
||||
// When a script is loaded with a callback, but no infinite loop so it closes
|
||||
|
@ -66,8 +68,30 @@ namespace BizHawk.Client.Common
|
|||
logCallback($"error running function attached by the event {Event}\nError message: {ex.Message}");
|
||||
}
|
||||
};
|
||||
InputCallback = () => Callback(Array.Empty<object>());
|
||||
MemCallback = (addr, val, flags) => Callback(new object[] { addr, val, flags });
|
||||
InputCallback = () =>
|
||||
{
|
||||
LuaLibraries.IsInInputOrMemoryCallback = true;
|
||||
try
|
||||
{
|
||||
Callback(Array.Empty<object>());
|
||||
}
|
||||
finally
|
||||
{
|
||||
LuaLibraries.IsInInputOrMemoryCallback = false;
|
||||
}
|
||||
};
|
||||
MemCallback = (addr, val, flags) =>
|
||||
{
|
||||
LuaLibraries.IsInInputOrMemoryCallback = true;
|
||||
try
|
||||
{
|
||||
Callback(new object[] { addr, val, flags });
|
||||
}
|
||||
finally
|
||||
{
|
||||
LuaLibraries.IsInInputOrMemoryCallback = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void DetachFromScript()
|
||||
|
@ -87,6 +111,11 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public LuaFile LuaFile { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// HACK
|
||||
/// </summary>
|
||||
private ILuaLibraries LuaLibraries { get; }
|
||||
|
||||
private Func<LuaThread> CreateThreadCallback { get; }
|
||||
|
||||
public string Event { get; }
|
||||
|
|
|
@ -139,6 +139,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (Engaged())
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("tastudio.setplayback() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsUpdateSupressed = true;
|
||||
|
||||
int f;
|
||||
|
@ -298,6 +303,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (Engaged())
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("tastudio.applyinputchanges() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsUpdateSupressed = true;
|
||||
|
||||
if (_changeList.Count > 0)
|
||||
|
@ -424,6 +434,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (Engaged())
|
||||
{
|
||||
if (_luaLibsImpl.IsInInputOrMemoryCallback)
|
||||
{
|
||||
throw new InvalidOperationException("tastudio.loadbranch() is not allowed during input/memory callbacks");
|
||||
}
|
||||
|
||||
_luaLibsImpl.IsUpdateSupressed = true;
|
||||
|
||||
Tastudio.LoadBranchByIndex(index);
|
||||
|
|
|
@ -165,6 +165,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public bool IsUpdateSupressed { get; set; }
|
||||
|
||||
public bool IsInInputOrMemoryCallback { get; set; }
|
||||
|
||||
private readonly IDictionary<Type, LuaLibraryBase> Libraries = new Dictionary<Type, LuaLibraryBase>();
|
||||
|
||||
private EventWaitHandle LuaWait;
|
||||
|
@ -309,7 +311,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
LuaFile luaFile,
|
||||
string name = null)
|
||||
{
|
||||
var nlf = new NamedLuaFunction(function, theEvent, logCallback, luaFile, () => _lua.NewThread(), name);
|
||||
var nlf = new NamedLuaFunction(function, theEvent, logCallback, luaFile, () => _lua.NewThread(), this, name);
|
||||
RegisteredFunctions.Add(nlf);
|
||||
return nlf;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue