docs: update architecture docs for addon-first model (#255)
Some checks failed
Build and Test / build (pull_request) Failing after 2m1s
Some checks failed
Build and Test / build (pull_request) Failing after 2m1s
ARCHITECTURE.md: - Replace exec()-based bootstrap flow with manifest-driven loader diagram - Add addon lifecycle section (scan → parse → validate → resolve → load → register) - Add SDK and C++ scaffold to source layout - Document load order: sdk (0) → ztools (50) → silo (60) INTEGRATION_PLAN.md: - Add Layer 4 (Addon SDK) between bootstrap and addons (now 5 layers) - Update Layer 3: now hosts both Python loader AND C++ scaffold - Add Phase 1.5 (SDK) and Phase 1.75 (C++ scaffold) as DONE - Update Phase 4 (theme): colors centralized in SDK YAML palette - Update Phase 6 (build): now DONE with CMake install rules for all addons - Add design decisions #7 (SDK as adaptation layer) and #8 (manifest-driven loading) README.md: - Update addon integration section: manifest-driven loading, SDK wrappers - Add mods/sdk/ to project structure tree - Update Create module description to mention C++ scaffold Closes #255.
This commit is contained in:
13
README.md
13
README.md
@@ -112,7 +112,9 @@ Addons extend this through the Python API:
|
|||||||
|
|
||||||
### Addon integration
|
### Addon integration
|
||||||
|
|
||||||
Both ztools and Silo are loaded by the `src/Mod/Create/` bootstrap module, which executes their `Init.py` and `InitGui.py` files at startup. Neither requires the user to switch workbenches. Instead, they register commands and use the editing context system to make those commands visible in the appropriate situations.
|
Addons in `mods/` are loaded by a manifest-driven loader (`src/Mod/Create/addon_loader.py`). Each addon provides a `package.xml` with `<kindred>` extensions declaring version bounds, load priority, and dependencies. The loader resolves dependencies via topological sort and loads addons in order: **sdk** (0) → **ztools** (50) → **silo** (60).
|
||||||
|
|
||||||
|
Addons call platform APIs through the **kindred-addon-sdk** (`mods/sdk/kindred_sdk/`) rather than `FreeCADGui.*` internals directly. The SDK provides stable wrappers for editing contexts, theme tokens, FileOrigin registration, and dock panels.
|
||||||
|
|
||||||
ztools uses a `WorkbenchManipulator` plus `injectEditingCommands()` to add its tools to PartDesign, Assembly, and Spreadsheet contexts. Silo registers an overlay that adds the "Silo Origin" toolbar whenever the active document contains Silo tracking properties (`SiloItemId`, `SiloPartNumber`).
|
ztools uses a `WorkbenchManipulator` plus `injectEditingCommands()` to add its tools to PartDesign, Assembly, and Spreadsheet contexts. Silo registers an overlay that adds the "Silo Origin" toolbar whenever the active document contains Silo tracking properties (`SiloItemId`, `SiloPartNumber`).
|
||||||
|
|
||||||
@@ -179,13 +181,14 @@ create/
|
|||||||
│ │ ├── Stylesheets/ # QSS theme files
|
│ │ ├── Stylesheets/ # QSS theme files
|
||||||
│ │ └── PreferencePacks/ # Theme and preference configurations
|
│ │ └── PreferencePacks/ # Theme and preference configurations
|
||||||
│ ├── Mod/ # FreeCAD modules (PartDesign, Assembly, Sketcher, ...)
|
│ ├── Mod/ # FreeCAD modules (PartDesign, Assembly, Sketcher, ...)
|
||||||
│ │ └── Create/ # Kindred bootstrap module -- loads ztools and Silo
|
│ │ └── Create/ # Kindred Create module (Python loader + C++ scaffold)
|
||||||
│ └── 3rdParty/ # Vendored dependencies
|
│ └── 3rdParty/ # Vendored dependencies
|
||||||
│ ├── OndselSolver/ # Assembly constraint solver (forked)
|
│ ├── OndselSolver/ # Assembly constraint solver (forked)
|
||||||
│ └── GSL/ # Microsoft Guidelines Support Library
|
│ └── GSL/ # Microsoft Guidelines Support Library
|
||||||
├── mods/ # Kindred addon modules (git submodules)
|
├── mods/ # Kindred addon modules
|
||||||
│ ├── ztools/ # ztools command provider
|
│ ├── sdk/ # Addon SDK — stable API contract (priority 0)
|
||||||
│ └── silo/ # Silo PLM workbench
|
│ ├── ztools/ # ztools command provider (submodule, priority 50)
|
||||||
|
│ └── silo/ # Silo PLM workbench (submodule, priority 60)
|
||||||
├── resources/ # Branding, icons, desktop integration, MIME types
|
├── resources/ # Branding, icons, desktop integration, MIME types
|
||||||
├── package/ # Packaging scripts
|
├── package/ # Packaging scripts
|
||||||
│ ├── debian/ # .deb build script
|
│ ├── debian/ # .deb build script
|
||||||
|
|||||||
@@ -5,42 +5,116 @@
|
|||||||
```
|
```
|
||||||
FreeCAD startup
|
FreeCAD startup
|
||||||
└─ src/Mod/Create/Init.py
|
└─ src/Mod/Create/Init.py
|
||||||
└─ setup_kindred_addons()
|
└─ addon_loader.load_addons(gui=False)
|
||||||
├─ exec(mods/ztools/ztools/Init.py)
|
├─ scan_addons("mods/") — find package.xml manifests
|
||||||
└─ exec(mods/silo/freecad/Init.py)
|
├─ parse_manifest() — extract <kindred> extensions
|
||||||
|
├─ validate_manifest() — check min/max_create_version
|
||||||
|
├─ resolve_load_order() — topological sort by <dependency>
|
||||||
|
└─ for each addon in order:
|
||||||
|
├─ add addon dir to sys.path
|
||||||
|
├─ exec(Init.py)
|
||||||
|
└─ register in AddonRegistry (FreeCAD.KindredAddons)
|
||||||
|
|
||||||
└─ src/Mod/Create/InitGui.py
|
└─ src/Mod/Create/InitGui.py
|
||||||
├─ setup_kindred_workbenches()
|
├─ addon_loader.load_addons(gui=True)
|
||||||
│ ├─ exec(mods/ztools/ztools/InitGui.py)
|
│ └─ for each addon in order:
|
||||||
│ │ └─ schedules deferred _register() (2000ms)
|
│ └─ exec(InitGui.py)
|
||||||
│ │ ├─ imports ZTools commands
|
│ ├─ sdk (priority 0): logs "SDK loaded"
|
||||||
│ │ ├─ installs _ZToolsManipulator (global)
|
│ ├─ ztools (priority 50): schedules deferred _register() (2000ms)
|
||||||
│ │ └─ injects commands into editing contexts
|
│ │ ├─ imports ZTools commands
|
||||||
│ └─ exec(mods/silo/freecad/InitGui.py)
|
│ │ ├─ installs _ZToolsManipulator (global)
|
||||||
│ ├─ registers SiloWorkbench
|
│ │ └─ injects commands into editing contexts
|
||||||
│ └─ schedules deferred Silo overlay registration (2500ms)
|
│ └─ silo (priority 60): registers SiloWorkbench
|
||||||
|
│ └─ schedules deferred Silo overlay registration (2500ms)
|
||||||
├─ EditingContextResolver singleton created (MainWindow constructor)
|
├─ EditingContextResolver singleton created (MainWindow constructor)
|
||||||
│ ├─ registers built-in contexts (PartDesign, Sketcher, Assembly, Spreadsheet)
|
│ ├─ registers built-in contexts (PartDesign, Sketcher, Assembly, Spreadsheet)
|
||||||
│ ├─ connects to signalInEdit/signalResetEdit/signalActiveDocument/signalActivateView
|
│ ├─ connects to signalInEdit/signalResetEdit/signalActiveDocument/signalActivateView
|
||||||
│ └─ BreadcrumbToolBar connected to contextChanged signal
|
│ └─ BreadcrumbToolBar connected to contextChanged signal
|
||||||
└─ Deferred setup (QTimer):
|
└─ Deferred setup (QTimer):
|
||||||
|
├─ 500ms: _register_kc_format() → .kc file format
|
||||||
├─ 1500ms: _register_silo_origin() → registers Silo FileOrigin
|
├─ 1500ms: _register_silo_origin() → registers Silo FileOrigin
|
||||||
├─ 2000ms: _setup_silo_auth_panel() → "Database Auth" dock
|
├─ 2000ms: _setup_silo_auth_panel() → "Database Auth" dock
|
||||||
├─ 2000ms: ZTools _register() → commands + manipulator
|
├─ 2000ms: ZTools _register() → commands + manipulator
|
||||||
├─ 2500ms: Silo overlay registration → "Silo Origin" toolbar overlay
|
├─ 2500ms: Silo overlay registration → "Silo Origin" toolbar overlay
|
||||||
├─ 3000ms: _check_silo_first_start() → settings prompt
|
├─ 3000ms: _check_silo_first_start() → settings prompt
|
||||||
├─ 4000ms: _setup_silo_activity_panel() → "Database Activity" dock (SSE)
|
├─ 4000ms: _setup_silo_activity_panel() → "Database Activity" dock
|
||||||
└─ 10000ms: _check_for_updates() → update checker (Gitea API)
|
└─ 10000ms: _check_for_updates() → update checker (Gitea API)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Addon lifecycle
|
||||||
|
|
||||||
|
Each addon in `mods/` provides a `package.xml` manifest with a `<kindred>` extension block:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<kindred>
|
||||||
|
<min_create_version>0.1.0</min_create_version>
|
||||||
|
<load_priority>50</load_priority>
|
||||||
|
<pure_python>true</pure_python>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>sdk</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</kindred>
|
||||||
|
```
|
||||||
|
|
||||||
|
The loader (`addon_loader.py`) processes addons in this order:
|
||||||
|
|
||||||
|
1. **Scan** — find all `mods/*/package.xml` files
|
||||||
|
2. **Parse** — extract `<kindred>` metadata (version bounds, priority, dependencies)
|
||||||
|
3. **Validate** — reject addons incompatible with the current Create version
|
||||||
|
4. **Resolve** — topological sort by `<dependency>` declarations, breaking ties by `<load_priority>`
|
||||||
|
5. **Load** — execute `Init.py` (console) then `InitGui.py` (GUI) for each addon
|
||||||
|
6. **Register** — populate `FreeCAD.KindredAddons` registry with addon state
|
||||||
|
|
||||||
|
Current load order: **sdk** (0) → **ztools** (50) → **silo** (60)
|
||||||
|
|
||||||
## Key source layout
|
## Key source layout
|
||||||
|
|
||||||
```
|
```
|
||||||
src/Mod/Create/ Kindred bootstrap module (Python)
|
src/Mod/Create/ Kindred Create module
|
||||||
├── Init.py Adds mods/ addon paths, loads Init.py files
|
├── Init.py Console bootstrap — loads addons via manifest-driven loader
|
||||||
├── InitGui.py Loads workbenches, installs Silo manipulators
|
├── InitGui.py GUI bootstrap — loads addons, Silo integration, update checker
|
||||||
|
├── addon_loader.py Manifest-driven addon loader with dependency resolution
|
||||||
|
├── kc_format.py .kc file format round-trip preservation
|
||||||
├── version.py.in CMake template → version.py (build-time)
|
├── version.py.in CMake template → version.py (build-time)
|
||||||
└── update_checker.py Checks Gitea releases API for updates
|
├── update_checker.py Checks Gitea releases API for updates
|
||||||
|
├── CreateGlobal.h C++ export macros (CreateExport, CreateGuiExport)
|
||||||
|
├── App/ C++ App library (CreateApp.so)
|
||||||
|
│ ├── AppCreate.cpp Module entry point — PyMOD_INIT_FUNC(CreateApp)
|
||||||
|
│ └── AppCreatePy.cpp Python module object (Py::ExtensionModule)
|
||||||
|
└── Gui/ C++ Gui library (CreateGui.so)
|
||||||
|
├── AppCreateGui.cpp Module entry point — PyMOD_INIT_FUNC(CreateGui)
|
||||||
|
└── AppCreateGuiPy.cpp Python module object (Py::ExtensionModule)
|
||||||
|
|
||||||
|
mods/sdk/ [dir] Kindred addon SDK — stable API contract
|
||||||
|
├── package.xml Manifest (priority 0, no dependencies)
|
||||||
|
├── kindred_sdk/
|
||||||
|
│ ├── __init__.py Public API re-exports
|
||||||
|
│ ├── context.py Editing context wrappers (register_context, register_overlay, ...)
|
||||||
|
│ ├── theme.py YAML-driven palette system (get_theme_tokens, load_palette, Palette)
|
||||||
|
│ ├── origin.py FileOrigin registration (register_origin, unregister_origin)
|
||||||
|
│ ├── dock.py Deferred dock panel helper (register_dock_panel)
|
||||||
|
│ ├── compat.py Version detection (create_version, freecad_version)
|
||||||
|
│ └── palettes/
|
||||||
|
│ └── catppuccin-mocha.yaml 26 colors + 14 semantic roles
|
||||||
|
└── Init.py / InitGui.py Minimal log messages
|
||||||
|
|
||||||
|
mods/ztools/ [submodule] command provider (not a workbench)
|
||||||
|
├── package.xml Manifest (priority 50, depends on sdk)
|
||||||
|
├── ztools/InitGui.py Deferred command registration + _ZToolsManipulator
|
||||||
|
├── ztools/ztools/
|
||||||
|
│ ├── commands/ Datum, pattern, pocket, assembly, spreadsheet
|
||||||
|
│ ├── datums/core.py Datum creation via Part::AttachExtension
|
||||||
|
│ └── resources/ Icons (SDK theme tokens), theme utilities
|
||||||
|
└── CatppuccinMocha/ Theme preference pack (QSS)
|
||||||
|
|
||||||
|
mods/silo/ [submodule → silo-mod.git] FreeCAD workbench
|
||||||
|
├── freecad/package.xml Manifest (priority 60, depends on sdk)
|
||||||
|
├── silo-client/ [submodule → silo-client.git] shared API client
|
||||||
|
│ └── silo_client/ SiloClient, SiloSettings, CATEGORY_NAMES
|
||||||
|
└── freecad/ FreeCAD workbench (Python)
|
||||||
|
├── InitGui.py SiloWorkbench + overlay registration (via SDK)
|
||||||
|
├── silo_commands.py Commands + FreeCADSiloSettings adapter
|
||||||
|
└── silo_origin.py FileOrigin backend for Silo (via SDK)
|
||||||
|
|
||||||
src/Gui/EditingContext.h/.cpp EditingContextResolver singleton + context registry
|
src/Gui/EditingContext.h/.cpp EditingContextResolver singleton + context registry
|
||||||
src/Gui/BreadcrumbToolBar.h/.cpp Color-coded breadcrumb toolbar (Catppuccin Mocha)
|
src/Gui/BreadcrumbToolBar.h/.cpp Color-coded breadcrumb toolbar (Catppuccin Mocha)
|
||||||
@@ -49,22 +123,6 @@ src/Gui/CommandOrigin.cpp Origin_Commit/Pull/Push/Info/BOM commands
|
|||||||
src/Gui/OriginManager.h/.cpp Origin lifecycle management
|
src/Gui/OriginManager.h/.cpp Origin lifecycle management
|
||||||
src/Gui/OriginSelectorWidget.h/.cpp UI for origin selection
|
src/Gui/OriginSelectorWidget.h/.cpp UI for origin selection
|
||||||
|
|
||||||
mods/ztools/ [submodule] command provider (not a workbench)
|
|
||||||
├── ztools/InitGui.py Deferred command registration + _ZToolsManipulator
|
|
||||||
├── ztools/ztools/
|
|
||||||
│ ├── commands/ Datum, pattern, pocket, assembly, spreadsheet
|
|
||||||
│ ├── datums/core.py Datum creation via Part::AttachExtension
|
|
||||||
│ └── resources/ Icons, theme utilities
|
|
||||||
└── CatppuccinMocha/ Theme preference pack (QSS)
|
|
||||||
|
|
||||||
mods/silo/ [submodule -> silo-mod.git] FreeCAD workbench
|
|
||||||
├── silo-client/ [submodule -> silo-client.git] shared API client
|
|
||||||
│ └── silo_client/ SiloClient, SiloSettings, CATEGORY_NAMES
|
|
||||||
└── freecad/ FreeCAD workbench (Python)
|
|
||||||
├── InitGui.py SiloWorkbench + Silo overlay context registration
|
|
||||||
├── silo_commands.py Commands + FreeCADSiloSettings adapter
|
|
||||||
└── silo_origin.py FileOrigin backend for Silo
|
|
||||||
|
|
||||||
src/Gui/Stylesheets/ QSS themes and SVG assets
|
src/Gui/Stylesheets/ QSS themes and SVG assets
|
||||||
src/Gui/PreferencePacks/ KindredCreate preference pack (cfg + build-time QSS)
|
src/Gui/PreferencePacks/ KindredCreate preference pack (cfg + build-time QSS)
|
||||||
```
|
```
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user