diff --git a/BizHawk.Client.ApiHawk/Attributes/BizHawkExternalToolAttribute.cs b/BizHawk.Client.ApiHawk/Attributes/BizHawkExternalToolAttribute.cs
index 134a3ab3f01..112a073ad9b 100644
--- a/BizHawk.Client.ApiHawk/Attributes/BizHawkExternalToolAttribute.cs
+++ b/BizHawk.Client.ApiHawk/Attributes/BizHawkExternalToolAttribute.cs
@@ -1,67 +1,26 @@
using System;
+using BizHawk.Client.Common;
+
namespace BizHawk.Client.ApiHawk
{
- ///
- /// This class holds logic interaction for the ExternalToolAttribute
- /// This attribute helps BizHawk to handle ExternalTools
- ///
+ /// This class needs to be in the assembly or old tools will throw on load instead of being recognised as old.
[AttributeUsage(AttributeTargets.Assembly)]
+ [Obsolete("last used in 2.4, use [ExternalTool] instead")]
public sealed class BizHawkExternalToolAttribute : Attribute
{
- #region cTor(s)
-
- ///
- /// Initialize a new instance of
- ///
- /// Tool's name
- /// Small description about the tool itself
- /// Icon embedded resource name
- public BizHawkExternalToolAttribute(string name, string description, string iconResourceName)
- {
- Name = name;
- Description = description;
- IconResourceName = iconResourceName;
- }
-
- ///
- /// Initialize a new instance of
- ///
- /// Tool's name
- /// Small description about the tool itself
- public BizHawkExternalToolAttribute(string name, string description)
- : this(name, description, "")
- { }
-
- ///
- /// Initialize a new instance of
- ///
- /// Tool's name
- public BizHawkExternalToolAttribute(string name)
- :this(name, "", "")
- {}
-
- #endregion
-
- #region Properties
-
- ///
- /// Gets tool's friendly name
- ///
- public string Name { get; }
-
- ///
- /// Gets tool's description
- ///
- public string Description { get; }
-
-
- ///
- /// Get the name of the embedded resource icon
- ///
- /// Don't forget to set compile => Embedded resource to the icon file in your project
- public string IconResourceName { get; }
+ public BizHawkExternalToolAttribute(string name, string description, string iconResourceName) {}
+ public BizHawkExternalToolAttribute(string name, string description) {}
+ public BizHawkExternalToolAttribute(string name) {}
+ }
- #endregion
+ ///
+ [AttributeUsage(AttributeTargets.Assembly)]
+ [Obsolete("last used in 2.4, use [ExternalToolApplicability.*] instead")]
+ public sealed class BizHawkExternalToolUsageAttribute : Attribute
+ {
+ public BizHawkExternalToolUsageAttribute(BizHawkExternalToolUsage usage, CoreSystem system, string gameHash) {}
+ public BizHawkExternalToolUsageAttribute(BizHawkExternalToolUsage usage, CoreSystem system) {}
+ public BizHawkExternalToolUsageAttribute() {}
}
}
diff --git a/BizHawk.Client.ApiHawk/Attributes/BizHawkExternalToolUsageAttribute.cs b/BizHawk.Client.ApiHawk/Attributes/BizHawkExternalToolUsageAttribute.cs
deleted file mode 100644
index e98d84d673a..00000000000
--- a/BizHawk.Client.ApiHawk/Attributes/BizHawkExternalToolUsageAttribute.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using System;
-
-using BizHawk.Client.Common;
-
-namespace BizHawk.Client.ApiHawk
-{
- ///
- /// This class holds logic interaction for the BizHawkExternalToolUsageAttribute
- /// This attribute helps ApiHawk to know how a tool can be enabled or not
- ///
- [AttributeUsage(AttributeTargets.Assembly)]
- public sealed class BizHawkExternalToolUsageAttribute : Attribute
- {
- #region cTor(s)
-
- ///
- /// is and is , or
- /// usage is and is blank
- ///
- public BizHawkExternalToolUsageAttribute(BizHawkExternalToolUsage usage, CoreSystem system, string gameHash)
- {
- if (usage == BizHawkExternalToolUsage.EmulatorSpecific && system == CoreSystem.Null)
- {
- throw new InvalidOperationException("A system must be set");
- }
- if (usage == BizHawkExternalToolUsage.GameSpecific && gameHash.Trim() == "")
- {
- throw new InvalidOperationException("A game hash must be set");
- }
-
- ToolUsage = usage;
- System = system;
- GameHash = gameHash;
- }
-
- ///
- /// Initialize a new instance of
- ///
- /// i.e. what your external tool is for
- /// that your external tool is used for
- public BizHawkExternalToolUsageAttribute(BizHawkExternalToolUsage usage, CoreSystem system)
- :this(usage, system, "")
- {}
-
- ///
- /// Initialize a new instance of
- ///
- public BizHawkExternalToolUsageAttribute()
- :this(BizHawkExternalToolUsage.Global, CoreSystem.Null, "")
- { }
-
-
- #endregion
-
- #region Properties
-
- ///
- /// Gets the specific system used by the external tool
- ///
- public CoreSystem System { get; }
-
-
- ///
- /// Gets the specific game (hash) used by the external tool
- ///
- public string GameHash { get; }
-
- ///
- /// Gets the tool usage
- ///
- public BizHawkExternalToolUsage ToolUsage { get; }
-
- #endregion
- }
-}
diff --git a/BizHawk.Client.ApiHawk/Classes/ExternalToolManager.cs b/BizHawk.Client.ApiHawk/Classes/ExternalToolManager.cs
index 6a4d669e180..a128fbd5eb2 100644
--- a/BizHawk.Client.ApiHawk/Classes/ExternalToolManager.cs
+++ b/BizHawk.Client.ApiHawk/Classes/ExternalToolManager.cs
@@ -71,101 +71,78 @@ private static void BuildToolStrip()
}
}
- ///
- /// Generate a from an
- /// external tool dll.
- /// The assembly must have in its
- /// assembly attributes
- ///
- /// File that will be reflected
- /// A new ; assembly path can be found in the Tag property
- /// For the moment, you could only load a dll that have a form (which implements )
+ /// Generates a from an assembly at containing an external tool.
+ ///
+ /// a with its containing a (string, string);
+ /// the first is the assembly path () and the second is the of the entry point form's type
+ ///
private static ToolStripMenuItem GenerateToolTipFromFileName(string fileName)
{
- ToolStripMenuItem item = null;
-
+ if (fileName == null) throw new Exception();
+ var item = new ToolStripMenuItem(Path.GetFileName(fileName)) { Enabled = false };
try
{
if (!OSTailoredCode.IsUnixHost) MotWHack.RemoveMOTW(fileName);
var externalToolFile = Assembly.LoadFrom(fileName);
- object[] attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolAttribute), false);
- if (attributes != null && attributes.Count() == 1)
+ var entryPoint = externalToolFile.GetTypes()
+ .SingleOrDefault(t => typeof(IExternalToolForm).IsAssignableFrom(t) && t.GetCustomAttributes().OfType().Any());
+#pragma warning disable CS0618
+ if (entryPoint == null) throw new ExternalToolAttribute.MissingException(externalToolFile.GetCustomAttributes().OfType().Any());
+#pragma warning restore CS0618
+
+ var allAttrs = entryPoint.GetCustomAttributes().ToList();
+ var applicabilityAttrs = allAttrs.OfType().ToList();
+ if (applicabilityAttrs.Count > 1) throw new ExternalToolApplicabilityAttributeBase.DuplicateException();
+
+ var toolAttribute = allAttrs.OfType().First();
+ var embeddedIconAttr = allAttrs.OfType().FirstOrDefault();
+ if (embeddedIconAttr != null)
{
- BizHawkExternalToolAttribute attribute = (BizHawkExternalToolAttribute)attributes[0];
- item = new ToolStripMenuItem(attribute.Name) { ToolTipText = attribute.Description };
- if (attribute.IconResourceName != "")
- {
- Stream s = externalToolFile.GetManifestResourceStream($"{externalToolFile.GetName().Name}.{attribute.IconResourceName}");
- if (s != null)
- {
- item.Image = new Bitmap(s);
- }
- }
-
- var availTypes = externalToolFile.GetTypes();
- var customFormType = availTypes.FirstOrDefault(t => t.FullName == "BizHawk.Client.EmuHawk.CustomMainForm")
- ?? availTypes.SingleOrDefault(t => typeof(IExternalToolForm).IsAssignableFrom(t) && t.CustomAttributes.Any(cad => cad.AttributeType == typeof(ExternalToolEntryPointFormAttribute)));
- if (customFormType == null)
+ var rawIcon = externalToolFile.GetManifestResourceStream(embeddedIconAttr.ResourcePath);
+ if (rawIcon != null) item.Image = new Bitmap(rawIcon);
+ }
+ item.Text = toolAttribute.Name;
+ item.Tag = (externalToolFile.Location, entryPoint.FullName); // Tag set => no errors (show custom icon even when disabled)
+ if (applicabilityAttrs.Count == 1)
+ {
+ var system = ClientApi.SystemIdConverter.Convert(Global.Emulator.SystemId);
+ if (applicabilityAttrs[0].NotApplicableTo(system))
{
- item.ToolTipText = "Does not have a correctly-formatted CustomMainForm or a form decorated with [ExternalToolEntryPointForm]";
- item.Enabled = false;
+ item.ToolTipText = system == CoreSystem.Null
+ ? "This tool doesn't work when no rom is loaded"
+ : "This tool doesn't work with this system";
+ return item;
}
- item.Tag = (fileName, customFormType?.FullName);
-
- attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolUsageAttribute), false);
- if (attributes != null && attributes.Length == 1)
+ if (applicabilityAttrs[0].NotApplicableTo(Global.Game.Hash, system))
{
- BizHawkExternalToolUsageAttribute attribute2 = (BizHawkExternalToolUsageAttribute)attributes[0];
- if(Global.Emulator.SystemId == "NULL" && attribute2.ToolUsage != BizHawkExternalToolUsage.Global)
- {
- item.ToolTipText = "This tool doesn't work if nothing is loaded";
- item.Enabled = false;
- }
- else if(attribute2.ToolUsage == BizHawkExternalToolUsage.EmulatorSpecific && Global.Emulator.SystemId != ClientApi.SystemIdConverter.ConvertBack(attribute2.System))
- {
- item.ToolTipText = "This tool doesn't work for current system";
- item.Enabled = false;
- }
- else if (attribute2.ToolUsage == BizHawkExternalToolUsage.GameSpecific && Global.Game.Hash != attribute2.GameHash)
- {
- item.ToolTipText = "This tool doesn't work for current game";
- item.Enabled = false;
- }
+ item.ToolTipText = "This tool doesn't work with this game";
+ return item;
}
}
- else
- {
- item = new ToolStripMenuItem(externalToolFile.GetName().Name)
- {
- ToolTipText = "BizHawkExternalTool attribute hasn't been found", Enabled = false
- };
- }
- }
- catch (BadImageFormatException)
- {
- item = new ToolStripMenuItem(fileName);
- item.ToolTipText = "This is not an assembly";
- item.Enabled = false;
- }
-#if DEBUG //I added special debug stuff to get additional information. Don't think it can be useful for released versions
- catch (ReflectionTypeLoadException ex)
+ item.Enabled = true;
+ if (!string.IsNullOrWhiteSpace(toolAttribute.Description)) item.ToolTipText = toolAttribute.Description;
+ return item;
+ }
+ catch (Exception e)
{
- foreach (Exception e in ex.LoaderExceptions)
+#if DEBUG
+ if (e is ReflectionTypeLoadException rtle)
{
- Debug.WriteLine(e.Message);
+ foreach (var e1 in rtle.LoaderExceptions) Debug.WriteLine(e1.Message);
}
- item.ToolTipText = "Something goes wrong while trying to load";
- item.Enabled = false;
- }
-#else
- catch (ReflectionTypeLoadException)
- {
- item.ToolTipText = "Something goes wrong while trying to load";
- item.Enabled = false;
- }
#endif
-
+ item.ToolTipText = e switch
+ {
+ BadImageFormatException _ => "This assembly can't be loaded, probably because it's corrupt or targets an incompatible .NET runtime.",
+ ExternalToolApplicabilityAttributeBase.DuplicateException _ => "The IExternalToolForm has conflicting applicability attributes.",
+ ExternalToolAttribute.MissingException e1 => e1.OldAttributeFound
+ ? "The assembly doesn't contain a class implementing IExternalToolForm and annotated with [ExternalTool].\nHowever, the assembly itself is annotated with [BizHawkExternalTool], which is now deprecated. Has the tool been updated since BizHawk 2.4?"
+ : "The assembly doesn't contain a class implementing IExternalToolForm and annotated with [ExternalTool].",
+ ReflectionTypeLoadException _ => "Something went wrong while trying to load the assembly.",
+ _ => $"An exception of type {e.GetType().FullName} was thrown while trying to load the assembly and look for an IExternalToolForm:\n{e.Message}"
+ };
+ }
return item;
}
diff --git a/BizHawk.Client.Common/Api/ExternalToolAttributes.cs b/BizHawk.Client.Common/Api/ExternalToolAttributes.cs
new file mode 100644
index 00000000000..0c572fc5642
--- /dev/null
+++ b/BizHawk.Client.Common/Api/ExternalToolAttributes.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using BizHawk.Common.StringExtensions;
+
+namespace BizHawk.Client.Common
+{
+ public static class ExternalToolApplicability
+ {
+ /// This class is not deprecated, do not remove it.
+ [AttributeUsage(AttributeTargets.Class)]
+ [Obsolete("this is the default behaviour, you can safely omit this attribute")]
+ public sealed class Always : ExternalToolApplicabilityAttributeBase
+ {
+ public override bool NotApplicableTo(CoreSystem system) => false;
+
+ public override bool NotApplicableTo(string romHash, CoreSystem? system) => false;
+ }
+
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class AnyRomLoaded : ExternalToolApplicabilityAttributeBase
+ {
+ public override bool NotApplicableTo(CoreSystem system) => system == CoreSystem.Null;
+
+ public override bool NotApplicableTo(string romHash, CoreSystem? system) => system == CoreSystem.Null;
+ }
+
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class RomWhitelist : ExternalToolApplicabilityAttributeBase
+ {
+ private readonly IList _romHashes;
+
+ private readonly CoreSystem _system;
+
+ public RomWhitelist(CoreSystem system, params string[] romHashes)
+ {
+ if (system == CoreSystem.Null) throw new ArgumentException("there are no roms for the NULL system", nameof(system));
+ if (!romHashes.All(StringExtensions.IsHex)) throw new ArgumentException("misformatted hash", nameof(romHashes));
+ _system = system;
+ _romHashes = romHashes.ToList();
+ }
+
+ public override bool NotApplicableTo(CoreSystem system) => system != _system;
+
+ public override bool NotApplicableTo(string romHash, CoreSystem? system) => system != _system || !_romHashes.Contains(romHash);
+ }
+
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class SingleRom : ExternalToolApplicabilityAttributeBase
+ {
+ private readonly string _romHash;
+
+ private readonly CoreSystem _system;
+
+ public SingleRom(CoreSystem system, string romHash)
+ {
+ if (system == CoreSystem.Null) throw new ArgumentException("there are no roms for the NULL system", nameof(system));
+ if (!romHash.IsHex()) throw new ArgumentException("misformatted hash", nameof(romHash));
+ _system = system;
+ _romHash = romHash;
+ }
+
+ public override bool NotApplicableTo(CoreSystem system) => system != _system;
+
+ public override bool NotApplicableTo(string romHash, CoreSystem? system) => system != _system || romHash != _romHash;
+ }
+
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class SingleSystem : ExternalToolApplicabilityAttributeBase
+ {
+ private readonly CoreSystem _system;
+
+ public SingleSystem(CoreSystem system)
+ {
+ _system = system;
+ }
+
+ public override bool NotApplicableTo(CoreSystem system) => system != _system;
+
+ public override bool NotApplicableTo(string romHash, CoreSystem? system) => system != _system;
+ }
+ }
+
+ public abstract class ExternalToolApplicabilityAttributeBase : Attribute
+ {
+ public abstract bool NotApplicableTo(CoreSystem system);
+
+ public abstract bool NotApplicableTo(string romHash, CoreSystem? system);
+
+ public bool NotApplicableTo(string romHash) => NotApplicableTo(romHash, null);
+
+ public class DuplicateException : Exception {}
+ }
+
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class ExternalToolAttribute : Attribute
+ {
+ public readonly string Description;
+
+ public readonly string Name;
+
+ public ExternalToolAttribute(string name, string description = null)
+ {
+ Description = description;
+ Name = string.IsNullOrWhiteSpace(name) ? Guid.NewGuid().ToString() : name;
+ }
+
+ public class MissingException : Exception
+ {
+ public readonly bool OldAttributeFound;
+
+ public MissingException(bool oldAttributeFound)
+ {
+ OldAttributeFound = oldAttributeFound;
+ }
+ }
+ }
+
+ public sealed class ExternalToolEmbeddedIconAttribute : Attribute
+ {
+ /// The full path, including the assembly name.
+ public readonly string ResourcePath;
+
+ /// The full path, including the assembly name.
+ public ExternalToolEmbeddedIconAttribute(string resourcePath)
+ {
+ ResourcePath = resourcePath;
+ }
+ }
+}
diff --git a/BizHawk.Client.Common/Api/ExternalToolEntryPointFormAttribute.cs b/BizHawk.Client.Common/Api/ExternalToolEntryPointFormAttribute.cs
deleted file mode 100644
index b6e457167c6..00000000000
--- a/BizHawk.Client.Common/Api/ExternalToolEntryPointFormAttribute.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using System;
-
-namespace BizHawk.Client.Common
-{
- [AttributeUsage(AttributeTargets.Class)]
- public class ExternalToolEntryPointFormAttribute : Attribute {}
-}
diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs
index c2e080f5c47..4f4038de0fb 100644
--- a/BizHawk.Client.EmuHawk/MainForm.Events.cs
+++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs
@@ -1411,13 +1411,12 @@ private void ExternalToolMenuItem_DropDownOpening(object sender, EventArgs e)
foreach (var item in ExternalToolManager.ToolStripMenu)
{
- if (item.Enabled)
+ if (item.Tag is ValueTuple tuple)
{
- item.Click += delegate
+ if (item.Enabled)
{
- var (fileName, customFormTypeName) = ((string, string)) item.Tag;
- Tools.LoadExternalToolForm(fileName, customFormTypeName);
- };
+ item.Click += (clickEventSender, clickEventArgs) => Tools.LoadExternalToolForm(tuple.Item1, tuple.Item2);
+ }
}
else
{
diff --git a/ExternalToolProjects/AutoGenConfig/AutoGenConfig.csproj b/ExternalToolProjects/AutoGenConfig/AutoGenConfig.csproj
index b5f4c56262e..83fca47a524 100644
--- a/ExternalToolProjects/AutoGenConfig/AutoGenConfig.csproj
+++ b/ExternalToolProjects/AutoGenConfig/AutoGenConfig.csproj
@@ -2,6 +2,6 @@
-
+
diff --git a/ExternalToolProjects/AutoGenConfig/CustomMainForm.cs b/ExternalToolProjects/AutoGenConfig/AutoGenConfigForm.cs
similarity index 91%
rename from ExternalToolProjects/AutoGenConfig/CustomMainForm.cs
rename to ExternalToolProjects/AutoGenConfig/AutoGenConfigForm.cs
index 8e2f2b8a515..154dd0e0585 100644
--- a/ExternalToolProjects/AutoGenConfig/CustomMainForm.cs
+++ b/ExternalToolProjects/AutoGenConfig/AutoGenConfigForm.cs
@@ -9,11 +9,12 @@
using BizHawk.Client.ApiHawk;
using BizHawk.Client.Common;
-using static BizHawk.Client.EmuHawk.ConfigEditorUIGenerators;
+using static BizHawk.Experiment.AutoGenConfig.ConfigEditorUIGenerators;
-namespace BizHawk.Client.EmuHawk
+namespace BizHawk.Experiment.AutoGenConfig
{
- public class CustomMainForm : Form, IExternalToolForm
+ [ExternalTool("AutoGenConfig")]
+ public class AutoGenConfigForm : Form, IExternalToolForm
{
private static readonly IList<(PropertyInfo, IConfigPropEditorUIGen)> CachedControlGenerators;
@@ -28,7 +29,7 @@ public class CustomMainForm : Form, IExternalToolForm
public static readonly IDictionary DefaultValues;
- static CustomMainForm()
+ static AutoGenConfigForm()
{
CachedControlGenerators = new List<(PropertyInfo, IConfigPropEditorUIGen)>();
DefaultValues = new Dictionary();
@@ -63,7 +64,7 @@ static CustomMainForm()
public bool UpdateBefore => false;
- public CustomMainForm()
+ public AutoGenConfigForm()
{
ClientSize = new Size(640, 720);
SuspendLayout();
diff --git a/ExternalToolProjects/AutoGenConfig/ConfigEditorUIGenerators.cs b/ExternalToolProjects/AutoGenConfig/ConfigEditorUIGenerators.cs
index 156298b060f..1927cfdf2f7 100644
--- a/ExternalToolProjects/AutoGenConfig/ConfigEditorUIGenerators.cs
+++ b/ExternalToolProjects/AutoGenConfig/ConfigEditorUIGenerators.cs
@@ -8,7 +8,7 @@
using BizHawk.Client.Common;
-namespace BizHawk.Client.EmuHawk
+namespace BizHawk.Experiment.AutoGenConfig
{
public static class ConfigEditorUIGenerators
{
@@ -19,39 +19,39 @@ public static class ConfigEditorUIGenerators
public static readonly IConfigPropEditorUIGen FinalFallbackGenerator = new UnrepresentablePropEditorUIGen();
- private static Color GetComparisonColorRefT(string prop, T? currentValue, CustomMainForm parent, Func equalityFunc)
+ private static Color GetComparisonColorRefT(string prop, T? currentValue, AutoGenConfigForm parent, Func equalityFunc)
where T : class
=> equalityFunc(currentValue, parent.BaselineValues[prop] as T)
? GetInitComparisonColorRefT(prop, currentValue, equalityFunc)
- : equalityFunc(currentValue, CustomMainForm.DefaultValues[prop] as T)
- ? CustomMainForm.ComparisonColors.ChangedUnset
- : CustomMainForm.ComparisonColors.Changed;
+ : equalityFunc(currentValue, AutoGenConfigForm.DefaultValues[prop] as T)
+ ? AutoGenConfigForm.ComparisonColors.ChangedUnset
+ : AutoGenConfigForm.ComparisonColors.Changed;
- private static Color GetComparisonColorValT(string prop, T? currentValue, CustomMainForm parent, Func equalityFunc)
+ private static Color GetComparisonColorValT(string prop, T? currentValue, AutoGenConfigForm parent, Func equalityFunc)
where T : struct
=> equalityFunc(currentValue, parent.BaselineValues[prop]?.Let(it => (T) it))
? GetInitComparisonColorValT(prop, currentValue, equalityFunc)
- : equalityFunc(currentValue, CustomMainForm.DefaultValues[prop]?.Let(it => (T) it))
- ? CustomMainForm.ComparisonColors.ChangedUnset
- : CustomMainForm.ComparisonColors.Changed;
+ : equalityFunc(currentValue, AutoGenConfigForm.DefaultValues[prop]?.Let(it => (T) it))
+ ? AutoGenConfigForm.ComparisonColors.ChangedUnset
+ : AutoGenConfigForm.ComparisonColors.Changed;
private static Color GetInitComparisonColorRefT(string prop, T? currentValue, Func equalityFunc)
where T : class
- => equalityFunc(currentValue, CustomMainForm.DefaultValues[prop] as T)
- ? CustomMainForm.ComparisonColors.UnchangedDefault
- : CustomMainForm.ComparisonColors.Unchanged;
+ => equalityFunc(currentValue, AutoGenConfigForm.DefaultValues[prop] as T)
+ ? AutoGenConfigForm.ComparisonColors.UnchangedDefault
+ : AutoGenConfigForm.ComparisonColors.Unchanged;
private static Color GetInitComparisonColorValT(string prop, T? currentValue, Func equalityFunc)
where T : struct
- => equalityFunc(currentValue, CustomMainForm.DefaultValues[prop]?.Let(it => (T) it))
- ? CustomMainForm.ComparisonColors.UnchangedDefault
- : CustomMainForm.ComparisonColors.Unchanged;
+ => equalityFunc(currentValue, AutoGenConfigForm.DefaultValues[prop]?.Let(it => (T) it))
+ ? AutoGenConfigForm.ComparisonColors.UnchangedDefault
+ : AutoGenConfigForm.ComparisonColors.Unchanged;
- private static CustomMainForm GetMainFormParent(Control c)
+ private static AutoGenConfigForm GetMainFormParent(Control c)
{
var parent = c.Parent;
- while (!(parent is CustomMainForm)) parent = parent.Parent;
- return (CustomMainForm) parent;
+ while (!(parent is AutoGenConfigForm)) parent = parent.Parent;
+ return (AutoGenConfigForm) parent;
}
private static string GetPropertyNameDesc(PropertyInfo pi)
diff --git a/ExternalToolProjects/AutoGenConfig/Properties/AssemblyInfo.cs b/ExternalToolProjects/AutoGenConfig/Properties/AssemblyInfo.cs
deleted file mode 100644
index 6e1ef1482f8..00000000000
--- a/ExternalToolProjects/AutoGenConfig/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System.Drawing;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using BizHawk.Client.ApiHawk;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("AutoGenConfig")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("AutoGenConfig")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-[assembly: BizHawkExternalTool("AutoGenConfig")]
-[assembly: BizHawkExternalToolUsage()]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("34ef725e-ecfd-4e25-b7fd-5c995dd62eef")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ExternalToolProjects/AutoGenConfig/ScopingExtensions.cs b/ExternalToolProjects/AutoGenConfig/ScopingExtensions.cs
index 6c2f9bbfa18..de3918e8000 100644
--- a/ExternalToolProjects/AutoGenConfig/ScopingExtensions.cs
+++ b/ExternalToolProjects/AutoGenConfig/ScopingExtensions.cs
@@ -1,7 +1,7 @@
using System;
using System.Runtime.CompilerServices;
-namespace BizHawk.Client.EmuHawk
+namespace BizHawk.Experiment.AutoGenConfig
{
internal static class ScopingExtensions
{
diff --git a/ExternalToolProjects/DBMan/CustomMainForm.cs b/ExternalToolProjects/DBMan/CustomMainForm.cs
index 10cb45fc694..c2088fbe6e5 100644
--- a/ExternalToolProjects/DBMan/CustomMainForm.cs
+++ b/ExternalToolProjects/DBMan/CustomMainForm.cs
@@ -5,12 +5,12 @@
using BizHawk.Client.ApiHawk;
using BizHawk.Client.Common;
using BizHawk.Common;
-using BizHawk.DBManTool;
using Community.CsharpSqlite.SQLiteClient;
-namespace BizHawk.Client.EmuHawk
+namespace BizHawk.DBManTool
{
+ [ExternalTool("DBMan", "DB Manager")]
public class CustomMainForm : Form, IExternalToolForm
{
public CustomMainForm()
diff --git a/ExternalToolProjects/DBMan/Properties/AssemblyInfo.cs b/ExternalToolProjects/DBMan/Properties/AssemblyInfo.cs
index 54d1af6dd35..27b049575c8 100644
--- a/ExternalToolProjects/DBMan/Properties/AssemblyInfo.cs
+++ b/ExternalToolProjects/DBMan/Properties/AssemblyInfo.cs
@@ -1,8 +1,5 @@
-using System.Drawing;
-using System.Reflection;
-using System.Runtime.CompilerServices;
+using System.Reflection;
using System.Runtime.InteropServices;
-using BizHawk.Client.ApiHawk;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -16,9 +13,6 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: BizHawkExternalTool("DBMan", "DB Manager")]
-[assembly: BizHawkExternalToolUsage()]
-
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
diff --git a/ExternalToolProjects/HelloWorld/CustomMainForm.Designer.cs b/ExternalToolProjects/HelloWorld/CustomMainForm.Designer.cs
index 72aabce3c51..8d8c1e6c09d 100644
--- a/ExternalToolProjects/HelloWorld/CustomMainForm.Designer.cs
+++ b/ExternalToolProjects/HelloWorld/CustomMainForm.Designer.cs
@@ -1,4 +1,4 @@
-namespace BizHawk.Client.EmuHawk
+namespace HelloWorld
{
public partial class CustomMainForm
{
diff --git a/ExternalToolProjects/HelloWorld/CustomMainForm.cs b/ExternalToolProjects/HelloWorld/CustomMainForm.cs
index 14a80644b65..684281558e6 100644
--- a/ExternalToolProjects/HelloWorld/CustomMainForm.cs
+++ b/ExternalToolProjects/HelloWorld/CustomMainForm.cs
@@ -8,9 +8,12 @@
using DisplayType = BizHawk.Client.Common.DisplayType;
-namespace BizHawk.Client.EmuHawk
+namespace HelloWorld
{
- /// ExternalToolForms must be a class named CustomMainForm in namespace BizHawk.Client.EmuHawk.
+ /// All of this is example code, but it's at least a little more substantiative than a simple "hello world".
+ [ExternalTool("HelloWorld", "An example of how to interact with EmuHawk")]
+// [ExternalToolApplicability.SingleRom(CoreSystem.NES, "EA343F4E445A9050D4B4FBAC2C77D0693B1D0922")] // example of limiting tool usage (this is SMB1)
+ [ExternalToolEmbeddedIcon("HelloWorld.icon_Hello.ico")]
public partial class CustomMainForm : Form, IExternalToolForm
{
/// RequiredServices are populated by EmuHawk at runtime.
diff --git a/ExternalToolProjects/HelloWorld/Properties/AssemblyInfo.cs b/ExternalToolProjects/HelloWorld/Properties/AssemblyInfo.cs
index 58825547310..9ecd5a9d4cd 100644
--- a/ExternalToolProjects/HelloWorld/Properties/AssemblyInfo.cs
+++ b/ExternalToolProjects/HelloWorld/Properties/AssemblyInfo.cs
@@ -1,8 +1,5 @@
-using System.Drawing;
-using System.Reflection;
-using System.Runtime.CompilerServices;
+using System.Reflection;
using System.Runtime.InteropServices;
-using BizHawk.Client.ApiHawk;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -16,18 +13,6 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-//As you can see this is a dedicated attribute. You can write the name of your tool, a small description
-//and give an icon. The icon should be compiled as an embedded resource and you must give the entire path
-[assembly: BizHawkExternalTool("Hello World", "My first External tool for BizHawk emulator", "icon_Hello.ico")]
-
-//This attribute say what the is for. here, I don't anything
-//It's equivalent to [assembly: BizHawkExternalToolUsage(BizHawkExternalToolUsage.Global, string.Empty)]
-//Here is an example for an emulator specific: BizHawkExternalToolUsage(BizHawkExternalToolUsage.EmulatorSpecific, EmulatedSystem.NES)]
-//Here is an example for an game specific: BizHawkExternalToolUsage(BizHawkExternalToolUsage.GameSpecific, "6B47BB75D16514B6A476AA0C73A683A2A4C18765")] => Super Mario World (USA)
-//By setting this, your tool is contextualized, that mean you can't load it if emulator is in state you don't want
-//It avoid crash
-[assembly: BizHawkExternalToolUsage()]
-
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.