Refactor IControlMainform handling in Mainform (#3935)
This allows any loaded tool to control any aspect of `IControlMainform` independently of others. Also improves rewinder handling when any tool `WantsToControlRewind`.
This commit is contained in:
parent
1a9e5e52f1
commit
256218305b
|
@ -78,9 +78,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
bool BlockFrameAdvance { get; set; }
|
||||
|
||||
/// <remarks>only referenced from <see cref="TAStudio"/></remarks>
|
||||
void RelinquishControl(IControlMainform master);
|
||||
|
||||
/// <remarks>only referenced from <see cref="TAStudio"/></remarks>
|
||||
void SeekFrameAdvance();
|
||||
|
||||
|
@ -88,9 +85,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
bool StartNewMovie(IMovie movie, bool record);
|
||||
|
||||
/// <remarks>only referenced from <see cref="TAStudio"/></remarks>
|
||||
void TakeBackControl();
|
||||
|
||||
/// <remarks>only referenced from <see cref="BasicBot"/></remarks>
|
||||
void Throttle();
|
||||
|
||||
|
|
|
@ -100,9 +100,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public void StopMovie(bool saveChanges = true)
|
||||
{
|
||||
if (IsSlave && Master.WantsToControlStopMovie)
|
||||
if (ToolControllingStopMovie is { } tool)
|
||||
{
|
||||
Master.StopMovie(!saveChanges);
|
||||
tool.StopMovie(!saveChanges);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -113,7 +113,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public bool RestartMovie()
|
||||
{
|
||||
if (IsSlave && Master.WantsToControlRestartMovie) return Master.RestartMovie();
|
||||
if (ToolControllingRestartMovie is { } tool) return tool.RestartMovie();
|
||||
if (!MovieSession.Movie.IsActive()) return false;
|
||||
var success = StartNewMovie(MovieSession.Movie, false);
|
||||
if (success) AddOnScreenMessage("Replaying movie file in read-only mode");
|
||||
|
@ -122,9 +122,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void ToggleReadOnly()
|
||||
{
|
||||
if (IsSlave && Master.WantsToControlReadOnly)
|
||||
if (ToolControllingReadOnly is { } tool)
|
||||
{
|
||||
Master.ToggleReadOnly();
|
||||
tool.ToggleReadOnly();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1089,6 +1089,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public readonly ToolManager Tools;
|
||||
|
||||
private IControlMainform ToolControllingSavestates => Tools.FirstOrNull<IControlMainform>(tool => tool.WantsToControlSavestates);
|
||||
private IControlMainform ToolControllingRewind => Tools.FirstOrNull<IControlMainform>(tool => tool.WantsToControlRewind);
|
||||
private IControlMainform ToolControllingReboot => Tools.FirstOrNull<IControlMainform>(tool => tool.WantsToControlReboot);
|
||||
private IControlMainform ToolControllingStopMovie => Tools.FirstOrNull<IControlMainform>(tool => tool.WantsToControlStopMovie);
|
||||
private IControlMainform ToolControllingRestartMovie => Tools.FirstOrNull<IControlMainform>(tool => tool.WantsToControlRestartMovie);
|
||||
private IControlMainform ToolControllingReadOnly => Tools.FirstOrNull<IControlMainform>(tool => tool.WantsToControlReadOnly);
|
||||
|
||||
private DisplayManager DisplayManager;
|
||||
|
||||
private OSDManager OSD => DisplayManager.OSD;
|
||||
|
@ -1116,6 +1123,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public void CreateRewinder()
|
||||
{
|
||||
if (ToolControllingRewind is not null) return;
|
||||
|
||||
Rewinder?.Dispose();
|
||||
Rewinder = Emulator.HasSavestates() && Config.Rewind.Enabled && (!Emulator.AsStatable().AvoidRewind || Config.Rewind.AllowSlowStates)
|
||||
? Config.Rewind.UseDelta
|
||||
|
@ -1274,9 +1283,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public bool RebootCore()
|
||||
{
|
||||
if (IsSlave && Master.WantsToControlReboot)
|
||||
if (ToolControllingReboot is { } tool)
|
||||
{
|
||||
Master.RebootCore();
|
||||
tool.RebootCore();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -3257,7 +3266,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
MovieSession.Movie.SwitchToRecord();
|
||||
}
|
||||
|
||||
if (isRewinding && !IsRewindSlave && MovieSession.Movie.IsRecording())
|
||||
if (isRewinding && ToolControllingRewind is null && MovieSession.Movie.IsRecording())
|
||||
{
|
||||
MovieSession.Movie.Truncate(Emulator.Frame);
|
||||
}
|
||||
|
@ -4175,7 +4184,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
Emulator.Dispose();
|
||||
Emulator = new NullEmulator();
|
||||
Game = GameInfo.NullInstance;
|
||||
CreateRewinder();
|
||||
Tools.Restart(Config, Emulator, Game);
|
||||
RewireSound();
|
||||
ClearHolds();
|
||||
|
@ -4248,25 +4256,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
Rewinder = null;
|
||||
}
|
||||
|
||||
// TODO: move me
|
||||
public IControlMainform Master { get; private set; }
|
||||
|
||||
private bool IsSlave => Master != null;
|
||||
|
||||
private bool IsSavestateSlave => IsSlave && Master.WantsToControlSavestates;
|
||||
|
||||
private bool IsRewindSlave => IsSlave && Master.WantsToControlRewind;
|
||||
|
||||
public void RelinquishControl(IControlMainform master)
|
||||
{
|
||||
Master = master;
|
||||
}
|
||||
|
||||
public void TakeBackControl()
|
||||
{
|
||||
Master = null;
|
||||
}
|
||||
|
||||
private int SlotToInt(string slot)
|
||||
{
|
||||
return int.Parse(slot.Substring(slot.Length - 1, 1));
|
||||
|
@ -4282,7 +4271,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
public bool LoadState(string path, string userFriendlyStateName, bool suppressOSD = false) // Move to client.common
|
||||
{
|
||||
if (!Emulator.HasSavestates()) return false;
|
||||
if (IsSavestateSlave) return Master.LoadState();
|
||||
if (ToolControllingSavestates is { } tool) return tool.LoadState();
|
||||
|
||||
if (!new SavestateFile(Emulator, MovieSession, MovieSession.UserBag).Load(path, this))
|
||||
{
|
||||
|
@ -4311,7 +4300,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
//we don't want to analyze how to intermix movies, rewinding, and states
|
||||
//so purge rewind history when loading a state while doing a movie
|
||||
if (!IsRewindSlave && MovieSession.Movie.IsActive())
|
||||
if (ToolControllingRewind is null && MovieSession.Movie.IsActive())
|
||||
{
|
||||
Rewinder?.Clear();
|
||||
}
|
||||
|
@ -4337,7 +4326,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
if (handled) return true; // not sure
|
||||
|
||||
if (IsSavestateSlave) return Master.LoadQuickSave(SlotToInt(quickSlotName));
|
||||
if (ToolControllingSavestates is { } tool) return tool.LoadQuickSave(SlotToInt(quickSlotName));
|
||||
|
||||
var path = $"{SaveStatePrefix()}.{quickSlotName}.State";
|
||||
if (!File.Exists(path))
|
||||
|
@ -4356,9 +4345,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
|
||||
if (IsSavestateSlave)
|
||||
if (ToolControllingSavestates is { } tool)
|
||||
{
|
||||
Master.SaveState();
|
||||
tool.SaveState();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4409,9 +4398,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
|
||||
if (IsSavestateSlave)
|
||||
if (ToolControllingSavestates is { } tool)
|
||||
{
|
||||
Master.SaveQuickSave(SlotToInt(quickSlotName));
|
||||
tool.SaveQuickSave(SlotToInt(quickSlotName));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4482,9 +4471,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
Tools.TAStudio.NamedStatePending = true;
|
||||
}
|
||||
|
||||
if (IsSavestateSlave)
|
||||
if (ToolControllingSavestates is { } tool)
|
||||
{
|
||||
Master.SaveStateAs();
|
||||
tool.SaveStateAs();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4512,7 +4501,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private bool LoadStateAs()
|
||||
{
|
||||
if (!Emulator.HasSavestates()) return false;
|
||||
if (IsSavestateSlave) return Master.LoadStateAs();
|
||||
if (ToolControllingSavestates is { } tool) return tool.LoadStateAs();
|
||||
|
||||
var result = this.ShowFileOpenDialog(
|
||||
discardCWDChange: true,
|
||||
|
@ -4525,9 +4514,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void SelectSlot(int slot)
|
||||
{
|
||||
if (!Emulator.HasSavestates()) return;
|
||||
if (IsSavestateSlave)
|
||||
if (ToolControllingSavestates is { } tool)
|
||||
{
|
||||
var handled = Master.SelectSlot(slot);
|
||||
bool handled = tool.SelectSlot(slot);
|
||||
if (handled) return;
|
||||
}
|
||||
Config.SaveSlot = slot;
|
||||
|
@ -4538,9 +4527,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void PreviousSlot()
|
||||
{
|
||||
if (!Emulator.HasSavestates()) return;
|
||||
if (IsSavestateSlave)
|
||||
if (ToolControllingSavestates is { } tool)
|
||||
{
|
||||
var handled = Master.PreviousSlot();
|
||||
bool handled = tool.PreviousSlot();
|
||||
if (handled) return;
|
||||
}
|
||||
Config.SaveSlot--;
|
||||
|
@ -4552,9 +4541,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void NextSlot()
|
||||
{
|
||||
if (!Emulator.HasSavestates()) return;
|
||||
if (IsSavestateSlave)
|
||||
if (ToolControllingSavestates is { } tool)
|
||||
{
|
||||
var handled = Master.NextSlot();
|
||||
bool handled = tool.NextSlot();
|
||||
if (handled) return;
|
||||
}
|
||||
Config.SaveSlot++;
|
||||
|
@ -4565,9 +4554,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void CaptureRewind(bool suppressCaptureRewind)
|
||||
{
|
||||
if (IsRewindSlave)
|
||||
if (ToolControllingRewind is { } tool)
|
||||
{
|
||||
Master.CaptureRewind();
|
||||
tool.CaptureRewind();
|
||||
}
|
||||
else if (!suppressCaptureRewind && Rewinder?.Active == true)
|
||||
{
|
||||
|
@ -4581,7 +4570,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
returnToRecording = false;
|
||||
|
||||
if (IsRewindSlave)
|
||||
if (ToolControllingRewind is { } rewindTool)
|
||||
{
|
||||
if (InputManager.ClientControls["Rewind"] || PressRewind)
|
||||
{
|
||||
|
@ -4620,7 +4609,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (isRewinding)
|
||||
{
|
||||
runFrame = Emulator.Frame > 1; // TODO: the master should be deciding this!
|
||||
Master.Rewind();
|
||||
rewindTool.Rewind();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
public bool WantsToControlRewind => true;
|
||||
public bool WantsToControlRewind { get; private set; } = true;
|
||||
|
||||
public void CaptureRewind()
|
||||
{
|
||||
|
|
|
@ -281,7 +281,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
MainForm.AddOnScreenMessage("TAStudio engaged");
|
||||
SetTasMovieCallbacks(CurrentTasMovie);
|
||||
UpdateWindowTitle();
|
||||
MainForm.RelinquishControl(this);
|
||||
_originalEndAction = Config.Movies.MovieEndAction;
|
||||
MainForm.DisableRewind();
|
||||
Config.Movies.MovieEndAction = MovieEndAction.Record;
|
||||
|
@ -732,8 +731,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
_engaged = false;
|
||||
MainForm.PauseOnFrame = null;
|
||||
MainForm.AddOnScreenMessage("TAStudio disengaged");
|
||||
MainForm.TakeBackControl();
|
||||
Config.Movies.MovieEndAction = _originalEndAction;
|
||||
WantsToControlRewind = false;
|
||||
MainForm.EnableRewind(true);
|
||||
MainForm.SetMainformMovieInfo();
|
||||
}
|
||||
|
|
|
@ -473,6 +473,25 @@ namespace BizHawk.Client.EmuHawk
|
|||
return Load<T>(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first tool of type <typeparamref name="T"/> that fulfills the given condition
|
||||
/// </summary>
|
||||
/// <param name="condition">The condition to check for</param>
|
||||
/// <typeparam name="T">Type of tools to check</typeparam>
|
||||
/// <returns></returns>
|
||||
public T FirstOrNull<T>(Predicate<T> condition) where T : class
|
||||
{
|
||||
foreach (var tool in _tools)
|
||||
{
|
||||
if (tool.IsActive && tool is T specialTool && condition(specialTool))
|
||||
{
|
||||
return specialTool;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns the instance of <paramref name="toolType"/>, regardless of whether it's loaded,<br/>
|
||||
/// but doesn't create and load a new instance if it's not found
|
||||
|
@ -482,7 +501,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
/// you may pass any class or interface
|
||||
/// </remarks>
|
||||
public IToolForm/*?*/ LazyGet(Type toolType)
|
||||
=> _tools.Find(t => toolType.IsAssignableFrom(t.GetType()));
|
||||
=> _tools.Find(toolType.IsInstanceOfType);
|
||||
|
||||
internal static readonly IDictionary<Type, (Image/*?*/ Icon, string Name)> IconAndNameCache = new Dictionary<Type, (Image/*?*/ Icon, string Name)>
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue