SketchApps - Rationale
While writing some SketchUp plugins
for Igloo Studios
I encountered a number of development issues.
At first, I created specialized solutions to address these issues,
but I soon realized that a more general approach was needed.
After all, why should I (and other SketchUp developers)
have to fight the same battles again and again?
So, taking inspiration (as well as a number of good ideas)
from the Ruby on Rails
web application framework
I began work on SketchApps and its plugin framework
This page describes a number of plugin development issues
and the manner in which the plugin framework addresses them.
Please contact me
if anything is unclear, seems wrong-headed, etc.
SketchUp requires plugins and their supporting files
to be stored under a common, "system" directory.
Each plugin contributes its own files and/or sub-directories.
This approach works reasonably well for simple situations
(eg, a few plugins by a single author), but it does not scale well.
In most situations where a common "name space" must be shared,
conventions and/or coordination are used to avoid conflicts and keep things orderly.
However, the plugin directory has nothing of this sort,
so file or directory names may conflict, related files may not be located together, etc.
The presence of multiple users or projects on a single system makes matters worse.
Administration of the common resource can become a challenge,
involving everything from logistics to personal preferences.
This can lead to annoyance, confusion, and possible error.
So, SketchApps sets up and manages a directory tree
) under each user's home directory.
By imposing certain File Layout
SketchApps helps plugins to avoid stepping on each others' files,
promotes the use of shared code, and generally eases maintenance.
SketchUp plugins are also required to share a number of Ruby resources
(eg, menu items, name spaces, processing time).
To make this easier, more efficient, and more reliable,
the Plugin Framework
implements a plugin registration system,
based on lazy loading
, and a few other tricks.
In a nutshell, a single loader plugin
- sets up common infrastructure (eg, logging)
- scans the SketchApps directory tree for plugins
- runs each plugin's stub code (eg, registers menu items)
- organizes the data (eg, creates a tree of menu items)
- sets up sub-menus, menu items, toolbars, tool icons, etc.
After defining a bootstrap class and its
each plugin's stub registers callbacks for menu items, tool icons, etc.
If and when the plugin is invoked (eg, by use of a menu item),
the bootstrap class is instantiated and its
method is invoked.
Only then is the majority of the plugin's code loaded and run.
In order to create and use WebDialogs,
Ruby on Rails' view subsystem handles this task admirably,
The Dialog Framework
generally follows this approach,
To ease debugging and testing of client-side code,
the framework also lets plugins send dialogs to a browser
I already use this for debugging dynamically-generated HTML;
I also plan to add support for automated testing.
This wiki page is maintained by Rich Morin
an independent consultant specializing in software design, development, and documentation.
Please feel free to email
comments, inquiries, suggestions, etc!