Deterministically order plugins, create cross-plugin call mechanism
authorChip Black <bytex64@bytex64.net>
Tue, 9 Jun 2009 08:49:59 +0000 (03:49 -0500)
committerChip Black <bytex64@bytex64.net>
Tue, 9 Jun 2009 08:49:59 +0000 (03:49 -0500)
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.

PluginManager.cs
plugins/Session.cs
plugins/Vimish.cs

index 051c6ab..551d5fd 100644 (file)
@@ -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;
+        }
     }
 }
index bec316f..559f250 100644 (file)
@@ -49,4 +49,9 @@ public class Session : WebThingPlugin {
         Options[SessionName] = String.Join(" ", Uris.ToArray());
         SaveConfig();
     }
+
+    public void DeleteSession(string SessionName) {
+        Options.Remove(SessionName);
+        SaveConfig();
+    }
 }
index bcb1546..27543ee 100644 (file)
@@ -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();
     }