commit:02acfc22dbfa3d145d265157fdf616a950fa30c6
author:Chip Black
committer:Chip Black
date:Tue Jun 9 03:49:59 2009 -0500
parents:ac127998500aa775484054cffa889098b3fd6a7b
Deterministically order plugins, create cross-plugin call mechanism

Added a PluginManager.Call(function_name, ...) that allows plugins to
call functions by name.  The plugin manager searches all plugins for
functions matching the name and signature of the arguments, then calls
each in turn.  It in effect creates a simple message-passing system
where callers and callees are anonymous.

Added DeleteSession() to Session, and modified Vimish's command-line to
use the above Call system for non-internal functions.
diff --git a/PluginManager.cs b/PluginManager.cs
line changes: +39/-3
index 051c6ab..551d5fd
--- a/PluginManager.cs
+++ b/PluginManager.cs
@@ -6,11 +6,13 @@ using WebKit;
 namespace bytex64.WebThing {
     public class PluginManager {
         public Dictionary<string,WebThingPlugin> Plugins;
+        public List<string> PluginOrder;
         
         private WebThing wt;
 
         public PluginManager(WebThing wt) {
             Plugins = new Dictionary<string,WebThingPlugin>();
+            PluginOrder = new List<string>();
             this.wt = wt;
         }
 
@@ -29,20 +31,54 @@ namespace bytex64.WebThing {
                     p.Init(wt);
                     Plugins[t.FullName] = p;
                     Console.WriteLine("Successfully loaded {0}", t.FullName);
+                    PluginOrder.Add(t.FullName);
                 }
             }
         }
 
         public void WebViewSetup(WebView view) {
-            foreach (string key in Plugins.Keys) {
+            foreach (string key in PluginOrder) {
                 Plugins[key].InitWebView(view);
             }
         }
 
         public void Deinit() {
-            foreach (WebThingPlugin p in Plugins.Values) {
-                p.Deinit(wt);
+            // This reverses the plugin order on the assumption that it
+            // will only be called once on program shutdown
+            PluginOrder.Reverse();
+            foreach (string key in PluginOrder) {
+                Plugins[key].Deinit(wt);
             }
         }
+
+        public bool Call(string funcname, params object[] args) {
+            bool found = false;
+            if (args.Length > 0) {
+                foreach (string key in PluginOrder) {
+                    WebThingPlugin plugin = Plugins[key];
+                    Type ptype = plugin.GetType();
+
+                    List<Type> types = new List<Type>();
+                    foreach (object o in args)
+                        types.Add(o.GetType());
+
+                    MethodInfo method = ptype.GetMethod(funcname, types.ToArray());
+                    if (method == null) continue;
+                    method.Invoke(plugin, args);
+                    found = true;
+                }
+            } else {
+                foreach (string key in PluginOrder) {
+                    WebThingPlugin plugin = Plugins[key];
+                    Type ptype = plugin.GetType();
+
+                    MethodInfo method = ptype.GetMethod(funcname, new Type[] {});
+                    if (method == null) continue;
+                    method.Invoke(plugin, null);
+                    found = true;
+                }
+            }
+            return found;
+        }
     }
 }

diff --git a/plugins/Session.cs b/plugins/Session.cs
line changes: +5/-0
index bec316f..559f250
--- a/plugins/Session.cs
+++ b/plugins/Session.cs
@@ -49,4 +49,9 @@ public class Session : WebThingPlugin {
         Options[SessionName] = String.Join(" ", Uris.ToArray());
         SaveConfig();
     }
+
+    public void DeleteSession(string SessionName) {
+        Options.Remove(SessionName);
+        SaveConfig();
+    }
 }

diff --git a/plugins/Vimish.cs b/plugins/Vimish.cs
line changes: +16/-0
index bcb1546..27543ee
--- a/plugins/Vimish.cs
+++ b/plugins/Vimish.cs
@@ -139,6 +139,22 @@ public class Vimish : WebThingPlugin {
                 Options[args[1]] = args[2];
             ApplyOptions();
             break;
+        default:
+            bool found;
+            if (args.Length > 1) {
+                string[] callargs = new string[args.Length - 1];
+                Array.Copy(args, 1, callargs, 0, args.Length - 1);
+                found = wt.Plugins.Call(args[0], callargs);
+                if (!found)
+                    Error("No function {0}({1}) found", args[0], String.Join(", ", callargs));
+            } else {
+                found = wt.Plugins.Call(args[0]);
+                if (!found)
+                    Error("No function {0}() found", args[0]);
+            }
+            if (found)
+                Console.WriteLine("Plugin function {0} called successfully", args[0]);
+            break;
         }
         CommandlineHide();
     }