BizHawk/BizHawk.Client.EmuHawk/tools/ToolManager.cs

484 lines
9.9 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
public class ToolManager
{
//TODO: merge ToolHelper code where logical
//For instance, add an IToolForm property called UsesCheats, so that a UpdateCheatRelatedTools() method can update all tools of this type
//Also a UsesRam, and similar method
private List<IToolForm> _tools = new List<IToolForm>();
/// <summary>
/// Loads the tool dialog T, if it does not exist it will be created, if it is already open, it will be focused
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public IToolForm Load<T>() where T : IToolForm
{
var existingTool = _tools.FirstOrDefault(x => x is T);
if (existingTool != null)
{
2013-11-02 20:13:53 +00:00
if (existingTool.IsDisposed)
{
_tools.Remove(existingTool);
}
else
{
existingTool.Show();
existingTool.Focus();
return existingTool;
}
}
2013-11-02 20:13:53 +00:00
var result = Get<T>();
result.Show();
return result;
}
/// <summary>
/// Returns true if an instance of T exists
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public bool Has<T>() where T : IToolForm
{
return _tools.Any(x => x is T);
}
/// <summary>
/// Gets the instance of T, or creates and returns a new instance
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public IToolForm Get<T>() where T : IToolForm
{
var existingTool = _tools.FirstOrDefault(x => x is T);
if (existingTool != null)
{
if (existingTool.IsDisposed)
{
Close<T>();
return CreateInstance<T>();
}
else
{
return existingTool;
}
}
else
{
return CreateInstance<T>();
}
}
public void UpdateBefore()
{
var beforeList = _tools.Where(x => x.UpdateBefore);
foreach (var tool in beforeList)
{
if (!tool.IsDisposed ||
(tool is RamWatch && Global.Config.DisplayRamWatch)) //Ram Watch hack, on screen display should run even if Ram Watch is closed
{
tool.UpdateValues();
}
}
}
public void UpdateAfter()
{
var afterList = _tools.Where(x => !x.UpdateBefore);
foreach (var tool in afterList)
{
if (!tool.IsDisposed)
{
tool.UpdateValues();
}
}
}
/// <summary>
/// Calls UpdateValues() on an instance of T, if it exists
/// </summary>
public void UpdateValues<T>() where T : IToolForm
{
CloseIfDisposed<T>();
var tool = _tools.FirstOrDefault(x => x is T);
if (tool != null)
{
tool.UpdateValues();
}
}
public void Restart()
{
// If Cheat tool is loaded, restarting will restart the list too anyway
if (!GlobalWin.Tools.Has<Cheats>())
{
Global.CheatList.NewList(GenerateDefaultCheatFilename());
}
_tools.ForEach(x => x.Restart());
}
/// <summary>
/// Calls Restart() on an instance of T, if it exists
/// </summary>
/// <typeparam name="T"></typeparam>
public void Restart<T>() where T : IToolForm
{
CloseIfDisposed<T>();
var tool = _tools.FirstOrDefault(x => x is T);
if (tool != null)
{
tool.Restart();
}
}
/// <summary>
/// Runs AskSave on every tool dialog, false is returned if any tool returns false
/// </summary>
/// <returns></returns>
public bool AskSave()
{
foreach (var tool in _tools)
{
var result = tool.AskSave();
if (!result)
{
return false;
}
}
return true;
}
/// <summary>
/// Calls AskSave() on an instance of T, if it exists, else returns true
/// The caller should interpret false as cancel and will back out of the action that invokes this call
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public bool AskSave<T>() where T : IToolForm
{
var tool = _tools.FirstOrDefault(x => x is T);
if (tool != null)
{
return tool.AskSave();
}
else
{
return false;
}
}
/// <summary>
/// If T exists, this call will close the tool, and remove it from memory
/// </summary>
/// <typeparam name="T"></typeparam>
public void Close<T>() where T : IToolForm
{
var tool = _tools.FirstOrDefault(x => x is T);
if (tool != null)
{
tool.Close();
_tools.Remove(tool);
}
}
public void Close()
{
_tools.ForEach(x => x.Close());
_tools.Clear();
}
private IToolForm CreateInstance<T>()
{
var tool = Activator.CreateInstance(typeof(T));
// Add to the list and extract it, so it will be strongly typed as T
_tools.Add(tool as IToolForm);
return _tools.FirstOrDefault(x => x is T);
}
private void CloseIfDisposed<T>() where T : IToolForm
{
var existingTool = _tools.FirstOrDefault(x => x is T);
if (existingTool != null && existingTool.IsDisposed)
{
Close<T>();
}
}
public void UpdateToolsBefore(bool fromLua = false)
{
if (Has<LuaConsole>())
{
if (!fromLua)
{
LuaConsole.StartLuaDrawing();
}
LuaConsole.LuaImp.CallFrameBeforeEvent();
}
UpdateBefore();
}
public void UpdateToolsAfter(bool fromLua = false)
{
if (!fromLua && Has<LuaConsole>())
{
LuaConsole.ResumeScripts(true);
}
GlobalWin.Tools.UpdateAfter();
if (Has<LuaConsole>())
{
LuaConsole.LuaImp.CallFrameAfterEvent();
if (!fromLua)
{
GlobalWin.DisplayManager.PreFrameUpdateLuaSource();
LuaConsole.EndLuaDrawing();
}
}
}
// Note: Referencing these properties creates an instance of the tool and persists it. They should be referenced by type if this is not desired
#region Tools
public RamWatch RamWatch
{
get
{
var tool = _tools.FirstOrDefault(x => x is RamWatch);
if (tool != null)
{
2013-11-02 20:13:53 +00:00
if (tool.IsDisposed)
{
_tools.Remove(tool);
}
else
{
return tool as RamWatch;
}
}
2013-11-02 20:13:53 +00:00
var newTool = new RamWatch();
_tools.Add(newTool);
return newTool;
2013-11-02 20:13:53 +00:00
}
}
public RamSearch RamSearch
{
get
{
var tool = _tools.FirstOrDefault(x => x is RamSearch);
if (tool != null)
{
2013-11-02 20:13:53 +00:00
if (tool.IsDisposed)
{
_tools.Remove(tool);
}
else
{
return tool as RamSearch;
}
}
2013-11-02 20:13:53 +00:00
var newTool = new RamSearch();
_tools.Add(newTool);
return newTool;
}
}
public Cheats Cheats
{
get
{
var tool = _tools.FirstOrDefault(x => x is Cheats);
if (tool != null)
{
if (tool.IsDisposed)
{
_tools.Remove(tool);
}
else
{
return tool as Cheats;
}
}
var newTool = new Cheats();
_tools.Add(newTool);
return newTool;
}
}
2013-11-02 20:25:53 +00:00
public HexEditor HexEditor
{
get
{
var tool = _tools.FirstOrDefault(x => x is HexEditor);
if (tool != null)
{
if (tool.IsDisposed)
{
_tools.Remove(tool);
}
else
{
return tool as HexEditor;
}
}
var newTool = new HexEditor();
_tools.Add(newTool);
return newTool;
2013-11-02 20:25:53 +00:00
}
}
2013-11-02 21:31:04 +00:00
public VirtualPadForm VirtualPad
{
get
{
var tool = _tools.FirstOrDefault(x => x is VirtualPadForm);
if (tool != null)
{
if (tool.IsDisposed)
{
_tools.Remove(tool);
}
else
{
return tool as VirtualPadForm;
}
}
var newTool = new VirtualPadForm();
_tools.Add(newTool);
return newTool;
}
}
public SNESGraphicsDebugger SNESGraphicsDebugger
{
get
{
var tool = _tools.FirstOrDefault(x => x is SNESGraphicsDebugger);
if (tool != null)
{
if (tool.IsDisposed)
{
_tools.Remove(tool);
}
else
{
return tool as SNESGraphicsDebugger;
}
}
var newTool = new SNESGraphicsDebugger();
_tools.Add(newTool);
return newTool;
2013-11-02 21:31:04 +00:00
}
}
public LuaConsole LuaConsole
{
get
{
var tool = _tools.FirstOrDefault(x => x is LuaConsole);
if (tool != null)
{
if (tool.IsDisposed)
{
_tools.Remove(tool);
}
else
{
return tool as LuaConsole;
}
}
var newTool = new LuaConsole();
_tools.Add(newTool);
return newTool;
}
}
#endregion
#region Specialized Tool Loading Logic
public void LoadRamWatch(bool loadDialog)
{
if (Global.Config.RecentWatches.AutoLoad && !Global.Config.RecentWatches.Empty)
{
GlobalWin.Tools.RamWatch.LoadFileFromRecent(Global.Config.RecentWatches[0]);
}
if (loadDialog)
{
GlobalWin.Tools.Load<RamWatch>();
}
}
public void LoadTraceLogger()
{
if (Global.Emulator.CoreComm.CpuTraceAvailable)
{
Load<TraceLogger>();
}
}
public void LoadGameGenieEc()
{
if (Global.Emulator.SystemId == "NES")
{
Load<NESGameGenie>();
}
else if (Global.Emulator.SystemId == "SNES")
{
Load<SNESGameGenie>();
}
else if ((Global.Emulator.SystemId == "GB") || (Global.Game.System == "GG"))
{
Load<GBGameGenie>();
}
else if (Global.Emulator.SystemId == "GEN" && VersionInfo.INTERIM)
{
Load<GenGameGenie>();
}
}
#endregion
public static string GenerateDefaultCheatFilename()
{
var pathEntry = Global.Config.PathEntries[Global.Game.System, "Cheats"];
if (pathEntry == null)
{
pathEntry = Global.Config.PathEntries[Global.Game.System, "Base"];
}
var path = PathManager.MakeAbsolutePath(pathEntry.Path, Global.Game.System);
var f = new FileInfo(path);
if (f.Directory != null && f.Directory.Exists == false)
{
f.Directory.Create();
}
return Path.Combine(path, PathManager.FilesystemSafeName(Global.Game) + ".cht");
}
}
}