Refactor external tool attributes
This commit is contained in:
parent
3143c38b7d
commit
593e1ef97d
|
@ -1,67 +1,26 @@
|
|||
using System;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// This class holds logic interaction for the ExternalToolAttribute
|
||||
/// This attribute helps BizHawk to handle ExternalTools
|
||||
/// </summary>
|
||||
/// <remarks>This class needs to be in the assembly or old tools will throw on load instead of being recognised as old.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Assembly)]
|
||||
[Obsolete("last used in 2.4, use [ExternalTool] instead")]
|
||||
public sealed class BizHawkExternalToolAttribute : Attribute
|
||||
{
|
||||
#region cTor(s)
|
||||
public BizHawkExternalToolAttribute(string name, string description, string iconResourceName) {}
|
||||
public BizHawkExternalToolAttribute(string name, string description) {}
|
||||
public BizHawkExternalToolAttribute(string name) {}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of <see cref="BizHawkExternalToolAttribute"/>
|
||||
/// </summary>
|
||||
/// <param name="name">Tool's name</param>
|
||||
/// <param name="description">Small description about the tool itself</param>
|
||||
/// <param name="iconResourceName">Icon embedded resource name</param>
|
||||
public BizHawkExternalToolAttribute(string name, string description, string iconResourceName)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
IconResourceName = iconResourceName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of <see cref="BizHawkExternalToolAttribute"/>
|
||||
/// </summary>
|
||||
/// <param name="name">Tool's name</param>
|
||||
/// <param name="description">Small description about the tool itself</param>
|
||||
public BizHawkExternalToolAttribute(string name, string description)
|
||||
: this(name, description, "")
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of <see cref="BizHawkExternalToolAttribute"/>
|
||||
/// </summary>
|
||||
/// <param name="name">Tool's name</param>
|
||||
public BizHawkExternalToolAttribute(string name)
|
||||
:this(name, "", "")
|
||||
{}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets tool's friendly name
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets tool's description
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get the name of the embedded resource icon
|
||||
/// </summary>
|
||||
/// <remarks>Don't forget to set compile => Embedded resource to the icon file in your project</remarks>
|
||||
public string IconResourceName { get; }
|
||||
|
||||
#endregion
|
||||
/// <inheritdoc cref="BizHawkExternalToolAttribute"/>
|
||||
[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() {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
using System;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.ApiHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// This class holds logic interaction for the BizHawkExternalToolUsageAttribute
|
||||
/// This attribute helps ApiHawk to know how a tool can be enabled or not
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Assembly)]
|
||||
public sealed class BizHawkExternalToolUsageAttribute : Attribute
|
||||
{
|
||||
#region cTor(s)
|
||||
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// <paramref name="usage"/> is <see cref="BizHawkExternalToolUsage.EmulatorSpecific"/> and <paramref name="system"/> is <see cref="CoreSystem.Null"/>, or
|
||||
/// usage is <see cref="BizHawkExternalToolUsage.GameSpecific"/> and <paramref name="gameHash"/> is blank
|
||||
/// </exception>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of <see cref="BizHawkExternalToolUsageAttribute"/>
|
||||
/// </summary>
|
||||
/// <param name="usage"><see cref="BizHawkExternalToolUsage"/> i.e. what your external tool is for</param>
|
||||
/// <param name="system"><see cref="CoreSystem"/> that your external tool is used for</param>
|
||||
public BizHawkExternalToolUsageAttribute(BizHawkExternalToolUsage usage, CoreSystem system)
|
||||
:this(usage, system, "")
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of <see cref="BizHawkExternalToolUsageAttribute"/>
|
||||
/// </summary>
|
||||
public BizHawkExternalToolUsageAttribute()
|
||||
:this(BizHawkExternalToolUsage.Global, CoreSystem.Null, "")
|
||||
{ }
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specific system used by the external tool
|
||||
/// </summary>
|
||||
public CoreSystem System { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specific game (hash) used by the external tool
|
||||
/// </summary>
|
||||
public string GameHash { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tool usage
|
||||
/// </summary>
|
||||
public BizHawkExternalToolUsage ToolUsage { get; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -71,101 +71,78 @@ namespace BizHawk.Client.ApiHawk
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a <see cref="ToolStripMenuItem"/> from an
|
||||
/// external tool dll.
|
||||
/// The assembly must have <see cref="BizHawkExternalToolAttribute"/> in its
|
||||
/// assembly attributes
|
||||
/// </summary>
|
||||
/// <param name="fileName">File that will be reflected</param>
|
||||
/// <returns>A new <see cref="ToolStripMenuItem"/>; assembly path can be found in the Tag property</returns>
|
||||
/// <remarks>For the moment, you could only load a dll that have a form (which implements <see cref="IExternalToolForm"/>)</remarks>
|
||||
/// <summary>Generates a <see cref="ToolStripMenuItem"/> from an assembly at <paramref name="fileName"/> containing an external tool.</summary>
|
||||
/// <returns>
|
||||
/// a <see cref="ToolStripMenuItem"/> with its <see cref="ToolStripItem.Tag"/> containing a <c>(string, string)</c>;
|
||||
/// the first is the assembly path (<paramref name="fileName"/>) and the second is the <see cref="Type.FullName"/> of the entry point form's type
|
||||
/// </returns>
|
||||
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<ExternalToolAttribute>().Any());
|
||||
#pragma warning disable CS0618
|
||||
if (entryPoint == null) throw new ExternalToolAttribute.MissingException(externalToolFile.GetCustomAttributes().OfType<BizHawkExternalToolAttribute>().Any());
|
||||
#pragma warning restore CS0618
|
||||
|
||||
var allAttrs = entryPoint.GetCustomAttributes().ToList();
|
||||
var applicabilityAttrs = allAttrs.OfType<ExternalToolApplicabilityAttributeBase>().ToList();
|
||||
if (applicabilityAttrs.Count > 1) throw new ExternalToolApplicabilityAttributeBase.DuplicateException();
|
||||
|
||||
var toolAttribute = allAttrs.OfType<ExternalToolAttribute>().First();
|
||||
var embeddedIconAttr = allAttrs.OfType<ExternalToolEmbeddedIconAttribute>().FirstOrDefault();
|
||||
if (embeddedIconAttr != null)
|
||||
{
|
||||
BizHawkExternalToolAttribute attribute = (BizHawkExternalToolAttribute)attributes[0];
|
||||
item = new ToolStripMenuItem(attribute.Name) { ToolTipText = attribute.Description };
|
||||
if (attribute.IconResourceName != "")
|
||||
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))
|
||||
{
|
||||
Stream s = externalToolFile.GetManifestResourceStream($"{externalToolFile.GetName().Name}.{attribute.IconResourceName}");
|
||||
if (s != null)
|
||||
{
|
||||
item.Image = new Bitmap(s);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
if (applicabilityAttrs[0].NotApplicableTo(Global.Game.Hash, system))
|
||||
{
|
||||
item.ToolTipText = "Does not have a correctly-formatted CustomMainForm or a form decorated with [ExternalToolEntryPointForm]";
|
||||
item.Enabled = false;
|
||||
}
|
||||
item.Tag = (fileName, customFormType?.FullName);
|
||||
|
||||
attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolUsageAttribute), false);
|
||||
if (attributes != null && attributes.Length == 1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/// <remarks>This class is not deprecated, do not remove it.</remarks>
|
||||
[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<string> _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
|
||||
{
|
||||
/// <remarks>The full path, including the assembly name.</remarks>
|
||||
public readonly string ResourcePath;
|
||||
|
||||
/// <param name="resourcePath">The full path, including the assembly name.</param>
|
||||
public ExternalToolEmbeddedIconAttribute(string resourcePath)
|
||||
{
|
||||
ResourcePath = resourcePath;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ExternalToolEntryPointFormAttribute : Attribute {}
|
||||
}
|
|
@ -1411,13 +1411,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
foreach (var item in ExternalToolManager.ToolStripMenu)
|
||||
{
|
||||
if (item.Enabled)
|
||||
if (item.Tag is ValueTuple<string, string> 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
|
||||
{
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
<Import Project="$(ProjectDir)../Common.props" />
|
||||
<Import Project="$(ProjectDir)../NET48ExternalToolForm.props" />
|
||||
<ItemGroup>
|
||||
<Compile Update="CustomMainForm.cs" SubType="Form" />
|
||||
<Compile Update="AutoGenConfigForm.cs" SubType="Form" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -9,11 +9,12 @@ using System.Windows.Forms;
|
|||
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<Control>)> CachedControlGenerators;
|
||||
|
||||
|
@ -28,7 +29,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public static readonly IDictionary<string, object?> DefaultValues;
|
||||
|
||||
static CustomMainForm()
|
||||
static AutoGenConfigForm()
|
||||
{
|
||||
CachedControlGenerators = new List<(PropertyInfo, IConfigPropEditorUIGen<Control>)>();
|
||||
DefaultValues = new Dictionary<string, object?>();
|
||||
|
@ -63,7 +64,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public bool UpdateBefore => false;
|
||||
|
||||
public CustomMainForm()
|
||||
public AutoGenConfigForm()
|
||||
{
|
||||
ClientSize = new Size(640, 720);
|
||||
SuspendLayout();
|
|
@ -8,7 +8,7 @@ using System.Windows.Forms;
|
|||
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
namespace BizHawk.Experiment.AutoGenConfig
|
||||
{
|
||||
public static class ConfigEditorUIGenerators
|
||||
{
|
||||
|
@ -19,39 +19,39 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public static readonly IConfigPropEditorUIGen<GroupBox> FinalFallbackGenerator = new UnrepresentablePropEditorUIGen();
|
||||
|
||||
private static Color GetComparisonColorRefT<T>(string prop, T? currentValue, CustomMainForm parent, Func<T?, T?, bool> equalityFunc)
|
||||
private static Color GetComparisonColorRefT<T>(string prop, T? currentValue, AutoGenConfigForm parent, Func<T?, T?, bool> 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<T>(string prop, T? currentValue, CustomMainForm parent, Func<T?, T?, bool> equalityFunc)
|
||||
private static Color GetComparisonColorValT<T>(string prop, T? currentValue, AutoGenConfigForm parent, Func<T?, T?, bool> 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<T>(string prop, T? currentValue, Func<T?, T?, bool> 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<T>(string prop, T? currentValue, Func<T?, T?, bool> 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)
|
||||
|
|
|
@ -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")]
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
namespace BizHawk.Experiment.AutoGenConfig
|
||||
{
|
||||
internal static class ScopingExtensions
|
||||
{
|
||||
|
|
|
@ -5,12 +5,12 @@ using System.Windows.Forms;
|
|||
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()
|
||||
|
|
|
@ -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 @@ using BizHawk.Client.ApiHawk;
|
|||
[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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace BizHawk.Client.EmuHawk
|
||||
namespace HelloWorld
|
||||
{
|
||||
public partial class CustomMainForm
|
||||
{
|
||||
|
|
|
@ -8,9 +8,12 @@ using BizHawk.Emulation.Common;
|
|||
|
||||
using DisplayType = BizHawk.Client.Common.DisplayType;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
namespace HelloWorld
|
||||
{
|
||||
/// <remarks><see cref="IExternalToolForm">ExternalToolForms</see> must be a class named <c>CustomMainForm</c> in namespace <c>BizHawk.Client.EmuHawk</c>.</remarks>
|
||||
/// <remarks>All of this is example code, but it's at least a little more substantiative than a simple "hello world".</remarks>
|
||||
[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
|
||||
{
|
||||
/// <remarks><see cref="RequiredServiceAttribute">RequiredServices</see> are populated by EmuHawk at runtime.</remarks>
|
||||
|
|
|
@ -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 @@ using BizHawk.Client.ApiHawk;
|
|||
[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.
|
||||
|
|
Loading…
Reference in New Issue