[tor-commits] [vidalia/alpha] Add first draft of the plugin framework documentation

chiiph at torproject.org chiiph at torproject.org
Sat Jul 2 21:53:46 UTC 2011


commit 5bed9056139a2d33042995f1f0e7838fb43c9a3d
Author: Tomas Touceda <chiiph at gentoo.org>
Date:   Tue May 17 13:50:31 2011 -0300

    Add first draft of the plugin framework documentation
---
 doc/plugin-framework.txt |  153 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/doc/plugin-framework.txt b/doc/plugin-framework.txt
new file mode 100644
index 0000000..e00ab8c
--- /dev/null
+++ b/doc/plugin-framework.txt
@@ -0,0 +1,153 @@
+Plugin Framework specification
+
+1. Directory structure:
+
+  Each plugin will live inside its own directory, separated from all the
+  other plugins.
+  The directory will contain the following:
+    info.xml      *
+    <file>.js     **
+    <subdir>/     ***
+
+    * The plugin description will live inside an XML file named info.xml,
+    its specification will be specified later.
+
+    ** Each source code file that the plugin uses will have a "js"
+    extension. The plugin may contain any other kind of files, along with
+    other source code files.
+
+    *** The plugin may contain any sort of directory dispositions. The
+    developer can reference files within subdirectories freely. The main
+    file can live anywhere within the plugin directory, as long as its
+    relative path is specified correctly in the info.xml file.
+
+2. Definition file:
+
+  The definition file for a plugin will be a XML file with the following DTD:
+
+  <!DOCTYPE VidaliaPlugin [
+    <!ENTITY name (#CDATA)>
+    <!ENTITY date (#CDATA)>
+    <!ENTITY author (#CDATA)>
+    <!ENTITY type (EMPTY)>
+      <!ATTLIST type persistent CDATA "false">
+      <!ATTLIST type gui CDATA "false">
+    <!ENTITY files (file+)>
+      <!ENTITY file (#CDATA)>
+    <!ENTITY namespace (#CDATA)>
+  ]>
+
+  Short description:
+  - Name, date and author are self explanatory.
+  - Type: 
+    - Persistent: A plugin is persistent if it starts when Vidalia starts,
+    and it doesn't matter if the GUI (if it has one) is visible or not, the
+    plugin code is in execution.
+    - GUI: True if the plugin has a GUI.
+  - Files: Plugins may contain several source code files. The different
+  functions that must be implemented for it to work may be divided into
+  several files, or just one. Whatever the case may be, the files that the
+  plugin engine has to load must be specified in here. The plugin may use
+  other files, which don't need to be listed.
+  - Namespace: Each plugin will have its own namespace to avoid function
+  name collisions (the main functions will be named the same)
+
+3. Plugin functions:
+
+  Each plugin must implement the following functions:
+    start() : void
+    stop() : void
+    buildGUI() : VidaliaTab *
+
+  If the plugin isn't a GUI one, a default implementation will be added
+  that returns QScriptValue::NullValue.
+  Plugins may use several different files to implement its functionality.
+  To include files within other files use:
+
+    include("path/to/file.js") 
+  
+  This will be implemented by Vidalia's engine, it's not a native include
+  call. Another possibility would be to just list the file in the info.xml
+  file, and the engine will load it automatically and in order.
+
+4. Building an interface for a class to be used in a plugin:
+
+  To provide any class to be used in a plugin, there are two main parts to
+  implement: the constructor, and the prototype:
+    - Constructor: each constructable object in a plugin need to have
+    	a static constructor function implemented with the following
+    	signature:
+
+    	QScriptValue f(QScriptContext *, QScriptEngine *)
+
+    - Prototype: A prototype is a wrapper for a metatype's methods. This
+    	methods are what will be visible inside the plugin for a given
+    	object.
+
+  The prototype class must inherit from QObject and QScriptable.
+  All types used in the plugin must be handled this way, and must be
+  declared as a Qt Metatype. Each interface must handle the metatype
+  declaration.
+
+5. Settings:
+
+  For specifying where the plugins live, there will be a new item in
+  Vidalia's configuration file: PluginPath. Which will contain the absolute
+  path of the plugins.
+
+6. Plugin engine:
+
+  All plugins will leave in the same environment (QScriptEngine). When
+  Vidalia starts, it starts the plugin engine.
+  Here's a bit of pseudo-code to get an idea of the loading process.
+
+  6.1. Startup:
+
+    foreach provided_class:                              (1)
+      load_prototype                                     (2)
+      load_constructor                                   (3)
+
+    scan_plugin_directory                                (4)
+    foreach directory:
+      info = load_info_file                              (5)
+      wrapper = plugin_wrapper(info)                     (6)
+      if info.persistent:
+        wrapper.start()                                  (7)
+      if info.gui:
+        plugin_menu.addAction(wrapper.menu_action())     (8)
+
+    (1) This loop will be probably hardcoded, since there isn't any way to
+    iterate through every class that we want to provide for the plugins.
+    (2) First we need to load the prototype for the given metatype.
+    (3) Then we can add a constructor for the metatype as a function of the
+    global script engine interpreter.
+    (4) Scan the PluginPath for directories that contain the info.xml
+    file.
+    (5) Interpret the info file to see what kind of plugin we are dealing
+    with.
+    (6) A plugin wrapper is an object that abstracts the actual calls to
+    the methods we know the plugin must implement with its corresponding
+    namespace.
+    (7) If it's a persistent plugin, then start it.
+    (8) If it's a gui plugin, add the entry to the plugin menu. If the
+    plugin is also persistent, then the menu action will be linked to
+    a show() function instead of the start(), since the plugin will be
+    already loaded.
+
+  6.2. Quit:
+
+    foreach plugin:
+      wrapper.stop()
+
+7. Things to consider:
+
+  - Will the fact that all the plugins live in the same environment affect
+  	in terms of security? or at least the workflow of each individual
+  	plugin?
+    Possible solution: One instance of QScriptEngine for each plugin (kind
+    of a sandbox). But what will be the performance drawbacks to this?
+  - Is there the need to connect signals emitted from the plugin to
+  	Vidalia? If so, this seems to be a nice implementation:
+  	http://gitorious.org/qtscriptsignalhandler
+  - Do we want to have all files listed in the info.xml file too? May be we
+  	can use that to have some kind of sanity check.





More information about the tor-commits mailing list