Deterministically order plugins, create cross-plugin call mechanism
[WebThing.git] / PluginManager.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;
+        }
     }
 }