some changes to corefeatureanalysis
This commit is contained in:
parent
6de080dd9c
commit
c5daf82a3b
|
@ -33,12 +33,13 @@
|
||||||
this.CoreTree = new System.Windows.Forms.TreeView();
|
this.CoreTree = new System.Windows.Forms.TreeView();
|
||||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||||
|
this.CurrentCoreTree = new System.Windows.Forms.TreeView();
|
||||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||||
this.ReleasedCoresLabel = new System.Windows.Forms.Label();
|
this.ReleasedCoresLabel = new System.Windows.Forms.Label();
|
||||||
this.label2 = new System.Windows.Forms.Label();
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
this.TotalCoresLabel = new System.Windows.Forms.Label();
|
this.TotalCoresLabel = new System.Windows.Forms.Label();
|
||||||
this.label1 = new System.Windows.Forms.Label();
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
this.CurrentCoreTree = new System.Windows.Forms.TreeView();
|
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
|
||||||
this.tabControl1.SuspendLayout();
|
this.tabControl1.SuspendLayout();
|
||||||
this.tabPage1.SuspendLayout();
|
this.tabPage1.SuspendLayout();
|
||||||
this.tabPage2.SuspendLayout();
|
this.tabPage2.SuspendLayout();
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.CoreTree.Location = new System.Drawing.Point(6, 24);
|
this.CoreTree.Location = new System.Drawing.Point(6, 24);
|
||||||
this.CoreTree.Name = "CoreTree";
|
this.CoreTree.Name = "CoreTree";
|
||||||
this.CoreTree.Size = new System.Drawing.Size(481, 495);
|
this.CoreTree.Size = new System.Drawing.Size(481, 480);
|
||||||
this.CoreTree.TabIndex = 0;
|
this.CoreTree.TabIndex = 0;
|
||||||
//
|
//
|
||||||
// tabControl1
|
// tabControl1
|
||||||
|
@ -73,10 +74,10 @@
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.tabControl1.Controls.Add(this.tabPage1);
|
this.tabControl1.Controls.Add(this.tabPage1);
|
||||||
this.tabControl1.Controls.Add(this.tabPage2);
|
this.tabControl1.Controls.Add(this.tabPage2);
|
||||||
this.tabControl1.Location = new System.Drawing.Point(15, 12);
|
this.tabControl1.Location = new System.Drawing.Point(15, 27);
|
||||||
this.tabControl1.Name = "tabControl1";
|
this.tabControl1.Name = "tabControl1";
|
||||||
this.tabControl1.SelectedIndex = 0;
|
this.tabControl1.SelectedIndex = 0;
|
||||||
this.tabControl1.Size = new System.Drawing.Size(501, 551);
|
this.tabControl1.Size = new System.Drawing.Size(501, 536);
|
||||||
this.tabControl1.TabIndex = 6;
|
this.tabControl1.TabIndex = 6;
|
||||||
//
|
//
|
||||||
// tabPage1
|
// tabPage1
|
||||||
|
@ -85,11 +86,21 @@
|
||||||
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
||||||
this.tabPage1.Name = "tabPage1";
|
this.tabPage1.Name = "tabPage1";
|
||||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||||
this.tabPage1.Size = new System.Drawing.Size(493, 525);
|
this.tabPage1.Size = new System.Drawing.Size(493, 510);
|
||||||
this.tabPage1.TabIndex = 0;
|
this.tabPage1.TabIndex = 0;
|
||||||
this.tabPage1.Text = "Current";
|
this.tabPage1.Text = "Current";
|
||||||
this.tabPage1.UseVisualStyleBackColor = true;
|
this.tabPage1.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
|
// CurrentCoreTree
|
||||||
|
//
|
||||||
|
this.CurrentCoreTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.CurrentCoreTree.Location = new System.Drawing.Point(6, 6);
|
||||||
|
this.CurrentCoreTree.Name = "CurrentCoreTree";
|
||||||
|
this.CurrentCoreTree.Size = new System.Drawing.Size(481, 498);
|
||||||
|
this.CurrentCoreTree.TabIndex = 1;
|
||||||
|
//
|
||||||
// tabPage2
|
// tabPage2
|
||||||
//
|
//
|
||||||
this.tabPage2.Controls.Add(this.ReleasedCoresLabel);
|
this.tabPage2.Controls.Add(this.ReleasedCoresLabel);
|
||||||
|
@ -100,7 +111,7 @@
|
||||||
this.tabPage2.Location = new System.Drawing.Point(4, 22);
|
this.tabPage2.Location = new System.Drawing.Point(4, 22);
|
||||||
this.tabPage2.Name = "tabPage2";
|
this.tabPage2.Name = "tabPage2";
|
||||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||||
this.tabPage2.Size = new System.Drawing.Size(493, 525);
|
this.tabPage2.Size = new System.Drawing.Size(493, 510);
|
||||||
this.tabPage2.TabIndex = 1;
|
this.tabPage2.TabIndex = 1;
|
||||||
this.tabPage2.Text = "All";
|
this.tabPage2.Text = "All";
|
||||||
this.tabPage2.UseVisualStyleBackColor = true;
|
this.tabPage2.UseVisualStyleBackColor = true;
|
||||||
|
@ -141,15 +152,13 @@
|
||||||
this.label1.TabIndex = 6;
|
this.label1.TabIndex = 6;
|
||||||
this.label1.Text = "Total:";
|
this.label1.Text = "Total:";
|
||||||
//
|
//
|
||||||
// CurrentCoreTree
|
// menuStrip1
|
||||||
//
|
//
|
||||||
this.CurrentCoreTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||||
| System.Windows.Forms.AnchorStyles.Left)
|
this.menuStrip1.Name = "menuStrip1";
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
this.menuStrip1.Size = new System.Drawing.Size(528, 24);
|
||||||
this.CurrentCoreTree.Location = new System.Drawing.Point(6, 6);
|
this.menuStrip1.TabIndex = 7;
|
||||||
this.CurrentCoreTree.Name = "CurrentCoreTree";
|
this.menuStrip1.Text = "menuStrip1";
|
||||||
this.CurrentCoreTree.Size = new System.Drawing.Size(481, 513);
|
|
||||||
this.CurrentCoreTree.TabIndex = 1;
|
|
||||||
//
|
//
|
||||||
// CoreFeatureAnalysis
|
// CoreFeatureAnalysis
|
||||||
//
|
//
|
||||||
|
@ -160,16 +169,18 @@
|
||||||
this.ClientSize = new System.Drawing.Size(528, 604);
|
this.ClientSize = new System.Drawing.Size(528, 604);
|
||||||
this.Controls.Add(this.tabControl1);
|
this.Controls.Add(this.tabControl1);
|
||||||
this.Controls.Add(this.OkBtn);
|
this.Controls.Add(this.OkBtn);
|
||||||
|
this.Controls.Add(this.menuStrip1);
|
||||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||||
|
this.MainMenuStrip = this.menuStrip1;
|
||||||
this.Name = "CoreFeatureAnalysis";
|
this.Name = "CoreFeatureAnalysis";
|
||||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
this.Text = "Core Features";
|
this.Text = "Core Features";
|
||||||
this.Load += new System.EventHandler(this.CoreFeatureAnalysis_Load);
|
|
||||||
this.tabControl1.ResumeLayout(false);
|
this.tabControl1.ResumeLayout(false);
|
||||||
this.tabPage1.ResumeLayout(false);
|
this.tabPage1.ResumeLayout(false);
|
||||||
this.tabPage2.ResumeLayout(false);
|
this.tabPage2.ResumeLayout(false);
|
||||||
this.tabPage2.PerformLayout();
|
this.tabPage2.PerformLayout();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,5 +196,6 @@
|
||||||
private System.Windows.Forms.Label TotalCoresLabel;
|
private System.Windows.Forms.Label TotalCoresLabel;
|
||||||
private System.Windows.Forms.Label label1;
|
private System.Windows.Forms.Label label1;
|
||||||
private System.Windows.Forms.TreeView CurrentCoreTree;
|
private System.Windows.Forms.TreeView CurrentCoreTree;
|
||||||
|
private System.Windows.Forms.MenuStrip menuStrip1;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
@ -10,11 +11,105 @@ using BizHawk.Client.Common;
|
||||||
|
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
public partial class CoreFeatureAnalysis : Form
|
public partial class CoreFeatureAnalysis : Form, IToolFormAutoConfig
|
||||||
{
|
{
|
||||||
|
#region ConfigPersist
|
||||||
|
|
||||||
|
private class CoreInfo
|
||||||
|
{
|
||||||
|
public string CoreName { get; set; }
|
||||||
|
public string TypeName { get; set; }
|
||||||
|
public bool Released { get; set; }
|
||||||
|
public Dictionary<string, ServiceInfo> Services { get; set; }
|
||||||
|
|
||||||
|
public CoreInfo() { }
|
||||||
|
public CoreInfo(IEmulator emu)
|
||||||
|
{
|
||||||
|
TypeName = emu.GetType().ToString();
|
||||||
|
CoreName = emu.Attributes().CoreName;
|
||||||
|
Released = emu.Attributes().Released;
|
||||||
|
Services = new Dictionary<string, ServiceInfo>();
|
||||||
|
var ser = emu.ServiceProvider;
|
||||||
|
foreach (Type t in ser.AvailableServices)
|
||||||
|
{
|
||||||
|
var si = new ServiceInfo(t, ser.GetService(t));
|
||||||
|
Services.Add(si.TypeName, si);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ServiceInfo
|
||||||
|
{
|
||||||
|
public string TypeName { get; set; }
|
||||||
|
public bool Complete { get; set; }
|
||||||
|
public List<FunctionInfo> Functions { get; set; }
|
||||||
|
|
||||||
|
public ServiceInfo() { }
|
||||||
|
public ServiceInfo(Type servicetype, object service)
|
||||||
|
{
|
||||||
|
if (servicetype.IsGenericType)
|
||||||
|
{
|
||||||
|
TypeName = servicetype.GetGenericTypeDefinition().ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TypeName = servicetype.ToString();
|
||||||
|
}
|
||||||
|
Functions = new List<FunctionInfo>();
|
||||||
|
|
||||||
|
IEnumerable<MethodInfo> methods = servicetype.GetMethods(); // .Concat(servicetype.GetProperties().Select(p => p.GetGetMethod()));
|
||||||
|
|
||||||
|
if (servicetype.IsInterface)
|
||||||
|
{
|
||||||
|
var map = service.GetType().GetInterfaceMap(servicetype);
|
||||||
|
// project interface methods to actual implementations
|
||||||
|
methods = methods.Select(
|
||||||
|
m => map.TargetMethods[Array.IndexOf(map.InterfaceMethods, m)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
Functions.Add(new FunctionInfo(method, service));
|
||||||
|
}
|
||||||
|
Complete = Functions.All(f => f.Complete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FunctionInfo
|
||||||
|
{
|
||||||
|
public string TypeName { get; set; }
|
||||||
|
public bool Complete { get; set; }
|
||||||
|
|
||||||
|
public FunctionInfo() { }
|
||||||
|
public FunctionInfo(MethodInfo m, object service)
|
||||||
|
{
|
||||||
|
TypeName = m.ToString();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Complete = m.IsImplemented();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Complete = false; // TODO: fixme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConfigPersist]
|
||||||
|
private Dictionary<string, CoreInfo> KnownCores { get; set; }
|
||||||
|
[ConfigPersist]
|
||||||
|
private HashSet<string> KnownServices { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[RequiredService]
|
||||||
|
IEmulator emu { get; set; }
|
||||||
|
|
||||||
public CoreFeatureAnalysis()
|
public CoreFeatureAnalysis()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
KnownCores = new Dictionary<string, CoreInfo>();
|
||||||
|
KnownServices = new HashSet<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OkBtn_Click(object sender, EventArgs e)
|
private void OkBtn_Click(object sender, EventArgs e)
|
||||||
|
@ -22,208 +117,128 @@ namespace BizHawk.Client.EmuHawk
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CoreFeatureAnalysis_Load(object sender, EventArgs e)
|
private TreeNode CreateCoreTree(CoreInfo ci)
|
||||||
{
|
{
|
||||||
DoCurrentCoreTree();
|
var ret = new TreeNode
|
||||||
DoAllCoresTree();
|
{
|
||||||
|
Text = ci.CoreName + (ci.Released ? string.Empty : " (UNRELEASED)"),
|
||||||
|
ForeColor = ci.Released ? Color.Black : Color.DarkGray
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var service in ci.Services.Values)
|
||||||
|
{
|
||||||
|
string img = service.Complete ? "Good" : "Bad";
|
||||||
|
var serviceNode = new TreeNode
|
||||||
|
{
|
||||||
|
Text = service.TypeName,
|
||||||
|
ForeColor = service.Complete ? Color.Black : Color.Red,
|
||||||
|
ImageKey = img,
|
||||||
|
SelectedImageKey = img,
|
||||||
|
StateImageKey = img
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var function in service.Functions)
|
||||||
|
{
|
||||||
|
img = function.Complete ? "Good" : "Bad";
|
||||||
|
serviceNode.Nodes.Add(new TreeNode
|
||||||
|
{
|
||||||
|
Text = function.TypeName,
|
||||||
|
ForeColor = function.Complete ? Color.Black : Color.Red,
|
||||||
|
ImageKey = img,
|
||||||
|
SelectedImageKey = img,
|
||||||
|
StateImageKey = img
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ret.Nodes.Add(serviceNode);
|
||||||
|
}
|
||||||
|
foreach (string servicename in KnownServices.Where(s => !ci.Services.ContainsKey(s)))
|
||||||
|
{
|
||||||
|
string img = "Bad";
|
||||||
|
var serviceNode = new TreeNode
|
||||||
|
{
|
||||||
|
Text = servicename,
|
||||||
|
ForeColor = Color.Red,
|
||||||
|
ImageKey = img,
|
||||||
|
SelectedImageKey = img,
|
||||||
|
StateImageKey = img
|
||||||
|
};
|
||||||
|
ret.Nodes.Add(serviceNode);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoCurrentCoreTree()
|
private void DoCurrentCoreTree(CoreInfo ci)
|
||||||
{
|
{
|
||||||
CurrentCoreTree.ImageList = new ImageList();
|
CurrentCoreTree.ImageList = new ImageList();
|
||||||
CurrentCoreTree.ImageList.Images.Add("Good", Properties.Resources.GreenCheck);
|
CurrentCoreTree.ImageList.Images.Add("Good", Properties.Resources.GreenCheck);
|
||||||
CurrentCoreTree.ImageList.Images.Add("Bad", Properties.Resources.ExclamationRed);
|
CurrentCoreTree.ImageList.Images.Add("Bad", Properties.Resources.ExclamationRed);
|
||||||
|
|
||||||
var core = Global.Emulator;
|
|
||||||
var services = Assembly
|
|
||||||
.GetAssembly(typeof(IEmulator))
|
|
||||||
.GetTypes()
|
|
||||||
.Where(t => t.IsInterface)
|
|
||||||
.Where(t => typeof(IEmulatorService).IsAssignableFrom(t))
|
|
||||||
.Where(t => t != typeof(IEmulatorService))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var additionalRegisteredServices = core.ServiceProvider.AvailableServices
|
|
||||||
.Where(s => !services.Contains(s))
|
|
||||||
.Where(s => s != core.GetType()); // We don't care about the core itself
|
|
||||||
|
|
||||||
services.AddRange(additionalRegisteredServices);
|
|
||||||
|
|
||||||
CurrentCoreTree.Nodes.Clear();
|
CurrentCoreTree.Nodes.Clear();
|
||||||
CurrentCoreTree.BeginUpdate();
|
CurrentCoreTree.BeginUpdate();
|
||||||
|
var coreNode = CreateCoreTree(ci);
|
||||||
var coreNode = new TreeNode
|
|
||||||
{
|
|
||||||
Text = core.Attributes().CoreName + (core.Attributes().Released ? string.Empty : " (UNRELEASED)"),
|
|
||||||
ForeColor = core.Attributes().Released ? Color.Black : Color.DarkGray,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
coreNode.Expand();
|
coreNode.Expand();
|
||||||
|
|
||||||
bool missingImplementation = false;
|
|
||||||
|
|
||||||
foreach (var service in services)
|
|
||||||
{
|
|
||||||
bool isImplemented = false;
|
|
||||||
if (core.ServiceProvider.HasService(service))
|
|
||||||
{
|
|
||||||
isImplemented = true;
|
|
||||||
}
|
|
||||||
else if (service.IsAssignableFrom(typeof(ISettable<,>))) // TODO
|
|
||||||
{
|
|
||||||
isImplemented = core.GetType()
|
|
||||||
.GetInterfaces()
|
|
||||||
.Where(t => t.IsGenericType &&
|
|
||||||
t.GetGenericTypeDefinition() == typeof(ISettable<,>))
|
|
||||||
.FirstOrDefault() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var serviceNode = new TreeNode
|
|
||||||
{
|
|
||||||
Text = service.Name,
|
|
||||||
ForeColor = isImplemented ? Color.Black : Color.Red
|
|
||||||
};
|
|
||||||
|
|
||||||
bool fullyImplementedInterface = isImplemented;
|
|
||||||
|
|
||||||
if (isImplemented)
|
|
||||||
{
|
|
||||||
foreach (var field in service.GetMethods().OrderBy(f => f.Name))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var coreImplementation = core.ServiceProvider.GetService(service).GetType().GetMethod(field.Name);
|
|
||||||
|
|
||||||
if (coreImplementation != null)
|
|
||||||
{
|
|
||||||
var i = coreImplementation.IsImplemented();
|
|
||||||
serviceNode.Nodes.Add(new TreeNode
|
|
||||||
{
|
|
||||||
Text = field.Name,
|
|
||||||
ImageKey = i ? "Good" : "Bad",
|
|
||||||
SelectedImageKey = i ? "Good" : "Bad",
|
|
||||||
StateImageKey = i ? "Good" : "Bad"
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!i)
|
|
||||||
{
|
|
||||||
fullyImplementedInterface = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// TODO: SavestateBinary() and SaveStateBinary(BinaryWriter bw) cause an exception, need to look at signature too
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
missingImplementation = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceNode.StateImageKey = serviceNode.SelectedImageKey = serviceNode.ImageKey = fullyImplementedInterface ? "Good" : "Bad";
|
|
||||||
|
|
||||||
coreNode.Nodes.Add(serviceNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
coreNode.StateImageKey = coreNode.SelectedImageKey = coreNode.ImageKey = missingImplementation ? "Bad" : "Good";
|
|
||||||
CurrentCoreTree.Nodes.Add(coreNode);
|
CurrentCoreTree.Nodes.Add(coreNode);
|
||||||
|
|
||||||
CurrentCoreTree.EndUpdate();
|
CurrentCoreTree.EndUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoAllCoresTree()
|
private void DoAllCoresTree(CoreInfo current_ci)
|
||||||
{
|
{
|
||||||
CoreTree.ImageList = new ImageList();
|
CoreTree.ImageList = new ImageList();
|
||||||
CoreTree.ImageList.Images.Add("Good", Properties.Resources.GreenCheck);
|
CoreTree.ImageList.Images.Add("Good", Properties.Resources.GreenCheck);
|
||||||
CoreTree.ImageList.Images.Add("Bad", Properties.Resources.ExclamationRed);
|
CoreTree.ImageList.Images.Add("Bad", Properties.Resources.ExclamationRed);
|
||||||
|
|
||||||
var cores = Assembly
|
TotalCoresLabel.Text = KnownCores.Count.ToString();
|
||||||
.Load("BizHawk.Emulation.Cores")
|
ReleasedCoresLabel.Text = KnownCores.Values.Count(c => c.Released).ToString();
|
||||||
.GetTypes()
|
|
||||||
.Where(t => typeof(IEmulator).IsAssignableFrom(t))
|
|
||||||
.Select(core => new
|
|
||||||
{
|
|
||||||
CoreType = core,
|
|
||||||
CoreAttributes = core.GetCustomAttributes(false)
|
|
||||||
.OfType<CoreAttributes>()
|
|
||||||
.Single(),
|
|
||||||
ServicesNotApplicable = core.GetCustomAttributes(false)
|
|
||||||
.OfType<ServiceNotApplicable>()
|
|
||||||
.SingleOrDefault() ?? new ServiceNotApplicable()
|
|
||||||
})
|
|
||||||
.OrderBy(c => !c.CoreAttributes.Released)
|
|
||||||
.ThenBy(c => c.CoreAttributes.CoreName)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
TotalCoresLabel.Text = cores.Count.ToString();
|
|
||||||
ReleasedCoresLabel.Text = cores.Count(c => c.CoreAttributes.Released).ToString();
|
|
||||||
|
|
||||||
CoreTree.Nodes.Clear();
|
CoreTree.Nodes.Clear();
|
||||||
CoreTree.BeginUpdate();
|
CoreTree.BeginUpdate();
|
||||||
|
|
||||||
foreach (var core in cores)
|
foreach (var ci in KnownCores.Values)
|
||||||
{
|
{
|
||||||
var coreNode = new TreeNode
|
var coreNode = CreateCoreTree(ci);
|
||||||
{
|
|
||||||
Text = core.CoreAttributes.CoreName + (core.CoreAttributes.Released ? string.Empty : " (UNRELEASED)"),
|
|
||||||
ForeColor = core.CoreAttributes.Released ? Color.Black : Color.DarkGray,
|
|
||||||
};
|
|
||||||
|
|
||||||
var service = typeof(IEmulator);
|
if (ci.CoreName == current_ci.CoreName)
|
||||||
|
|
||||||
bool isImplemented = false;
|
|
||||||
if (service.IsAssignableFrom(core.CoreType))
|
|
||||||
{
|
{
|
||||||
isImplemented = true;
|
coreNode.Expand();
|
||||||
}
|
}
|
||||||
|
|
||||||
var serviceNode = new TreeNode
|
|
||||||
{
|
|
||||||
Text = service.Name,
|
|
||||||
ForeColor = isImplemented ? Color.Black : Color.Red
|
|
||||||
};
|
|
||||||
|
|
||||||
serviceNode.Expand();
|
|
||||||
|
|
||||||
bool fullyImplementedInterface = isImplemented;
|
|
||||||
|
|
||||||
if (isImplemented)
|
|
||||||
{
|
|
||||||
foreach (var field in service.GetMethods().OrderBy(f => f.Name))
|
|
||||||
{
|
|
||||||
var coreImplementation = core.CoreType.GetMethod(field.Name);
|
|
||||||
|
|
||||||
if (coreImplementation != null)
|
|
||||||
{
|
|
||||||
var i = coreImplementation.IsImplemented();
|
|
||||||
serviceNode.Nodes.Add(new TreeNode
|
|
||||||
{
|
|
||||||
Text = field.Name,
|
|
||||||
ImageKey = i ? "Good" : "Bad",
|
|
||||||
SelectedImageKey = i ? "Good" : "Bad",
|
|
||||||
StateImageKey = i ? "Good" : "Bad"
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!i)
|
|
||||||
{
|
|
||||||
fullyImplementedInterface = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceNode.StateImageKey = serviceNode.SelectedImageKey = serviceNode.ImageKey = fullyImplementedInterface ? "Good" : "Bad";
|
|
||||||
|
|
||||||
coreNode.Nodes.Add(serviceNode);
|
|
||||||
coreNode.StateImageKey = coreNode.SelectedImageKey = coreNode.ImageKey = fullyImplementedInterface ? "Good" : "Bad";
|
|
||||||
|
|
||||||
CoreTree.Nodes.Add(coreNode);
|
CoreTree.Nodes.Add(coreNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreTree.EndUpdate();
|
CoreTree.EndUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IToolForm
|
||||||
|
|
||||||
|
public void UpdateValues()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FastUpdate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Restart()
|
||||||
|
{
|
||||||
|
var ci = new CoreInfo(emu);
|
||||||
|
KnownCores[ci.CoreName] = ci;
|
||||||
|
|
||||||
|
// this will keep phantom services around even when no core implements them,
|
||||||
|
// which might not be desired?
|
||||||
|
KnownServices.UnionWith(ci.Services.Keys);
|
||||||
|
|
||||||
|
DoCurrentCoreTree(ci);
|
||||||
|
DoAllCoresTree(ci);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AskSaveChanges()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UpdateBefore
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,9 @@
|
||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
|
|
|
@ -3656,7 +3656,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void FeaturesMenuItem_Click(object sender, EventArgs e)
|
private void FeaturesMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
new CoreFeatureAnalysis().Show();
|
GlobalWin.Tools.Load<CoreFeatureAnalysis>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HelpSubMenu_DropDownOpened(object sender, EventArgs e)
|
private void HelpSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||||
|
|
Loading…
Reference in New Issue