# 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 and 1.0.9 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:

- to compile it as a buildin (static-link it into the pcb executable)
- to compile it as a plugin (dynamic-link it runtime, if the .so is installed in the plugins/ directory)
- to disable the plugin, so it is not compiled at all

I believe such modularization has benefits on multiple levels:

- it is possible to compiler smaller, potentially faster executables by omitting features the specific user would never use anyway
- in a distribution dynamic-link plugins can be distributed as separate packages providing the user with the option to decide what features to install
- such plugins have to have some sort of APIs if they want to reference eachother or if the code needs to reference them; such an API may not (and often did not) exist when the code is part of the core

## 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.0.9 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 | description
--- | --- | --- | --- | ---
autoplace | 612 | works | buildin | Automatically place elements.
autoroute | 4337 | works | buildin | Automatically route selected or all rats. This is the original autorouter.
dbus | 438 | disabled (TODO: needs scconfig support) | disabled | Remote control PCB using DBUS.
djopt | 2320 | works | buildin | Various board optimization algorithms.
export_bom | 374 | works | buildin | Export bom (Bill of Materials)
export_gcode | 2452 | works | buildin | Export to gcode
export_gerber | 972 | works | buildin | Export to gerber
export_lpr | 96 | works | buildin | Export to lpr (using export_ps to generate postscript)
export_nelma | 685 | works | buildin | Export to nelma (Numerical capacitance calculator)
export_png | 1107 | works | buildin | Export to png, gif and jpeg
export_ps | 1613 | works | buildin | Export postscript or embedded postscript.
fontmode | 163 | works | buildin | Font editing actions.
gpmi | 3003 | works | buildin (if gpmi is installed) | 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.
import_edif | 3578 | works | buildin | Import code for netlists in the EDIF format.
import_sch | 259 | works | buildin | Imports element and netlist data from the schematics (or some other source).
legacy_func | 72 | works | buildin | 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.
mincut | 886 | works | buildin | 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.
oldactions | 57 | works | disabled | Random collection of old/obsolete actions. Bell(): audible feedback; DumpLibrary(): print footprint library on stdout
puller | 1884 | works | buildin | Pull traces to minimize their length.
renumber | 222 | works | buildin | Renumber elements (renaming them) and generate a text file for back annotation.
stroke | 124 | partially works (doesn't work with lesstif; works with the gtk hid, but there's no zoom bindings) | disabled (requires libstroke installed) | Gesture recognition with libstroke.
toporouter | 6165 | fails (infinite loop in gts) | disabled | Automatically route selected or all rats using a topological algorithm. This is the new autorouter from 2009.
vendordrill | 572 | works | buildin | Vendor drill mapping.