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.

File Management

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 (eg, Library/SketchUp/SketchApps) under each user's home directory. By imposing certain File Layout conventions, SketchApps helps plugins to avoid stepping on each others' files, promotes the use of shared code, and generally eases maintenance.

Plugin Framework

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, metaprogramming, 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 main method, 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 main method is invoked. Only then is the majority of the plugin's code loaded and run.

Dialog Framework

In order to create and use WebDialogs, plugins must generate CSS, HTML, and JavaScript code. Ruby on Rails' view subsystem handles this task admirably, using ERuby-based templates. The Dialog Framework generally follows this approach, but adds a few tricks (eg, JavaScript-defining Ruby "macros").

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!

Topic revision: r6 - 21 Jun 2012, RichMorin
This site is powered by Foswiki Copyright © by the contributing authors. All material on this wiki is the property of the contributing authors.
Foswiki version v2.1.6, Release Foswiki-2.1.6, Plugin API version 2.4
Ideas, requests, problems regarding CFCL Wiki? Send us email