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.