1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-11 17:29:29 +00:00

Fix proxy object timeout in visualization editor

The visualization editor was retaining an IPlugin reference for the
visualization generator selection combo box.  After 5 minutes the
proxy object timed out, so if you left the editor open and inactive
for that long you'd start getting weird errors.

We now keep the script identifier string and use that to get a
fresh IPlugin proxy object.
This commit is contained in:
Andy McFadden 2019-12-28 14:00:48 -08:00
parent 1759317c8c
commit 7c2fbec773
6 changed files with 55 additions and 45 deletions

View File

@ -132,14 +132,16 @@ namespace PluginCommon {
/// Generates a list of references to instances of active plugins.
/// </summary>
/// <returns>Newly-created list of plugin references.</returns>
public List<IPlugin> GetActivePlugins() {
List<IPlugin> list = new List<IPlugin>(mActivePlugins.Count);
public Dictionary<string, IPlugin> GetActivePlugins() {
Dictionary<string, IPlugin> dict =
new Dictionary<string, IPlugin>(mActivePlugins.Count);
foreach (KeyValuePair<string, IPlugin> 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;
}
/// <summary>

View File

@ -2496,9 +2496,12 @@ namespace SourceGen {
}
// Punch-through functions; trying to avoid exposing ScriptManager for now.
public List<PluginCommon.IPlugin> GetActivePlugins() {
public Dictionary<string, PluginCommon.IPlugin> GetActivePlugins() {
return mScriptManager.GetActivePlugins();
}
public PluginCommon.IPlugin GetPlugin(string scriptIdent) {
return mScriptManager.GetInstance(scriptIdent);
}
public void PrepareScripts(PluginCommon.IApplication appRef) {
mScriptManager.PrepareScripts(appRef);
}

View File

@ -140,15 +140,17 @@ namespace SourceGen.Sandbox {
/// </summary>
/// <returns>Newly-created list of plugin references.</returns>
public List<IPlugin> GetAllInstances() {
Dictionary<string, IPlugin> dict;
if (DomainMgr == null) {
List<IPlugin> list = new List<IPlugin>(mActivePlugins.Count);
foreach (KeyValuePair<string, IPlugin> kvp in mActivePlugins) {
list.Add(kvp.Value);
}
return list;
dict = mActivePlugins;
} else {
return DomainMgr.PluginMgr.GetActivePlugins();
dict = DomainMgr.PluginMgr.GetActivePlugins();
}
List<IPlugin> list = new List<IPlugin>(dict.Count);
foreach (KeyValuePair<string, IPlugin> kvp in dict) {
list.Add(kvp.Value);
}
return list;
}
/// <summary>
@ -272,36 +274,36 @@ namespace SourceGen.Sandbox {
return plSymbols;
}
#if false
public delegate bool CheckMatch(IPlugin plugin);
public IPlugin GetMatchingScript(CheckMatch check) {
Dictionary<string, IPlugin> plugins;
if (DomainMgr == null) {
foreach (KeyValuePair<string, IPlugin> kvp in mActivePlugins) {
if (check(kvp.Value)) {
return kvp.Value;
}
}
plugins = mActivePlugins;
} else {
List<IPlugin> 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
/// <summary>
/// Returns a list of loaded plugins. Callers should not retain this list, as the
/// set can change due to user activity.
/// </summary>
public List<IPlugin> GetActivePlugins() {
public Dictionary<string, IPlugin> GetActivePlugins() {
if (DomainMgr == null) {
List<IPlugin> plist = new List<IPlugin>();
// copy the contents
Dictionary<string, IPlugin> pdict = new Dictionary<string, IPlugin>();
foreach (KeyValuePair<string, IPlugin> 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<IPlugin> plugins = DomainMgr.PluginMgr.GetActivePlugins();
foreach (IPlugin plugin in plugins) {
Dictionary<string, IPlugin> 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);

View File

@ -174,7 +174,7 @@ namespace SourceGen {
/// <param name="project">Project reference.</param>
public static void RefreshAllThumbnails(DisasmProject project) {
ScriptSupport iapp = null;
List<IPlugin> plugins = null;
Dictionary<string, IPlugin> plugins = null;
SortedList<int, VisualizationSet> visSets = project.VisualizationSets;
@ -248,9 +248,9 @@ namespace SourceGen {
/// <param name="plugins">List of plugins, from project ScriptManager.</param>
/// <param name="visGenIdent">Visualization generator identifier.</param>
/// <returns>A plugin that matches, or null if none found.</returns>
private static IPlugin_Visualizer FindPluginByVisGenIdent(List<IPlugin> plugins,
string visGenIdent, out VisDescr visDescr) {
foreach (IPlugin chkPlug in plugins) {
private static IPlugin_Visualizer FindPluginByVisGenIdent(
Dictionary<string, IPlugin> plugins, string visGenIdent, out VisDescr visDescr) {
foreach (IPlugin chkPlug in plugins.Values) {
if (!(chkPlug is IPlugin_Visualizer)) {
continue;
}

View File

@ -84,13 +84,15 @@ namespace SourceGen.WpfGui {
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
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<VisualizationItem>();
List<IPlugin> plugins = proj.GetActivePlugins();
foreach (IPlugin chkPlug in plugins) {
if (!(chkPlug is IPlugin_Visualizer)) {
Dictionary<string, IPlugin> plugins = proj.GetActivePlugins();
foreach (KeyValuePair<string, IPlugin> 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");
}

View File

@ -125,8 +125,8 @@ namespace SourceGen.WpfGui {
}
// Check to see if we have any relevant plugins. If not, disable New/Edit.
List<IPlugin> plugins = project.GetActivePlugins();
foreach (IPlugin chkPlug in plugins) {
Dictionary<string, IPlugin> plugins = project.GetActivePlugins();
foreach (IPlugin chkPlug in plugins.Values) {
if (chkPlug is IPlugin_Visualizer) {
HasVisPlugins = true;
break;