← Back to team overview

gtg-contributors team mailing list archive

Plugins architecture

 

Hi all,

  As part of the introduction of the Preferences dialog, I rewrote the
PluginManager somewhat, but I wasn't fully sure what was going on. I was
browsing through the plugins code recently out of curiosity.

  What's in place seems to work, but I wonder if it could be made
simpler somehow. Below are some abstract thoughts...if they make sense,
I can start fiddling with the code in a branch.

=====

  The PluginAPI as-is seems to be more of a proxy object than an
interface. Both plugins and parts of GTG talk to PluginAPI instances and
use them to pass things back and forth.

  To make it a true interface (as I understand it), PluginAPI should be
a class that is never instantiated directly but contains some methods
and properties that are inherited by any class that wants to "expose"
that interface. Other objects can then call those methods, expecting
they will do useful things.

  The question then becomes whether the bits of GTG core should expose
an interface to plugins, or vice versa; I think it is clear that it
should be the former.

So, to refactor the plugin code, the idea would be:
 * Make the TaskBrowser, TaskEditor, PreferencesDialog and other objects
subclasses of PluginAPI.
 * "Adjust" the PluginAPI so the functions work no matter which subclass
they are called on. Also add features so plugins can determine which
object they are talking to.
 * Improve the PluginManager to inspect plugin instances for methods
like on_task_whatever and call them. Code like:

    def onTaskLoad(self, plugin_api):
        """Pass the onTaskLoad signal to all active plugins."""
        for plugin in self.active_plugins().itervalues():
            plugin.instance.onTaskOpened(plugin_api)
     
    def onTaskClose(self, plugins, plugin_api):
        """Pass the onTaskClose signal to all active plugins."""
        for plugin in self.active_plugins().itervalues():
            if hasattr(plugin.instance, 'onTaskClosed'):
                plugin.instance.onTaskClosed(plugin_api)

...can be replaced by a single all-purpose method. Or we could go
HARDXCORE and use DBus internally...but maybe that is overkill.

  Anyway, let me know what you think.

Cheers,
-- 
Paul Kishimoto
MASc candidate (2010), Flight Systems & Control Group
University of Toronto Institute for Aerospace Studies (UTIAS)

http://paul.kishimoto.name — +19053029315