cleanups in ToolManager

This commit is contained in:
adelikat 2017-05-22 12:51:34 -05:00
parent c1bff4b19c
commit 8d91557f4e
1 changed files with 106 additions and 94 deletions

View File

@ -5,20 +5,16 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.ComponentModel; using System.ComponentModel;
using System.Windows.Forms;
using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Common.ReflectionExtensions; using BizHawk.Common.ReflectionExtensions;
using System.Windows.Forms;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
public class ToolManager public class ToolManager
{ {
#region Fields
private readonly Form _owner; private readonly Form _owner;
// TODO: merge ToolHelper code where logical // TODO: merge ToolHelper code where logical
@ -26,12 +22,8 @@ namespace BizHawk.Client.EmuHawk
// Also a UsesRam, and similar method // Also a UsesRam, and similar method
private readonly List<IToolForm> _tools = new List<IToolForm>(); private readonly List<IToolForm> _tools = new List<IToolForm>();
#endregion
#region cTor(s)
/// <summary> /// <summary>
/// Initialize an new ToolManager instance /// Initializes a new instance of the <see cref="ToolManager"/> class.
/// </summary> /// </summary>
/// <param name="owner">Form that handle the ToolManager</param> /// <param name="owner">Form that handle the ToolManager</param>
public ToolManager(Form owner) public ToolManager(Form owner)
@ -39,28 +31,24 @@ namespace BizHawk.Client.EmuHawk
_owner = owner; _owner = owner;
} }
#endregion
/// <summary> /// <summary>
/// Loads the tool dialog T (T must implemants <see cref="IToolForm"/>) , if it does not exist it will be created, if it is already open, it will be focused /// Loads the tool dialog T (T must implements <see cref="IToolForm"/>) , if it does not exist it will be created, if it is already open, it will be focused
/// This method should be used only if you can't use the generic one /// This method should be used only if you can't use the generic one
/// </summary> /// </summary>
/// <param name="toolType">Type of tool you want to load</param> /// <param name="toolType">Type of tool you want to load</param>
/// <param name="focus">Define if the tool form has to get the focus or not (Default is true)</param> /// <param name="focus">Define if the tool form has to get the focus or not (Default is true)</param>
/// <returns>An instanciated <see cref="IToolForm"/></returns> /// <returns>An instantiated <see cref="IToolForm"/></returns>
/// <exception cref="ArgumentException">Raised if <paramref name="toolType"/> can't be casted into IToolForm </exception> /// <exception cref="ArgumentException">Raised if <paramref name="toolType"/> can't be casted into IToolForm </exception>
internal IToolForm Load(Type toolType, bool focus = true) internal IToolForm Load(Type toolType, bool focus = true)
{ {
if (!typeof(IToolForm).IsAssignableFrom(toolType)) if (!typeof(IToolForm).IsAssignableFrom(toolType))
{ {
throw new ArgumentException(string.Format("Type {0} does not implement IToolForm.", toolType.Name)); throw new ArgumentException($"Type {toolType.Name} does not implement IToolForm.");
}
else
{
//The type[] in parameter is used to avoid an ambigous name exception
MethodInfo method = GetType().GetMethod("Load", new Type[] { typeof(bool) }).MakeGenericMethod(toolType);
return (IToolForm)method.Invoke(this, new object[] { focus });
} }
// The type[] in parameter is used to avoid an ambigous name exception
MethodInfo method = GetType().GetMethod("Load", new Type[] { typeof(bool) }).MakeGenericMethod(toolType);
return (IToolForm)method.Invoke(this, new object[] { focus });
} }
/// <summary> /// <summary>
@ -68,7 +56,7 @@ namespace BizHawk.Client.EmuHawk
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool you want to load</typeparam> /// <typeparam name="T">Type of tool you want to load</typeparam>
/// <param name="focus">Define if the tool form has to get the focus or not (Default is true)</param> /// <param name="focus">Define if the tool form has to get the focus or not (Default is true)</param>
/// <returns>An instanciated <see cref="IToolForm"/></returns> /// <returns>An instantiated <see cref="IToolForm"/></returns>
public T Load<T>(bool focus = true) public T Load<T>(bool focus = true)
where T : class, IToolForm where T : class, IToolForm
{ {
@ -79,9 +67,9 @@ namespace BizHawk.Client.EmuHawk
/// Loads the tool dialog T (T must implement <see cref="IToolForm"/>) , if it does not exist it will be created, if it is already open, it will be focused /// Loads the tool dialog T (T must implement <see cref="IToolForm"/>) , if it does not exist it will be created, if it is already open, it will be focused
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool you want to load</typeparam> /// <typeparam name="T">Type of tool you want to load</typeparam>
/// <param name="toolPath">Path to the .dll of the external tool</param>
/// <param name="focus">Define if the tool form has to get the focus or not (Default is true)</param> /// <param name="focus">Define if the tool form has to get the focus or not (Default is true)</param>
/// <param name="toolPath">Path to the dll of the external tool</param> /// <returns>An instantiated <see cref="IToolForm"/></returns>
/// <returns>An instanciated <see cref="IToolForm"/></returns>
public T Load<T>(string toolPath, bool focus = true) public T Load<T>(string toolPath, bool focus = true)
where T : class, IToolForm where T : class, IToolForm
{ {
@ -95,11 +83,11 @@ namespace BizHawk.Client.EmuHawk
T existingTool; T existingTool;
if (isExternal) if (isExternal)
{ {
existingTool = (T)_tools.FirstOrDefault(x => x is T && x.GetType().Assembly.Location == toolPath); existingTool = (T)_tools.FirstOrDefault(t => t is T && t.GetType().Assembly.Location == toolPath);
} }
else else
{ {
existingTool = (T)_tools.FirstOrDefault(x => x is T); existingTool = (T)_tools.FirstOrDefault(t => t is T);
} }
if (existingTool != null) if (existingTool != null)
@ -144,6 +132,7 @@ namespace BizHawk.Client.EmuHawk
settings = new ToolDialogSettings(); settings = new ToolDialogSettings();
Global.Config.CommonToolSettings[toolType] = settings; Global.Config.CommonToolSettings[toolType] = settings;
} }
AttachSettingHooks(newTool as IToolFormAutoConfig, settings); AttachSettingHooks(newTool as IToolFormAutoConfig, settings);
} }
@ -156,6 +145,7 @@ namespace BizHawk.Client.EmuHawk
settings = new Dictionary<string, object>(); settings = new Dictionary<string, object>();
Global.Config.CustomToolSettings[toolType] = settings; Global.Config.CustomToolSettings[toolType] = settings;
} }
InstallCustomConfig(newTool, settings); InstallCustomConfig(newTool, settings);
} }
@ -171,7 +161,7 @@ namespace BizHawk.Client.EmuHawk
.Select(kvp => kvp.Key); .Select(kvp => kvp.Key);
var customSettings = Global.Config.CustomToolSettings var customSettings = Global.Config.CustomToolSettings
.Where(list => list.Value.Any(kvp => typeof(ToolDialogSettings).IsAssignableFrom(kvp.Value.GetType()) && (kvp.Value as ToolDialogSettings).AutoLoad)) .Where(list => list.Value.Any(kvp => kvp.Value is ToolDialogSettings && ((ToolDialogSettings)kvp.Value).AutoLoad))
.Select(kvp => kvp.Key); .Select(kvp => kvp.Key);
var typeNames = genericSettings.Concat(customSettings); var typeNames = genericSettings.Concat(customSettings);
@ -193,10 +183,10 @@ namespace BizHawk.Client.EmuHawk
private static void RefreshSettings(Form form, ToolStripItemCollection menu, ToolDialogSettings settings, int idx) private static void RefreshSettings(Form form, ToolStripItemCollection menu, ToolDialogSettings settings, int idx)
{ {
(menu[idx + 0] as ToolStripMenuItem).Checked = settings.SaveWindowPosition; ((ToolStripMenuItem)menu[idx + 0]).Checked = settings.SaveWindowPosition;
(menu[idx + 1] as ToolStripMenuItem).Checked = settings.TopMost; ((ToolStripMenuItem)menu[idx + 1]).Checked = settings.TopMost;
(menu[idx + 2] as ToolStripMenuItem).Checked = settings.FloatingWindow; ((ToolStripMenuItem)menu[idx + 2]).Checked = settings.FloatingWindow;
(menu[idx + 3] as ToolStripMenuItem).Checked = settings.AutoLoad; ((ToolStripMenuItem)menu[idx + 3]).Checked = settings.AutoLoad;
form.TopMost = settings.TopMost; form.TopMost = settings.TopMost;
@ -223,17 +213,22 @@ namespace BizHawk.Client.EmuHawk
break; break;
} }
} }
if (dest == null) if (dest == null)
{ {
var submenu = new ToolStripMenuItem("&Settings"); var submenu = new ToolStripMenuItem("&Settings");
ms.Items.Add(submenu); ms.Items.Add(submenu);
dest = submenu.DropDownItems; dest = submenu.DropDownItems;
} }
break; break;
} }
} }
if (dest == null) if (dest == null)
{
throw new InvalidOperationException("IToolFormAutoConfig must have menu to bind to!"); throw new InvalidOperationException("IToolFormAutoConfig must have menu to bind to!");
}
int idx = dest.Count; int idx = dest.Count;
@ -250,10 +245,13 @@ namespace BizHawk.Client.EmuHawk
form.StartPosition = FormStartPosition.Manual; form.StartPosition = FormStartPosition.Manual;
form.Location = settings.WindowPosition; form.Location = settings.WindowPosition;
} }
if (settings.UseWindowSize) if (settings.UseWindowSize)
{ {
if (form.FormBorderStyle == FormBorderStyle.Sizable || form.FormBorderStyle == FormBorderStyle.SizableToolWindow) if (form.FormBorderStyle == FormBorderStyle.Sizable || form.FormBorderStyle == FormBorderStyle.SizableToolWindow)
{
form.Size = settings.WindowSize; form.Size = settings.WindowSize;
}
} }
form.FormClosing += (o, e) => form.FormClosing += (o, e) =>
@ -262,8 +260,16 @@ namespace BizHawk.Client.EmuHawk
{ {
settings.Wndx = form.Location.X; settings.Wndx = form.Location.X;
settings.Wndy = form.Location.Y; settings.Wndy = form.Location.Y;
if (settings.Wndx < 0) settings.Wndx = 0; if (settings.Wndx < 0)
if (settings.Wndy < 0) settings.Wndy = 0; {
settings.Wndx = 0;
}
if (settings.Wndy < 0)
{
settings.Wndy = 0;
}
settings.Width = form.Right - form.Left; // why not form.Size.Width? settings.Width = form.Right - form.Left; // why not form.Size.Width?
settings.Height = form.Bottom - form.Top; settings.Height = form.Bottom - form.Top;
} }
@ -271,29 +277,29 @@ namespace BizHawk.Client.EmuHawk
dest[idx + 0].Click += (o, e) => dest[idx + 0].Click += (o, e) =>
{ {
bool val = !(o as ToolStripMenuItem).Checked; bool val = !((ToolStripMenuItem)o).Checked;
settings.SaveWindowPosition = val; settings.SaveWindowPosition = val;
(o as ToolStripMenuItem).Checked = val; ((ToolStripMenuItem)o).Checked = val;
}; };
dest[idx + 1].Click += (o, e) => dest[idx + 1].Click += (o, e) =>
{ {
bool val = !(o as ToolStripMenuItem).Checked; bool val = !((ToolStripMenuItem)o).Checked;
settings.TopMost = val; settings.TopMost = val;
(o as ToolStripMenuItem).Checked = val; ((ToolStripMenuItem)o).Checked = val;
form.TopMost = val; form.TopMost = val;
}; };
dest[idx + 2].Click += (o, e) => dest[idx + 2].Click += (o, e) =>
{ {
bool val = !(o as ToolStripMenuItem).Checked; bool val = !((ToolStripMenuItem)o).Checked;
settings.FloatingWindow = val; settings.FloatingWindow = val;
(o as ToolStripMenuItem).Checked = val; ((ToolStripMenuItem)o).Checked = val;
form.Owner = val ? null : _owner; form.Owner = val ? null : _owner;
}; };
dest[idx + 3].Click += (o, e) => dest[idx + 3].Click += (o, e) =>
{ {
bool val = !(o as ToolStripMenuItem).Checked; bool val = !((ToolStripMenuItem)o).Checked;
settings.AutoLoad = val; settings.AutoLoad = val;
(o as ToolStripMenuItem).Checked = val; ((ToolStripMenuItem)o).Checked = val;
}; };
dest[idx + 4].Click += (o, e) => dest[idx + 4].Click += (o, e) =>
{ {
@ -313,7 +319,9 @@ namespace BizHawk.Client.EmuHawk
Type type = tool.GetType(); Type type = tool.GetType();
var props = type.GetPropertiesWithAttrib(typeof(ConfigPersistAttribute)).ToList(); var props = type.GetPropertiesWithAttrib(typeof(ConfigPersistAttribute)).ToList();
if (props.Count == 0) if (props.Count == 0)
{
return; return;
}
foreach (var prop in props) foreach (var prop in props)
{ {
@ -329,18 +337,19 @@ namespace BizHawk.Client.EmuHawk
// back on regular object serialization when needed. so try to undo a TypeConverter // back on regular object serialization when needed. so try to undo a TypeConverter
// operation here // operation here
var converter = TypeDescriptor.GetConverter(prop.PropertyType); var converter = TypeDescriptor.GetConverter(prop.PropertyType);
val = converter.ConvertFromString(null,System.Globalization.CultureInfo.InvariantCulture,((string)val)); val = converter.ConvertFromString(null, System.Globalization.CultureInfo.InvariantCulture, (string)val);
} }
else if (!(val is bool) && prop.PropertyType.IsPrimitive) else if (!(val is bool) && prop.PropertyType.IsPrimitive)
{ {
// numeric constanst are similarly hosed // numeric constanst are similarly hosed
val = Convert.ChangeType(val, prop.PropertyType, System.Globalization.CultureInfo.InvariantCulture); val = Convert.ChangeType(val, prop.PropertyType, System.Globalization.CultureInfo.InvariantCulture);
} }
prop.SetValue(tool, val, null); prop.SetValue(tool, val, null);
} }
} }
(tool as Form).FormClosing += (o, e) => SaveCustomConfig(tool, data, props); ((Form)tool).FormClosing += (o, e) => SaveCustomConfig(tool, data, props);
} }
private static void SaveCustomConfig(IToolForm tool, Dictionary<string, object> data, List<PropertyInfo> props) private static void SaveCustomConfig(IToolForm tool, Dictionary<string, object> data, List<PropertyInfo> props)
@ -352,13 +361,13 @@ namespace BizHawk.Client.EmuHawk
} }
} }
/// <summary> /// <summary>
/// Determines whether a given IToolForm is already loaded /// Determines whether a given IToolForm is already loaded
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool to check</typeparam>
public bool IsLoaded<T>() where T : IToolForm public bool IsLoaded<T>() where T : IToolForm
{ {
var existingTool = _tools.FirstOrDefault(x => x is T); var existingTool = _tools.FirstOrDefault(t => t is T);
if (existingTool != null) if (existingTool != null)
{ {
return !existingTool.IsDisposed; return !existingTool.IsDisposed;
@ -376,14 +385,16 @@ namespace BizHawk.Client.EmuHawk
/// <summary> /// <summary>
/// Returns true if an instance of T exists /// Returns true if an instance of T exists
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool to check</typeparam>
public bool Has<T>() where T : IToolForm public bool Has<T>() where T : IToolForm
{ {
return _tools.Any(x => x is T && !x.IsDisposed); return _tools.Any(t => t is T && !t.IsDisposed);
} }
/// <summary> /// <summary>
/// Gets the instance of T, or creates and returns a new instance /// Gets the instance of T, or creates and returns a new instance
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool to get</typeparam>
public IToolForm Get<T>() where T : class, IToolForm public IToolForm Get<T>() where T : class, IToolForm
{ {
return Load<T>(false); return Load<T>(false);
@ -393,53 +404,58 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
//return _tools.Where(t => !t.IsDisposed);
return Assembly return Assembly
.GetAssembly(typeof(IToolForm)) .GetAssembly(typeof(IToolForm))
.GetTypes() .GetTypes()
.Where(t => typeof(IToolForm).IsAssignableFrom(t)) .Where(t => typeof(IToolForm).IsAssignableFrom(t))
.Where(t => !t.IsInterface) .Where(t => !t.IsInterface)
.Where(t => IsAvailable(t)); .Where(IsAvailable);
} }
} }
public void UpdateBefore() public void UpdateBefore()
{ {
var beforeList = _tools.Where(x => x.UpdateBefore); var beforeList = _tools.Where(t => t.UpdateBefore);
foreach (var tool in beforeList) foreach (var tool in beforeList)
{ {
if (!tool.IsDisposed || if (!tool.IsDisposed
(tool is RamWatch && Global.Config.DisplayRamWatch)) // RAM Watch hack, on screen display should run even if RAM Watch is closed || (tool is RamWatch && Global.Config.DisplayRamWatch)) // RAM Watch hack, on screen display should run even if RAM Watch is closed
{ {
tool.UpdateValues(); tool.UpdateValues();
} }
} }
foreach (var tool in _tools) foreach (var tool in _tools)
{
tool.NewUpdate(ToolFormUpdateType.PreFrame); tool.NewUpdate(ToolFormUpdateType.PreFrame);
}
} }
public void UpdateAfter() public void UpdateAfter()
{ {
var afterList = _tools.Where(x => !x.UpdateBefore); var afterList = _tools.Where(t => !t.UpdateBefore);
foreach (var tool in afterList) foreach (var tool in afterList)
{ {
if (!tool.IsDisposed || if (!tool.IsDisposed
(tool is RamWatch && Global.Config.DisplayRamWatch)) // RAM Watch hack, on screen display should run even if RAM Watch is closed || (tool is RamWatch && Global.Config.DisplayRamWatch)) // RAM Watch hack, on screen display should run even if RAM Watch is closed
{ {
tool.UpdateValues(); tool.UpdateValues();
} }
} }
foreach (var tool in _tools) foreach (var tool in _tools)
{
tool.NewUpdate(ToolFormUpdateType.PostFrame); tool.NewUpdate(ToolFormUpdateType.PostFrame);
}
} }
/// <summary> /// <summary>
/// Calls UpdateValues() on an instance of T, if it exists /// Calls UpdateValues() on an instance of T, if it exists
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool to update</typeparam>
public void UpdateValues<T>() where T : IToolForm public void UpdateValues<T>() where T : IToolForm
{ {
var tool = _tools.FirstOrDefault(x => x is T); var tool = _tools.FirstOrDefault(t => t is T);
if (tool != null) if (tool != null)
{ {
if (!tool.IsDisposed || if (!tool.IsDisposed ||
@ -488,13 +504,11 @@ namespace BizHawk.Client.EmuHawk
/// <summary> /// <summary>
/// Calls Restart() on an instance of T, if it exists /// Calls Restart() on an instance of T, if it exists
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool to restart</typeparam>
public void Restart<T>() where T : IToolForm public void Restart<T>() where T : IToolForm
{ {
var tool = _tools.FirstOrDefault(x => x is T); var tool = _tools.FirstOrDefault(t => t is T);
if (tool != null) tool?.Restart();
{
tool.Restart();
}
} }
/// <summary> /// <summary>
@ -516,6 +530,7 @@ namespace BizHawk.Client.EmuHawk
/// Calls AskSave() on an instance of T, if it exists, else returns true /// 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 /// The caller should interpret false as cancel and will back out of the action that invokes this call
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool</typeparam>
public bool AskSave<T>() where T : IToolForm public bool AskSave<T>() where T : IToolForm
{ {
if (Global.Config.SupressAskSave) // User has elected to not be nagged if (Global.Config.SupressAskSave) // User has elected to not be nagged
@ -523,23 +538,22 @@ namespace BizHawk.Client.EmuHawk
return true; return true;
} }
var tool = _tools.FirstOrDefault(x => x is T); var tool = _tools.FirstOrDefault(t => t is T);
if (tool != null) if (tool != null)
{ {
return tool.AskSaveChanges(); return tool.AskSaveChanges();
} }
else
{ return false;
return false;
}
} }
/// <summary> /// <summary>
/// If T exists, this call will close the tool, and remove it from memory /// If T exists, this call will close the tool, and remove it from memory
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool to close</typeparam>
public void Close<T>() where T : IToolForm public void Close<T>() where T : IToolForm
{ {
var tool = _tools.FirstOrDefault(x => x is T); var tool = _tools.FirstOrDefault(t => t is T);
if (tool != null) if (tool != null)
{ {
tool.Close(); tool.Close();
@ -549,7 +563,7 @@ namespace BizHawk.Client.EmuHawk
public void Close(Type toolType) public void Close(Type toolType)
{ {
var tool = _tools.FirstOrDefault(x => toolType.IsAssignableFrom(x.GetType())); var tool = _tools.FirstOrDefault(toolType.IsInstanceOfType);
if (tool != null) if (tool != null)
{ {
@ -560,7 +574,7 @@ namespace BizHawk.Client.EmuHawk
public void Close() public void Close()
{ {
_tools.ForEach(x => x.Close()); _tools.ForEach(t => t.Close());
_tools.Clear(); _tools.Clear();
} }
@ -568,7 +582,7 @@ namespace BizHawk.Client.EmuHawk
/// Create a new instance of an IToolForm and return it /// Create a new instance of an IToolForm and return it
/// </summary> /// </summary>
/// <typeparam name="T">Type of tool you want to create</typeparam> /// <typeparam name="T">Type of tool you want to create</typeparam>
/// <param name="dllPath">Path dll for an external tool</param> /// <param name="dllPath">Path .dll for an external tool</param>
/// <returns>New instance of an IToolForm</returns> /// <returns>New instance of an IToolForm</returns>
private IToolForm CreateInstance<T>(string dllPath) private IToolForm CreateInstance<T>(string dllPath)
where T : IToolForm where T : IToolForm
@ -586,13 +600,14 @@ namespace BizHawk.Client.EmuHawk
{ {
IToolForm tool; IToolForm tool;
//Specific case for custom tools // Specific case for custom tools
//TODO: Use AppDomain in order to be able to unload the assembly // TODO: Use AppDomain in order to be able to unload the assembly
//Hard stuff as we need a proxy object that inherit from MarshalByRefObject. // Hard stuff as we need a proxy object that inherit from MarshalByRefObject.
if (toolType == typeof(IExternalToolForm)) if (toolType == typeof(IExternalToolForm))
{ {
if (MessageBox.Show("Are you sure want to load this external tool?\r\nAccept ONLY if you trust the source and if you know what you're doing. In any other case, choose no." if (MessageBox.Show(
, "Confirmm loading", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) "Are you sure want to load this external tool?\r\nAccept ONLY if you trust the source and if you know what you're doing. In any other case, choose no.",
"Confirmm loading", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{ {
try try
{ {
@ -662,11 +677,11 @@ namespace BizHawk.Client.EmuHawk
public void FastUpdateBefore() public void FastUpdateBefore()
{ {
var beforeList = _tools.Where(x => x.UpdateBefore); var beforeList = _tools.Where(t => t.UpdateBefore);
foreach (var tool in beforeList) foreach (var tool in beforeList)
{ {
if (!tool.IsDisposed || if (!tool.IsDisposed
(tool is RamWatch && Global.Config.DisplayRamWatch)) // RAM Watch hack, on screen display should run even if RAM Watch is closed || (tool is RamWatch && Global.Config.DisplayRamWatch)) // RAM Watch hack, on screen display should run even if RAM Watch is closed
{ {
tool.FastUpdate(); tool.FastUpdate();
} }
@ -680,11 +695,11 @@ namespace BizHawk.Client.EmuHawk
LuaConsole.ResumeScripts(true); LuaConsole.ResumeScripts(true);
} }
var afterList = _tools.Where(x => !x.UpdateBefore); var afterList = _tools.Where(t => !t.UpdateBefore);
foreach (var tool in afterList) foreach (var tool in afterList)
{ {
if (!tool.IsDisposed || if (!tool.IsDisposed
(tool is RamWatch && Global.Config.DisplayRamWatch)) // RAM Watch hack, on screen display should run even if RAM Watch is closed || (tool is RamWatch && Global.Config.DisplayRamWatch)) // RAM Watch hack, on screen display should run even if RAM Watch is closed
{ {
tool.FastUpdate(); tool.FastUpdate();
} }
@ -722,13 +737,8 @@ namespace BizHawk.Client.EmuHawk
.OfType<ToolAttributes>() .OfType<ToolAttributes>()
.FirstOrDefault(); .FirstOrDefault();
if (attr == null) // If no attributes there is no supported systems documented so assume all
{
return true;
}
// If no supported systems mentioned assume all // If no supported systems mentioned assume all
if (attr.SupportedSystems != null && attr.SupportedSystems.Any()) if (attr?.SupportedSystems != null && attr.SupportedSystems.Any())
{ {
return attr.SupportedSystems.Contains(Global.Emulator.SystemId); return attr.SupportedSystems.Contains(Global.Emulator.SystemId);
} }
@ -743,7 +753,7 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
var tool = _tools.FirstOrDefault(x => x is RamWatch); var tool = _tools.FirstOrDefault(t => t is RamWatch);
if (tool != null) if (tool != null)
{ {
if (tool.IsDisposed) if (tool.IsDisposed)
@ -766,7 +776,7 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
var tool = _tools.FirstOrDefault(x => x is RamSearch); var tool = _tools.FirstOrDefault(t => t is RamSearch);
if (tool != null) if (tool != null)
{ {
if (tool.IsDisposed) if (tool.IsDisposed)
@ -789,7 +799,7 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
var tool = _tools.FirstOrDefault(x => x is Cheats); var tool = _tools.FirstOrDefault(t => t is Cheats);
if (tool != null) if (tool != null)
{ {
if (tool.IsDisposed) if (tool.IsDisposed)
@ -812,7 +822,7 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
var tool = _tools.FirstOrDefault(x => x is HexEditor); var tool = _tools.FirstOrDefault(t => t is HexEditor);
if (tool != null) if (tool != null)
{ {
if (tool.IsDisposed) if (tool.IsDisposed)
@ -835,7 +845,7 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
var tool = _tools.FirstOrDefault(x => x is VirtualpadTool); var tool = _tools.FirstOrDefault(t => t is VirtualpadTool);
if (tool != null) if (tool != null)
{ {
if (tool.IsDisposed) if (tool.IsDisposed)
@ -858,7 +868,7 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
var tool = _tools.FirstOrDefault(x => x is SNESGraphicsDebugger); var tool = _tools.FirstOrDefault(t => t is SNESGraphicsDebugger);
if (tool != null) if (tool != null)
{ {
if (tool.IsDisposed) if (tool.IsDisposed)
@ -881,7 +891,7 @@ namespace BizHawk.Client.EmuHawk
{ {
get get
{ {
var tool = _tools.FirstOrDefault(x => x is LuaConsole); var tool = _tools.FirstOrDefault(t => t is LuaConsole);
if (tool != null) if (tool != null)
{ {
if (tool.IsDisposed) if (tool.IsDisposed)
@ -906,9 +916,11 @@ namespace BizHawk.Client.EmuHawk
{ {
// prevent nasty silent corruption // prevent nasty silent corruption
if (!GlobalWin.Tools.IsLoaded<TAStudio>()) if (!GlobalWin.Tools.IsLoaded<TAStudio>())
{
System.Diagnostics.Debug.Fail("TAStudio does not exist!"); System.Diagnostics.Debug.Fail("TAStudio does not exist!");
}
var tool = _tools.FirstOrDefault(x => x is TAStudio); var tool = _tools.FirstOrDefault(t => t is TAStudio);
if (tool != null) if (tool != null)
{ {
if (tool.IsDisposed) if (tool.IsDisposed)