Italian Python User Group
A simple preamble about the history and the project purposes.
PlugBoard is born because of the need to create several plugin-based projects. These projects, currenly got a plugin management system many times different and not much organized. So, we decided to create a shared plugin system to use in all kinds of environments (my projects used GTK and console).
Actually, we chose Zope Interfaces to gain a good abstraction level for both the framework and its based applications.
The framework tries to offer as much utilities as possible to create a plugin-based application and at the same time to be as much flexible as possible, so that this framework could be applied to all kinds of projects.
An application based on this phylosophy should base everything on plugins, to let plugins be the core of the application as well, even the programmer decide to let the core be pluggable.
Simply explain what components are found in PlugBoard and how they could be connected each other.
The main component of the framework is the application interface (IAPPLICATION) used for reference by all other components: it should be initialized before using any other component. The application implementation should do nothing else that add some useful functions and hooks (such as adapters) to let the development be as the easier and faster as possible.
After the application initialization, registered plugins (IPLUGIN) must be found trough a plugin resource manager (IPLUGINRESOURCE). The plugin resources then adds internally all found plugins and register itself (the instance) as an IAPPLICATION adapter, so that the application could implement its own plugin resource following the interface scheme.
At this point, the application is configured and ready to be loaded using the context resource (ICONTEXTRESOURCE), which groups some plugins and loads them passing for the following three states:
Just after the initialization of each plugin, the plugin instance is registered as an adapter of IAPPLICATION so plugins could reach other plugins adapting the application to the requested plugin interface.1
The last optional but recomended component is the engine (IENGINE). It's something like a protocol that specifies how plugin communicate each other trough events and contain some useful utilities for a specified environment. Mandatory engine components are the event dispather (IEVENTDISPATCHER, registered as an adaptiong for IPLUGIN) and its events (IEVENT, adaption for IEVENTDISPATCHER).
Then each plugin could have its own event dispatcher based on the current engine to let other plugins connect to it.
Event connecting is also simplified by the event connector. Its behavior consists in getting all objects contained in self starting with ``on_'' and connecting them as callbacks for the rest of the object name as the event name to the specified plugin. Usually, it doesn't need to be implemented for each different engine since it uses the engine abstraction.
The setuptools plugin resource is used to gain the list of application plugins registered using setuptools entry points.
A simple usage:
from plugboard import plugin
plugin.SetuptoolsPluginResource(application, 'application.entry.point').refresh()
This resource gains context informations from a xml.dom.minidom.Element element, looking in its children.
A simple usage:
from xml.dom import minidom
xmlstr = ``''''<root>
<context name='ctx1'>
<plugin path='app.plugins.APlugin' />
<plugin path='app.plugins.BPlugin' />
</context>
``''''
from plugboard import context
context.XMLContextResource(application, minidom.parseString(xmlstr).documentElement).refresh()
The PlugBoard engine doesn't define any utility for applications, since it's the most general purpose engine. However, it has a really simple method for event dispatching: it stores observer callbacks and call them when an emit is requested.
This engine can be used in GTK 2.8 or above, since it exploits the creation of GTK signals2 into a generic GObject. So, everytime a signal is requested to be created, a new gobject is instantiated. To grant the integrity of the first argument passed to the callback to be the plugin instance and not the gobject when firing the event, connect_object is used instead of connect.
This class automatically connects its callable attributes beggining with ``on_'' to the specified plugin. The event name to be used is described in the object name itself, just after the ``on_'' string: for example ``on_new'' would connect to the event ``new''. For instance, these callable objects (usually methods) could hold an attribute called extra which contains extra arguments to be passed to the connect method of IEVENT.
A simple usage:
from plugboard import plugin, engine
from zope.interface import implements
import interfaces
class APlugin(plugin.Plugin):implements(interface.IAPlugin)
def __init__(self, application):self.dispatcher = engine.IEventDispatcher(self)
class BToAEventConnector(engine.EventConnector):self.dispatcher.add_event('new', (str, 'Some data type'))def load(self, context):self.dispatcher['new'].emit('Some data')def on_new(self, plugin, data, extra):class BPlugin(plugin.Plugin):...implements(interfaces.IBPlugin)
def preload(self, application):ec = BToAEventConnector(interfaces.IAPlugin(application))
ec.on_new.extra = ('first extra argument',)
This document was generated using the LaTeX2HTML translator Version 2002-2-1 (1.71)
Copyright © 1993, 1994, 1995, 1996,
Nikos Drakos,
Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999,
Ross Moore,
Mathematics Department, Macquarie University, Sydney.
The command line arguments were:
latex2html -no_subdir -split 0 -show_section_numbers /tmp/lyx_tmpdir182BNLobm/lyx_tmpbuf0/plugboard.tex
The translation was initiated by on 2006-02-09