From a46b2130544d3ca47b10490605577c1dcac316b4 Mon Sep 17 00:00:00 2001 From: adelikat Date: Wed, 14 Jan 2015 22:56:08 +0000 Subject: [PATCH] Core Features dialog - make 2 tabs, on the first show information about the currently instantiated core, this will show all registered services and their current state of implementation, 2nd tab will show all cores. Still todo: gut the functionality of the 2nd tab since it is no longer reliable information --- .../CoreFeatureAnalysis.Designer.cs | 163 ++++++++++++------ BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs | 114 +++++++++++- 2 files changed, 224 insertions(+), 53 deletions(-) diff --git a/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.Designer.cs b/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.Designer.cs index 4ce54ea254..b9ca90479a 100644 --- a/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.Designer.cs +++ b/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.Designer.cs @@ -30,11 +30,18 @@ { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CoreFeatureAnalysis)); this.OkBtn = new System.Windows.Forms.Button(); - this.label1 = new System.Windows.Forms.Label(); - this.TotalCoresLabel = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.ReleasedCoresLabel = new System.Windows.Forms.Label(); this.CoreTree = new System.Windows.Forms.TreeView(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.ReleasedCoresLabel = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.TotalCoresLabel = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.CurrentCoreTree = new System.Windows.Forms.TreeView(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tabPage2.SuspendLayout(); this.SuspendLayout(); // // OkBtn @@ -49,52 +56,101 @@ this.OkBtn.UseVisualStyleBackColor = true; this.OkBtn.Click += new System.EventHandler(this.OkBtn_Click); // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(99, 19); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(34, 13); - this.label1.TabIndex = 2; - this.label1.Text = "Total:"; - // - // TotalCoresLabel - // - this.TotalCoresLabel.AutoSize = true; - this.TotalCoresLabel.Location = new System.Drawing.Point(132, 19); - this.TotalCoresLabel.Name = "TotalCoresLabel"; - this.TotalCoresLabel.Size = new System.Drawing.Size(19, 13); - this.TotalCoresLabel.TabIndex = 3; - this.TotalCoresLabel.Text = "20"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(12, 19); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(55, 13); - this.label2.TabIndex = 4; - this.label2.Text = "Released:"; - // - // ReleasedCoresLabel - // - this.ReleasedCoresLabel.AutoSize = true; - this.ReleasedCoresLabel.Location = new System.Drawing.Point(64, 19); - this.ReleasedCoresLabel.Name = "ReleasedCoresLabel"; - this.ReleasedCoresLabel.Size = new System.Drawing.Size(19, 13); - this.ReleasedCoresLabel.TabIndex = 5; - this.ReleasedCoresLabel.Text = "20"; - // // CoreTree // this.CoreTree.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.CoreTree.Location = new System.Drawing.Point(12, 35); + this.CoreTree.Location = new System.Drawing.Point(6, 24); this.CoreTree.Name = "CoreTree"; - this.CoreTree.Size = new System.Drawing.Size(504, 528); + this.CoreTree.Size = new System.Drawing.Size(481, 495); this.CoreTree.TabIndex = 0; // + // tabControl1 + // + this.tabControl1.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.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Location = new System.Drawing.Point(15, 12); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(501, 551); + this.tabControl1.TabIndex = 6; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.CurrentCoreTree); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(493, 525); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "Current"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.ReleasedCoresLabel); + this.tabPage2.Controls.Add(this.label2); + this.tabPage2.Controls.Add(this.TotalCoresLabel); + this.tabPage2.Controls.Add(this.label1); + this.tabPage2.Controls.Add(this.CoreTree); + this.tabPage2.Location = new System.Drawing.Point(4, 22); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(493, 525); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "All"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // ReleasedCoresLabel + // + this.ReleasedCoresLabel.AutoSize = true; + this.ReleasedCoresLabel.Location = new System.Drawing.Point(62, 8); + this.ReleasedCoresLabel.Name = "ReleasedCoresLabel"; + this.ReleasedCoresLabel.Size = new System.Drawing.Size(19, 13); + this.ReleasedCoresLabel.TabIndex = 9; + this.ReleasedCoresLabel.Text = "20"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(10, 8); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(55, 13); + this.label2.TabIndex = 8; + this.label2.Text = "Released:"; + // + // TotalCoresLabel + // + this.TotalCoresLabel.AutoSize = true; + this.TotalCoresLabel.Location = new System.Drawing.Point(130, 8); + this.TotalCoresLabel.Name = "TotalCoresLabel"; + this.TotalCoresLabel.Size = new System.Drawing.Size(19, 13); + this.TotalCoresLabel.TabIndex = 7; + this.TotalCoresLabel.Text = "20"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(97, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(34, 13); + this.label1.TabIndex = 6; + this.label1.Text = "Total:"; + // + // 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, 513); + this.CurrentCoreTree.TabIndex = 1; + // // CoreFeatureAnalysis // this.AcceptButton = this.OkBtn; @@ -102,29 +158,32 @@ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.OkBtn; this.ClientSize = new System.Drawing.Size(528, 604); - this.Controls.Add(this.CoreTree); - this.Controls.Add(this.ReleasedCoresLabel); - this.Controls.Add(this.label2); - this.Controls.Add(this.TotalCoresLabel); - this.Controls.Add(this.label1); + this.Controls.Add(this.tabControl1); this.Controls.Add(this.OkBtn); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "CoreFeatureAnalysis"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Core Features"; this.Load += new System.EventHandler(this.CoreFeatureAnalysis_Load); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage2.ResumeLayout(false); + this.tabPage2.PerformLayout(); this.ResumeLayout(false); - this.PerformLayout(); } #endregion private System.Windows.Forms.Button OkBtn; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label TotalCoresLabel; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.Label ReleasedCoresLabel; private System.Windows.Forms.TreeView CoreTree; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.Label ReleasedCoresLabel; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label TotalCoresLabel; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TreeView CurrentCoreTree; } } \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs b/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs index fe85323692..0865aa78f9 100644 --- a/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs +++ b/BizHawk.Client.EmuHawk/CoreFeatureAnalysis.cs @@ -6,6 +6,7 @@ using System.Reflection; using BizHawk.Emulation.Common; using BizHawk.Emulation.Common.IEmulatorExtensions; +using BizHawk.Client.Common; namespace BizHawk.Client.EmuHawk { @@ -22,12 +23,123 @@ namespace BizHawk.Client.EmuHawk } private void CoreFeatureAnalysis_Load(object sender, EventArgs e) + { + DoCurrentCoreTree(); + DoAllCoresTree(); + } + + private void DoCurrentCoreTree() + { + CurrentCoreTree.ImageList = new ImageList(); + CurrentCoreTree.ImageList.Images.Add("Good", Properties.Resources.GreenCheck); + 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.BeginUpdate(); + + var coreNode = new TreeNode + { + Text = core.Attributes().CoreName + (core.Attributes().Released ? string.Empty : " (UNRELEASED)"), + ForeColor = core.Attributes().Released ? Color.Black : Color.DarkGray, + }; + + + 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.EndUpdate(); + } + + private void DoAllCoresTree() { CoreTree.ImageList = new ImageList(); CoreTree.ImageList.Images.Add("Good", Properties.Resources.GreenCheck); CoreTree.ImageList.Images.Add("Bad", Properties.Resources.ExclamationRed); - var services = Assembly .GetAssembly(typeof(IEmulator)) .GetTypes()