From 7c9f7706d3256a6ce376b7f86c80f59027739127 Mon Sep 17 00:00:00 2001
From: scepheo <scepheo@gmail.com>
Date: Sun, 14 Dec 2014 02:15:19 +0000
Subject: [PATCH] ToolManager: added compile-time unknown type version of Load
 and methods it uses.

---
 .../BizHawk.Client.EmuHawk.csproj             |  1 -
 BizHawk.Client.EmuHawk/tools/ToolManager.cs   | 83 ++++++++++++++-----
 2 files changed, 61 insertions(+), 23 deletions(-)

diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
index 4161395d82..86e5b0a348 100644
--- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
+++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
@@ -539,7 +539,6 @@
     </Compile>
     <Compile Include="MainForm.Hotkey.cs">
       <DependentUpon>MainForm.cs</DependentUpon>
-      <SubType>Form</SubType>
     </Compile>
     <Compile Include="MainForm.Movie.cs">
       <DependentUpon>MainForm.cs</DependentUpon>
diff --git a/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/BizHawk.Client.EmuHawk/tools/ToolManager.cs
index 60809a972a..97cd722e12 100644
--- a/BizHawk.Client.EmuHawk/tools/ToolManager.cs
+++ b/BizHawk.Client.EmuHawk/tools/ToolManager.cs
@@ -20,33 +20,44 @@ namespace BizHawk.Client.EmuHawk
 		/// </summary>
 		public IToolForm Load<T>() where T : IToolForm
 		{
-			if (IsAvailable(typeof(T)))
+			return Load(typeof(T));
+		}
+
+		/// <summary>
+		/// Loads a tool dialog of type toolType if it does not exist it will be
+		/// created, if it is already open, it will be focused.
+		/// </summary>
+		public IToolForm Load(Type toolType)
+		{
+			if (!typeof(IToolForm).IsAssignableFrom(toolType))
+				throw new ArgumentException(String.Format("Type {0} does not implement IToolForm.", toolType.Name));
+
+			if (!IsAvailable(toolType))
+				return null;
+
+			var existingTool = _tools.FirstOrDefault(x => toolType.IsAssignableFrom(x.GetType()));
+
+			if (existingTool != null)
 			{
-				var existingTool = _tools.FirstOrDefault(x => x is T);
-				if (existingTool != null)
+				if (existingTool.IsDisposed)
 				{
-					if (existingTool.IsDisposed)
-					{
-						_tools.Remove(existingTool);
-					}
-					else
-					{
-						existingTool.Show();
-						existingTool.Focus();
-						return existingTool;
-					}
+					_tools.Remove(existingTool);
+				}
+				else
+				{
+					existingTool.Show();
+					existingTool.Focus();
+					return existingTool;
 				}
-
-				var result = Get<T>();
-
-				UpdateServices(result);
-				result.Restart();
-
-				result.Show();
-				return result;
 			}
 
-			return null;
+			var newTool = CreateInstance(toolType);
+
+			UpdateServices(newTool);
+			newTool.Restart();
+
+			newTool.Show();
+			return newTool;
 		}
 
 		/// <summary>
@@ -294,6 +305,17 @@ namespace BizHawk.Client.EmuHawk
 			}
 		}
 
+		public void Close(Type toolType)
+		{
+			var tool = _tools.FirstOrDefault(x => toolType.IsAssignableFrom(x.GetType()));
+
+			if (tool != null)
+			{
+				tool.Close();
+				_tools.Remove(tool);
+			}
+		}
+
 		public void Close()
 		{
 			_tools.ForEach(x => x.Close());
@@ -309,6 +331,15 @@ namespace BizHawk.Client.EmuHawk
 			return _tools.FirstOrDefault(x => x is T);
 		}
 
+		private IToolForm CreateInstance(Type toolType)
+		{
+			var tool = (IToolForm)Activator.CreateInstance(toolType);
+
+			// Add to our list of tools
+			_tools.Add(tool);
+			return tool;
+		}
+
 		private void CloseIfDisposed<T>() where T : IToolForm
 		{
 			var existingTool = _tools.FirstOrDefault(x => x is T);
@@ -557,6 +588,14 @@ namespace BizHawk.Client.EmuHawk
 			}
 		}
 
+		public void LoadTraceLogger()
+		{
+			if (Global.Emulator.CpuTraceAvailable())
+			{
+				Load<TraceLogger>();
+			}
+		}
+
 		public void LoadGameGenieEc()
 		{
 			if (Global.Emulator.SystemId == "NES")