diff --git a/PluginCommon/PluginManager.cs b/PluginCommon/PluginManager.cs index 8a5d847..754e83e 100644 --- a/PluginCommon/PluginManager.cs +++ b/PluginCommon/PluginManager.cs @@ -132,14 +132,16 @@ namespace PluginCommon { /// Generates a list of references to instances of active plugins. /// /// Newly-created list of plugin references. - public List GetActivePlugins() { - List list = new List(mActivePlugins.Count); + public Dictionary GetActivePlugins() { + Dictionary dict = + new Dictionary(mActivePlugins.Count); foreach (KeyValuePair kvp in mActivePlugins) { - list.Add(kvp.Value); + // copy the contents; probably not necessary across AppDomain + dict.Add(kvp.Key, kvp.Value); } - Debug.WriteLine("PluginManager: returning " + list.Count + " plugins (id=" + + Debug.WriteLine("PluginManager: returning " + dict.Count + " plugins (id=" + AppDomain.CurrentDomain.Id + ")"); - return list; + return dict; } /// diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs index 3787c56..ef43cf2 100644 --- a/SourceGen/DisasmProject.cs +++ b/SourceGen/DisasmProject.cs @@ -2496,9 +2496,12 @@ namespace SourceGen { } // Punch-through functions; trying to avoid exposing ScriptManager for now. - public List GetActivePlugins() { + public Dictionary GetActivePlugins() { return mScriptManager.GetActivePlugins(); } + public PluginCommon.IPlugin GetPlugin(string scriptIdent) { + return mScriptManager.GetInstance(scriptIdent); + } public void PrepareScripts(PluginCommon.IApplication appRef) { mScriptManager.PrepareScripts(appRef); } diff --git a/SourceGen/Sandbox/ScriptManager.cs b/SourceGen/Sandbox/ScriptManager.cs index 931ebf0..1bb53ec 100644 --- a/SourceGen/Sandbox/ScriptManager.cs +++ b/SourceGen/Sandbox/ScriptManager.cs @@ -140,15 +140,17 @@ namespace SourceGen.Sandbox { /// /// Newly-created list of plugin references. public List GetAllInstances() { + Dictionary dict; if (DomainMgr == null) { - List list = new List(mActivePlugins.Count); - foreach (KeyValuePair kvp in mActivePlugins) { - list.Add(kvp.Value); - } - return list; + dict = mActivePlugins; } else { - return DomainMgr.PluginMgr.GetActivePlugins(); + dict = DomainMgr.PluginMgr.GetActivePlugins(); } + List list = new List(dict.Count); + foreach (KeyValuePair kvp in dict) { + list.Add(kvp.Value); + } + return list; } /// @@ -272,36 +274,36 @@ namespace SourceGen.Sandbox { return plSymbols; } +#if false public delegate bool CheckMatch(IPlugin plugin); public IPlugin GetMatchingScript(CheckMatch check) { + Dictionary plugins; if (DomainMgr == null) { - foreach (KeyValuePair kvp in mActivePlugins) { - if (check(kvp.Value)) { - return kvp.Value; - } - } + plugins = mActivePlugins; } else { - List plugins = DomainMgr.PluginMgr.GetActivePlugins(); - foreach (IPlugin plugin in plugins) { - if (check(plugin)) { - return plugin; - } + plugins = DomainMgr.PluginMgr.GetActivePlugins(); + } + foreach (IPlugin plugin in plugins.Values) { + if (check(plugin)) { + return plugin; } } return null; } +#endif /// /// Returns a list of loaded plugins. Callers should not retain this list, as the /// set can change due to user activity. /// - public List GetActivePlugins() { + public Dictionary GetActivePlugins() { if (DomainMgr == null) { - List plist = new List(); + // copy the contents + Dictionary pdict = new Dictionary(); foreach (KeyValuePair kvp in mActivePlugins) { - plist.Add(kvp.Value); + pdict.Add(kvp.Key, kvp.Value); } - return plist; + return pdict; } else { return DomainMgr.PluginMgr.GetActivePlugins(); } @@ -322,8 +324,8 @@ namespace SourceGen.Sandbox { DebugGetScriptInfo(kvp.Value, sb); } } else { - List plugins = DomainMgr.PluginMgr.GetActivePlugins(); - foreach (IPlugin plugin in plugins) { + Dictionary plugins = DomainMgr.PluginMgr.GetActivePlugins(); + foreach (IPlugin plugin in plugins.Values) { string loc = DomainMgr.PluginMgr.GetPluginAssemblyLocation(plugin); sb.AppendFormat("[sub {0}] ", DomainMgr.Id); sb.Append(loc); diff --git a/SourceGen/VisualizationSet.cs b/SourceGen/VisualizationSet.cs index 51581ea..5887236 100644 --- a/SourceGen/VisualizationSet.cs +++ b/SourceGen/VisualizationSet.cs @@ -174,7 +174,7 @@ namespace SourceGen { /// Project reference. public static void RefreshAllThumbnails(DisasmProject project) { ScriptSupport iapp = null; - List plugins = null; + Dictionary plugins = null; SortedList visSets = project.VisualizationSets; @@ -248,9 +248,9 @@ namespace SourceGen { /// List of plugins, from project ScriptManager. /// Visualization generator identifier. /// A plugin that matches, or null if none found. - private static IPlugin_Visualizer FindPluginByVisGenIdent(List plugins, - string visGenIdent, out VisDescr visDescr) { - foreach (IPlugin chkPlug in plugins) { + private static IPlugin_Visualizer FindPluginByVisGenIdent( + Dictionary plugins, string visGenIdent, out VisDescr visDescr) { + foreach (IPlugin chkPlug in plugins.Values) { if (!(chkPlug is IPlugin_Visualizer)) { continue; } diff --git a/SourceGen/WpfGui/EditVisualization.xaml.cs b/SourceGen/WpfGui/EditVisualization.xaml.cs index 7cc90c8..9d87002 100644 --- a/SourceGen/WpfGui/EditVisualization.xaml.cs +++ b/SourceGen/WpfGui/EditVisualization.xaml.cs @@ -84,13 +84,15 @@ namespace SourceGen.WpfGui { /// /// /// Strictly speaking we could just create an ItemsSource from VisDescr objects, but - /// the plugin reference saves a lookup later. + /// the plugin reference saves a lookup later. We store the script ident rather than + /// an IPlugin reference because our reference would be a proxy object that expires, + /// and there's no value in creating a Sponsor<> or playing keep-alive. /// public class VisualizationItem { - public IPlugin_Visualizer Plugin { get; private set; } + public string ScriptIdent { get; private set; } public VisDescr VisDescriptor { get; private set; } - public VisualizationItem(IPlugin_Visualizer plugin, VisDescr descr) { - Plugin = plugin; + public VisualizationItem(string scriptIdent, VisDescr descr) { + ScriptIdent = scriptIdent; VisDescriptor = descr; } } @@ -198,12 +200,12 @@ namespace SourceGen.WpfGui { int visSelection = -1; VisualizationList = new List(); - List plugins = proj.GetActivePlugins(); - foreach (IPlugin chkPlug in plugins) { - if (!(chkPlug is IPlugin_Visualizer)) { + Dictionary plugins = proj.GetActivePlugins(); + foreach (KeyValuePair kvp in plugins) { + if (!(kvp.Value is IPlugin_Visualizer)) { continue; } - IPlugin_Visualizer vplug = (IPlugin_Visualizer)chkPlug; + IPlugin_Visualizer vplug = (IPlugin_Visualizer)kvp.Value; foreach (VisDescr descr in vplug.GetVisGenDescrs()) { if (vis != null && vis.VisGenIdent == descr.Ident) { // found matching descriptor, set selection to this @@ -212,7 +214,7 @@ namespace SourceGen.WpfGui { // we used this one last time, use it if nothing better comes along visSelection = VisualizationList.Count; } - VisualizationList.Add(new VisualizationItem(vplug, descr)); + VisualizationList.Add(new VisualizationItem(kvp.Key, descr)); } } @@ -437,8 +439,9 @@ namespace SourceGen.WpfGui { IVisualization2d vis2d; try { - vis2d = item.Plugin.Generate2d(item.VisDescriptor, - CreateVisGenParams()); + IPlugin_Visualizer plugin = + (IPlugin_Visualizer)mProject.GetPlugin(item.ScriptIdent); + vis2d = plugin.Generate2d(item.VisDescriptor, CreateVisGenParams()); if (vis2d == null) { Debug.WriteLine("Vis generator returned null"); } diff --git a/SourceGen/WpfGui/EditVisualizationSet.xaml.cs b/SourceGen/WpfGui/EditVisualizationSet.xaml.cs index f75828b..9b72f34 100644 --- a/SourceGen/WpfGui/EditVisualizationSet.xaml.cs +++ b/SourceGen/WpfGui/EditVisualizationSet.xaml.cs @@ -125,8 +125,8 @@ namespace SourceGen.WpfGui { } // Check to see if we have any relevant plugins. If not, disable New/Edit. - List plugins = project.GetActivePlugins(); - foreach (IPlugin chkPlug in plugins) { + Dictionary plugins = project.GetActivePlugins(); + foreach (IPlugin chkPlug in plugins.Values) { if (chkPlug is IPlugin_Visualizer) { HasVisPlugins = true; break;