Add basic plugin infrastructure
authorPhilipp Zabel <philipp.zabel@gmail.com>
Fri, 30 Oct 2009 20:19:58 +0000 (21:19 +0100)
committerPhilipp Zabel <philipp.zabel@gmail.com>
Fri, 30 Oct 2009 22:10:57 +0000 (23:10 +0100)
Makefile
src/main.vala
src/plugin-interface.vala [new file with mode: 0644]
src/plugin-registrar.vala [new file with mode: 0644]

index 99d7b31..414bb64 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,9 +4,11 @@ cinaest_SOURCES = \
        src/movie-list-menu.vala \
        src/movie-list-store.vala \
        src/movie-list-view.vala \
-       src/movie-list-window.vala
+       src/movie-list-window.vala \
+       src/plugin-interface.vala \
+       src/plugin-registrar.vala
 
-cinaest_VALAFLAGS = --vapidir ./vapi --pkg hildon-1 --pkg libosso
+cinaest_VALAFLAGS = --vapidir ./vapi --pkg hildon-1 --pkg libosso --pkg gmodule-2.0
 
 cinaest: ${cinaest_SOURCES}
        valac -o $@ ${cinaest_VALAFLAGS} ${cinaest_SOURCES}
index 28ec410..667e1c1 100644 (file)
@@ -20,6 +20,7 @@ using Hildon;
 
 public class CinaestProgram : Hildon.Program {
        MovieListWindow window;
+       List<Plugin> plugins;
 
        construct {
                Environment.set_application_name ("Cinæst");
@@ -30,7 +31,36 @@ public class CinaestProgram : Hildon.Program {
                add_window (window);
        }
 
+       public void register_plugins () {
+               string plugin_path = Environment.get_variable ("PWD");
+               try {
+                       var directory = File.new_for_path (plugin_path);
+                       var enumerator = directory.enumerate_children (FILE_ATTRIBUTE_STANDARD_NAME, 0, null);
+
+                       FileInfo file_info;
+                       while ((file_info = enumerator.next_file (null)) != null) {
+                               string name = file_info.get_name ();
+
+                               if (name.has_suffix (".so")) {
+                                       Plugin plugin;
+                                       string path = Path.build_filename (plugin_path, name, null);
+
+                                       var registrar = new PluginRegistrar<Plugin> (path);
+                                       registrar.load ();
+
+                                       plugin = registrar.new_object ();
+                                       plugins.append (plugin);
+                                       plugin.hello (window);
+                               }
+                       }
+
+               } catch (Error e) {
+                       stderr.printf ("Error: %s\n", e.message);
+               }
+       }
+
        public void run () {
+               register_plugins ();
                Gtk.main ();
        }
 
diff --git a/src/plugin-interface.vala b/src/plugin-interface.vala
new file mode 100644 (file)
index 0000000..924ea63
--- /dev/null
@@ -0,0 +1,26 @@
+/* This file is part of Cinaest.
+ *
+ * Copyright (C) 2009 Philipp Zabel
+ *
+ * Cinaest is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Cinaest is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public abstract class Plugin : Object {
+       public abstract void hello (Gtk.Window window);
+
+       public delegate void ReceiveMovieFunction (Movie movie);
+
+       public abstract void get_movies (string filter, ReceiveMovieFunction callback, int limit);
+       public abstract void add_movie (Movie movie);
+}
diff --git a/src/plugin-registrar.vala b/src/plugin-registrar.vala
new file mode 100644 (file)
index 0000000..29eed01
--- /dev/null
@@ -0,0 +1,62 @@
+/* This file is part of Cinaest.
+ *
+ * Copyright (C) 2009 Philipp Zabel
+ *
+ * Cinaest is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Cinaest is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public class PluginRegistrar<T> : Object {
+       public string path { get; construct; }
+
+       private Type type;
+       private Module module;
+
+       private delegate Type RegisterPluginFunction ();
+
+       construct {
+               assert (Module.supported ());
+       }
+
+       public PluginRegistrar (string path) {
+               this.path = path;
+       }
+
+       public bool load () {
+               stdout.printf ("Loading plugin with path: '%s'\n", path);
+
+               module = Module.open (path, ModuleFlags.BIND_LAZY);
+               if (module == null) {
+                       return false;
+               }
+
+               stdout.printf ("Loaded module: '%s'\n", module.name ());
+
+               void* function;
+               module.symbol ("register_plugin", out function);
+               RegisterPluginFunction register_plugin = (RegisterPluginFunction) function;
+
+               type = register_plugin ();
+               stdout.printf ("Plugin type: %s\n\n", type.name ());
+
+               // So it doesn't vanish as soon as the registar goes
+               module.make_resident ();
+
+               return true;
+       }
+
+       public T new_object () {
+               return Object.new (type);
+       }
+}
+