pcb-rnd modularization

Why bother...

I believe good software should be modular. This is especially important in the context of large software, such as CAD applications. There should be a thin core that can model the world and provide the basic operations defined on it but anything else should go in separate modules.

Fortunately PCB already had a strong infrastructure supporting this idea. It has dynamic loadable plugins and the GUI and exporters are in separate HID modules. While working on pcb-gpmi and later pcb-rnd, I added the gpmi module as a separate plugin.

In version 1.0.8 to 1.1.0 a cosiderable chunk of core code has been moved into core plugins. A core plugin is just a plugin that is maintained together with the core, in the same repository, still the code is somewhat detached from the core. More importantly, the user can choose, for each plugin, separately:

I believe such modularization has benefits on multiple levels:

Progress in charts

Before-after

All numbers are in SLOC and are acquired running sloccount on the given directory. While lines of code alone is not a true measure of complexity, it's a good estimation. The slices of pie charts are the major components of the pcb-rnd executable.
       
Before modularization: pcb-rnd version 1.0.7
Note: gpmi was already a plugin
After modularization: pcb-rnd version 1.1.0
Note: gpmi is part of the "plugins" slice

Zooming on to the plugins

(Red means the plugin doesn't really work).

Progress in numbers

Below is a table with the summary of core plugins.
module size [sloc] status configure
default
class description
autocrop158 works buildin (feature) Reduce the board dimensions to just enclose the elements.
autoplace614 works buildin (feature) Automatically place elements.
autoroute4343 works buildin (feature) Automatically route selected or all rats. This is the original autorouter.
boardflip131 WIP
(doesn't update rtrees)
disabled (feature) All objects on the board are up-down flipped.
dbus483 WIP
(needs to install the xml?)
disabled (feature) Remote control PCB using DBUS.
diag162 works disabled (feature) Actions for pcb-rnd core diagnostics, intended for developers. These are not in core because end users normally don't need these. As a plugin, due to dynamic loading, it can be dropped on an existing pcb-rnd installation with minimal risk of scaring away a reproducible bug.
distalign428 works buildin (feature) Introducing Align() and Distribute(), which work much like the similarly named functions in Visio. Given that PCB does not have the concept of "first selected object" to draw on, the reference points can be selected by arguments.
distaligntext466 works buildin (feature) Same as distalign, operates on text objects.
djopt2320 works buildin (feature) Various board optimization algorithms.
export_bboard426 WIP disabled export Export breadboard
export_bom230 works buildin export Export bom (Bill of Materials)
export_dsn443 Work-in-progress disable export Export specctra .dsn files
export_dxf3992 WIP disabled export Export dxf
export_gcode2466 works buildin export Export to gcode
export_gerber971 works buildin export Export to gerber
export_ipcd356468 Work-in-progress disable export IPC-D-356 Netlist export.
export_lpr106 works buildin export Export to lpr (using export_ps to generate postscript)
export_nelma679 works buildin export Export to nelma (Numerical capacitance calculator)
export_openscad1394 WIP disabled export Export openscad
export_png1120 works buildin export Export to png, gif and jpeg
export_ps1638 works buildin export Export postscript or embedded postscript.
export_test257 disabled
(work in progress)
buildin export A thin layer of code to dump exporter calls for testing the HID exporter API.
export_xy270 works buildin export Export XY centroid element data for pick & place.
fontmode165 works buildin (feature) Font editing actions.
fp_fs379 works buildin fp Footprint: file system based implementation. Used to be called Newlib: load footprints from directories. Run external processes for the parametric footprints.
fp_wget302 works buildin fp Footprint: get static (file) footprints from the web, e.g. from http://gedasymbols.org
gl590 disabled
(pcb-rnd has no support for opengl.)
disabled (feature) Common gl functions for hids.
gpmi3046 works buildin
(if gpmi is installed)
(feature) Scriptable plugin system with about 10 scripting languages supported and dynamic load/unload of scripts that can manipulate the GUI, the board, can implement exporters, etc.
hid_batch333 works buildin hid HID without GUI; read actions from stdin.
hid_gtk15972 works buildin hid GUI: the GTK HID.
hid_lesstif6923 works buildin hid GUI: the lesstif HID.
import_dsn114 Work-in-progress disable import Import specctra .dsn files
import_edif3621 works buildin import Import plugin for netlists in the EDIF format.
import_netlist131 works buildin import Import plugin for netlists in the classic pcb netlist format.
import_sch301 works buildin import Imports element and netlist data from the schematics (or some other source).
io_kicad998 work-in-progress disabled io Load and save the design and elements in Kicad's s-expression format - this is the new, currently preferred format in Kicad.
io_kicad_legacy941 work-in-progress buildin io Load and save the design and elements in Kicad's legacy format.
io_lihata1042 WIP disabled io Load and save the design and elements in the lihata board format.
io_pcb2174 works buildin io Load and save the design and elements in the original pcb text format.
jostle446 works buildin (feature) Pushes lines out of the way.
lib_gensexpr6 works disabled (lib) S-expression parser lib
lib_legacy_func74 works buildin (lib) Random collection of old/obsolete (legacy) functions. 3rd party plugins may depend on them. This module implements C functions and variables and does not register actions or flags.
loghid273 WIP disabled (feature) Sits between a HID (or exporter) and the core and logs all core->plugin calls made through the HID structure.
mincut909 works buildin (feature) Use the minimal cut algorithm to indicate shorts: instead of highlighting two random pins/pads, try to highlight the least number of objects that connect the two networks.
oldactions155 works disabled (feature) Random collection of old/obsolete actions. Bell(): audible feedback; DumpLibrary(): print footprint library on stdout; a set of debug actions useful for writing pcb scripts: Debug(), DebugXY(), Return(). Old plugin actions to toggle or set settings that are now accessible via the unified config system (vendordrill, djopt)
polycombine208 works buildin (feature) The selected polygons are combined together according to the ordering of their points.
polystitch185 segfaults disable (feature) The polygon under the cursor (based on closest-corner) is stitched together with the polygon surrounding it on the same layer. Use with pstoedit conversions where there's a "hole" in the shape - select the hole.
propedit766 works buildin (feature) List and edit properties of a group of objects.
puller1888 works buildin (feature) Pull traces to minimize their length.
query1823 WIP disable (feature) pcb-rnd query language: execute expressions on objects and rules for the programmed drc.
renumber310 works buildin (feature) Renumber elements (renaming them) and generate a text file for back annotation.
report749 works buildin (feature) Report() and ReportObject() actions - print a report about design objects.
shand_cmd212 works buildin (feature) vi-like command shorthands (1..3 character long commands)
smartdisperse173 works buildin (feature) Improve the initial dispersion of elements by choosing an order based on the netlist, rather than the arbitrary element order. This isn't the same as a global autoplace, it's more of a linear autoplace. It might make some useful local groupings. For example, you should not have to chase all over the board to find the resistor that goes with a given LED.
stroke135 partially works (doesn't work with lesstif; works with the gtk hid, but there's no zoom bindings) disabled (feature) Gesture recognition with libstroke.
teardrops226 works buildin (feature) Draw teardrops on pins.
toporouter6162 fails
(infinite loop in gts)
disabled (feature) Automatically route selected or all rats using a topological algorithm. This is the new autorouter from 2009.
vendordrill513 works buildin (feature) Vendor drill mapping.

Classes

Each plugin implements a class (rarely a set of classes). Classes are:
name description
(feature) random features directly accessible for the user, usually actions
(lib) support code library for other plugins (core doesn't depend on these); functionality not directly accessible for the user but other plugins may depend on it
hid Human Interface Device: interactive user interface, usually GUI
import load alien formats into the design space
export save (parts of) the design space in alien formats
fp footprint (element) library implementation
io native file format (save & load) implementation