cad-editor/docs/PR-plugin-host.md
Michael Flynn e46701456f Add plugin host architecture and Storm Sewer add-on package
Generic plugin runtime (src/plugin/, HostSession, per-tab plugin_state, command router). QGIS-style add-on layout with plugin.toml and single PluginRegistration. Storm Sewer refactored as reference consumer with dispatch.rs, catchments, LandXML, headless tests (43 passing). Core update.rs decoupled from storm_sewer via CadCommand object-pick hooks. Docs: plugin-architecture.md, plugin-template, PR and issue-78 reply drafts.
2026-06-09 13:41:21 -04:00

2.7 KiB

PR: Add plugin host (Phase 1)

Target: HakanSeven12/OpenCADStudio
Branch: feature/plugin-host on mf4633/OpenCADStudio
Related: Issue #78 (Storm Sewer interest check / extension architecture)

Summary

Introduces a QGIS-style add-on architecture so discipline-specific tools (storm sewer, sanitary, geotech, …) can ship outside the core application. Core ribbon tabs (Home, Model, View, …) are unchanged. Add-on packages register ribbon + commands through a single PluginRegistration hook.

This PR contains only the generic host — no Storm Sewer tab, no stormsewer engine crate, no civil/hydraulics code in src/modules/.

What's included

Area Change
src/plugin/ Manifest, registry, BuiltinPlugin trait, try_dispatch
src/app/plugin_host.rs HostSession adapter (document, undo, tab state, command line)
src/app/document.rs Per-tab plugin_state map keyed by plugin id
src/app/commands.rs Plugin dispatch before legacy command match
src/command/mod.rs Generic ObjectPickHit + acquisition hooks on CadCommand
build.rs Skips dirs with plugin.toml (add-ons register via plugin host)
src/ui/ribbon/mod.rs all_ribbon_modules() = core tabs + plugin tabs
docs/plugin-architecture.md Accepted architecture spec
docs/plugin-template/ Scaffold for new add-on authors

Design principles

  1. src/plugin/ must not import domain modules — keeps core mergeable.
  2. One package, one registrationplugin.toml + register.rs + BuiltinPlugin.
  3. DWG round-trip — plugins persist domain data on entity XDATA (documented per add-on in PLUGIN.md).
  4. Phase 2 ready — same plugin.toml layout for future dynamic .dll loading.

How to add an add-on (after merge)

Copy docs/plugin-template/src/modules/<name>/, implement BuiltinPlugin, add pub mod <name>; to modules/mod.rs. No edits to commands.rs.

External repos: depend on extracted ocs_plugin_api (Phase 1b, follow-up PR).

Follow-up (not in this PR)

  • ocs_plugin_api workspace crate (semver-stable host surface)
  • Dynamic plugin loading (%APPDATA%/OpenCADStudio/plugins/)
  • Python/scripting bindings over host API (#29)
  • Storm Sewer add-on — separate repo/PR: mf4633 branch feature/storm-sewer-module

Testing

cargo build
cargo test --lib

No domain plugin is registered in this branch; existing core tests should pass unchanged.

Review questions

  1. OK to add inventory-based plugin registration (same pattern as CommandRegistration)?
  2. Should built-in add-ons ever live in the main repo, or only the host + template?
  3. Priority for Phase 1b (ocs_plugin_api crate) vs Phase 2 (dynamic loading)?