Module | PlugMan |
In: |
src/PlugMan.rb
|
PlugMan is the Plugin Manager for the plugin architecture for ruby applications.
PlugMan is the main interface to the plugin architecture, it manages a register of plugins and also allows plugins to discover other plugins that attached to extension points.
Plugins can:
More information on how this hangs together can be found in the Plugin class’ documentation.
PlugMan defines a convenient "root" plugin that may (or may not) be used as the base plugin for an application. It has a single extension point and doesn‘t do anything else really. You are free to ignore the root plugin or make your own base plugin if that suits.
If any plugins are defined without a parent plugin, they will be assigned the root plugin as a "required" plugin. This ensures no plugins are orphaned and by stopping the root plugin, all other plugins in the system will also be stopped. (Although it is possible to have no plugins attached to root, so this isn‘t enforced with any vigor…)
The PlugMan.define method is used to register each plugin. You don‘t actually create classes that extend Plugin, you create a proc that is a parameter to PlugMan.define that is used to create an instance of Plugin for you.
Typically all the plugins will live in a subdirectory tree and will be loaded early in the application‘s lifecycle using the PlugMan.load_plugins(PLUGIN_DIR) method, but plugins can also be loaded at any time in an application‘s lifecycle.
PlugMan assumes that plugin files have the extension .rb and PlugMan.load_plugins will attempt to load and register all .rb files in the drectory tree. Each .rb file should have the format
PlugMan.define :plugin_name do ... see rdoc for Plugin for more details on how to define a plugin's guts end
PlugMan also includes the Observable module. Listeners can be informed whenever a plugin is started/stopped. It is currently a simple mechansim where the name and new state of the plugin are passed to the listeners. Currently the states a plugin can be in are :stopped, :started or :error.
An example of observer use is:
# add observer somewhere in your code def do_something PlugMan.add_observer(self) end ## the callback method is update def update(state, plugin) puts "Plugin #{plugin.name.inspect} changed state to #{state.inspect}" end ## remove observer somewhere def do_another_thing PlugMan.delete_observer(self) end
ROOT_PLUGIN | = | :root | Root plugin, any orphan plugins will be automatically belonged to here. | |
ROOT_EXTENSION_POINT | = | :root | Root extension point, in case you want to use the root plugin and extension point for convenience. Can be safely ignored. | |
PLUGMAN_VERSION | = | "0.0.3" | Version information for PlugMan |
Registers a plugin. See Plugin for more information about defining a plugin.
Do not create plugins using Plugin.new as they won‘t be registered with PlugMan.
The plug_name must be unique amongst plugins and it will be converted to a symbol. &block is the actual code that will make up the plugin (once again, see Plugin for more details.)
Once a plugin is defined, it will be available using PlugMan.registered_plugins[:plug_name] and any plugins that extend it can be discovered using PlugMan.extensions(:plug_name, ext_point)
If a plugin is declared more than once, the instance with the greatest version number will be used (any older version will be discarded.)
When a plugin is initially defined, it is put into the :stopped state.
Gets a hash of all the registered plugins, key is a plugin name (as a symbol), value is the Plugin object.
Gets all the plugins that depend on the named plugin (the plugins that decare plugin_name as :required or :extends)
Starts a plugin and the plugins it requires. When a plugin is started, any observers are notified of the change.
If a plugin isn‘t started correctly, a PluginError(:start_failed) exception is raised.
Stops a plugin and the plugins that depend on it. When a plugin is stopped, any observers are notified of the change.
If a plugin isn‘t stopped correctly, a PluginError(:stop_failed) exception is raised.