From 4bf1ab279902a09d32ee3e110e8a3db64547fa7e Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Thu, 5 Dec 2019 10:21:07 -0800 Subject: [PATCH] Tweak visualizer interface Report visualization generation errors through an explicit IApplication interface, instead of pulling messages out of the DebugLog stream. Declare that GetVisGenDescrs() is only called when the plugin is in the "prepared" state, so that plugins can taylor the set based on the contents of the file. (This could be used to set min/max on the "offset" entries, but I want special handling for offsets, so we might as well set it later.) --- PluginCommon/Interfaces.cs | 13 +++++++++-- PluginCommon/VisBitmap8.cs | 2 +- SourceGen/CodeAnalysis.cs | 4 ++++ SourceGen/RuntimeData/Apple/VisHiRes.cs | 25 +++++++++++++--------- SourceGen/VisualizationSet.cs | 18 ++++++++++------ SourceGen/WpfGui/EditVisualization.xaml.cs | 8 +++++-- 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/PluginCommon/Interfaces.cs b/PluginCommon/Interfaces.cs index 73a1bb0..f4cc058 100644 --- a/PluginCommon/Interfaces.cs +++ b/PluginCommon/Interfaces.cs @@ -140,7 +140,9 @@ namespace PluginCommon { public interface IPlugin_Visualizer { /// /// Retrieves a list of descriptors for visualization generators implemented by this - /// plugin. The caller must not modify the contents. + /// plugin. The items in the set may have values based on the file data. + /// + /// The caller must not modify the contents. /// VisDescr[] GetVisGenDescrs(); @@ -150,7 +152,8 @@ namespace PluginCommon { /// VisGen identifier. /// Parameter set. /// 2D visualization object reference, or null if something went - /// wrong (unknown ident, bad parameters, etc). + /// wrong (unknown ident, bad parameters, etc). By convention, an error + /// message is reported through the IApplication ReportError interface. IVisualization2d Generate2d(VisDescr descr, ReadOnlyDictionary parms); } @@ -306,6 +309,12 @@ namespace PluginCommon { /// is passed to the plugin as an argument to Prepare(). /// public interface IApplication { + /// + /// Reports an error message to the application. Used by visualizers. + /// + /// + void ReportError(string msg); + /// /// Sends a debug message to the application. This can be useful when debugging scripts. /// (For example, DEBUG > Show Analyzer Output shows output generated while performing diff --git a/PluginCommon/VisBitmap8.cs b/PluginCommon/VisBitmap8.cs index c8e5636..0058a39 100644 --- a/PluginCommon/VisBitmap8.cs +++ b/PluginCommon/VisBitmap8.cs @@ -20,7 +20,7 @@ using System.Text; namespace PluginCommon { /// - /// Bitmap with 8-bit palette indices, for use with plugin visualizers. + /// Bitmap with 8-bit palette indices, for use with visualization generators. /// [Serializable] public class VisBitmap8 : IVisualization2d { diff --git a/SourceGen/CodeAnalysis.cs b/SourceGen/CodeAnalysis.cs index 4bae921..c677321 100644 --- a/SourceGen/CodeAnalysis.cs +++ b/SourceGen/CodeAnalysis.cs @@ -76,6 +76,10 @@ namespace SourceGen { mOuter = null; } + public void ReportError(string msg) { + DebugLog(msg); + } + public void DebugLog(string msg) { mOuter.mDebugLog.LogI("PLUGIN: " + msg); } diff --git a/SourceGen/RuntimeData/Apple/VisHiRes.cs b/SourceGen/RuntimeData/Apple/VisHiRes.cs index 8628aa4..41ed1df 100644 --- a/SourceGen/RuntimeData/Apple/VisHiRes.cs +++ b/SourceGen/RuntimeData/Apple/VisHiRes.cs @@ -107,6 +107,11 @@ namespace RuntimeData.Apple { // IPlugin_Visualizer public VisDescr[] GetVisGenDescrs() { + // We're using a static set, but it could be generated based on file contents. + // Confirm that we're prepared. + if (mFileData == null) { + return null; + } return mDescriptors; } @@ -121,7 +126,7 @@ namespace RuntimeData.Apple { case VIS_GEN_HR_SCREEN: return GenerateScreen(parms); default: - mAppRef.DebugLog("Unknown ident " + descr.Ident); + mAppRef.ReportError("Unknown ident " + descr.Ident); return null; } } @@ -147,21 +152,21 @@ namespace RuntimeData.Apple { byteWidth <= 0 || byteWidth > MAX_DIM || height <= 0 || height > MAX_DIM) { // the UI should flag these based on range (and ideally wouldn't have called us) - mAppRef.DebugLog("Invalid parameter"); + mAppRef.ReportError("Invalid parameter"); return null; } if (colStride <= 0 || colStride > MAX_DIM) { - mAppRef.DebugLog("Invalid column stride"); + mAppRef.ReportError("Invalid column stride"); return null; } if (rowStride < byteWidth * colStride - (colStride - 1) || rowStride > MAX_DIM) { - mAppRef.DebugLog("Invalid row stride"); + mAppRef.ReportError("Invalid row stride"); return null; } int lastOffset = offset + rowStride * height - (colStride - 1) - 1; if (lastOffset >= mFileData.Length) { - mAppRef.DebugLog("Bitmap runs off end of file (last offset +" + + mAppRef.ReportError("Bitmap runs off end of file (last offset +" + lastOffset.ToString("x6") + ")"); return null; } @@ -185,13 +190,13 @@ namespace RuntimeData.Apple { itemByteWidth <= 0 || itemByteWidth > MAX_DIM || itemHeight <= 0 || itemHeight > MAX_DIM) { // should be caught by editor - mAppRef.DebugLog("Invalid parameter"); + mAppRef.ReportError("Invalid parameter"); return null; } int lastOffset = offset + itemByteWidth * itemHeight - 1; if (lastOffset >= mFileData.Length) { - mAppRef.DebugLog("Bitmap runs off end of file (last offset +" + + mAppRef.ReportError("Bitmap runs off end of file (last offset +" + lastOffset.ToString("x6") + ")"); return null; } @@ -248,13 +253,13 @@ namespace RuntimeData.Apple { if (offset < 0 || offset >= mFileData.Length) { // should be caught by editor - mAppRef.DebugLog("Invalid parameter"); + mAppRef.ReportError("Invalid parameter"); return null; } int lastOffset = offset + RAW_IMAGE_SIZE - 1; if (lastOffset >= mFileData.Length) { - mAppRef.DebugLog("Bitmap runs off end of file (last offset +" + + mAppRef.ReportError("Bitmap runs off end of file (last offset +" + lastOffset.ToString("x6") + ")"); return null; } @@ -523,7 +528,7 @@ namespace RuntimeData.Apple { break; default: // just leave the bitmap empty - mAppRef.DebugLog("Unknown ColorMode " + colorMode); + mAppRef.ReportError("Unknown ColorMode " + colorMode); break; } } diff --git a/SourceGen/VisualizationSet.cs b/SourceGen/VisualizationSet.cs index 9c683a4..2355548 100644 --- a/SourceGen/VisualizationSet.cs +++ b/SourceGen/VisualizationSet.cs @@ -91,6 +91,10 @@ namespace SourceGen { private class ScriptSupport : MarshalByRefObject, PluginCommon.IApplication { public ScriptSupport() { } + public void ReportError(string msg) { + DebugLog(msg); + } + public void DebugLog(string msg) { Debug.WriteLine("Vis plugin: " + msg); } @@ -130,22 +134,22 @@ namespace SourceGen { } Debug.WriteLine("Vis needs refresh: " + vis.Tag); + if (iapp == null) { + // Prep the plugins on first need. + iapp = new ScriptSupport(); + project.PrepareScripts(iapp); + } + if (plugins == null) { plugins = project.GetActivePlugins(); } IPlugin_Visualizer vplug = FindPluginByVisGenIdent(plugins, vis.VisGenIdent, out VisDescr visDescr); if (vplug == null) { - Debug.WriteLine("Unable to referesh " + vis.Tag + ": plugin not found"); + Debug.WriteLine("Unable to refresh " + vis.Tag + ": plugin not found"); continue; } - if (iapp == null) { - // Prep the plugins on first need. - iapp = new ScriptSupport(); - project.PrepareScripts(iapp); - } - IVisualization2d vis2d; try { vis2d = vplug.Generate2d(visDescr, diff --git a/SourceGen/WpfGui/EditVisualization.xaml.cs b/SourceGen/WpfGui/EditVisualization.xaml.cs index 3d0ba1b..115ba22 100644 --- a/SourceGen/WpfGui/EditVisualization.xaml.cs +++ b/SourceGen/WpfGui/EditVisualization.xaml.cs @@ -125,9 +125,13 @@ namespace SourceGen.WpfGui { mOuter = outer; } + public void ReportError(string msg) { + mOuter.LastPluginMessage = msg; + DebugLog(msg); + } + public void DebugLog(string msg) { Debug.WriteLine("Vis plugin: " + msg); - mOuter.LastPluginMessage = msg; } public bool SetOperandFormat(int offset, DataSubType subType, string label) { @@ -165,6 +169,7 @@ namespace SourceGen.WpfGui { mOrigVis = vis; mScriptSupport = new ScriptSupport(this); + mProject.PrepareScripts(mScriptSupport); if (vis != null) { TagString = vis.Tag; @@ -191,7 +196,6 @@ namespace SourceGen.WpfGui { // Set the selection. This should cause the sel change event to fire. visComboBox.SelectedIndex = visSelection; - mProject.PrepareScripts(mScriptSupport); } ///