672a6a44b7
Document the single-crate app architecture, WGPU integration path, module boundaries, and next steps. Also clean up the terrain_gen test assertion so clippy stays green.
125 lines
5.9 KiB
Markdown
125 lines
5.9 KiB
Markdown
# WGPU/egui Interactive App Architecture Spike
|
|
|
|
> Goal: introduce an interactive OpenVistaPro app without destabilizing the existing CLI, importer pipeline, or deterministic CPU reference renderer.
|
|
|
|
## Decision
|
|
|
|
Keep the repository as a single Rust crate for now.
|
|
|
|
The current boundary set is still moving, but it is already useful:
|
|
|
|
- `src/terrain.rs`, `src/terrain_gen.rs`, `src/import.rs`, `src/scene.rs`, `src/scene_file.rs`, `src/script.rs`, `src/script_exec.rs`, `src/path.rs`, `src/render.rs`, and `src/colormap.rs` are the clean-room core.
|
|
- `src/cli.rs` and `src/main.rs` are the command-line adapter.
|
|
- `src/app_state.rs`, `src/ui_shell.rs`, `src/app.rs`, and `src/bin/openvistapro_app.rs` are the optional interactive shell.
|
|
|
|
A workspace split into `openvistapro-core`, `openvistapro-cli`, and `openvistapro-app` would add maintenance overhead before there is a second renderer/backend boundary that truly justifies it. The better near-term move is to keep a monolith and enforce boundaries with modules, feature flags, and tests.
|
|
|
|
Revisit a workspace split only when at least one of these becomes true:
|
|
|
|
1. the GPU renderer needs materially different dependencies from the CLI/reference renderer,
|
|
2. the core API stabilizes enough that the app shell can depend on it as a published internal crate boundary, or
|
|
3. build times / dependency fanout make the single-crate layout painful.
|
|
|
|
## Integration recommendation
|
|
|
|
Use egui as the interactive shell now, and treat WGPU as the rendering backend that arrives later behind a narrow viewport abstraction.
|
|
|
|
Recommended path:
|
|
|
|
1. Keep `eframe` for the windowing / egui host while the shell is still mostly controls and state.
|
|
2. Keep the current CPU renderer as the canonical reference output for tests and CLI smoke runs.
|
|
3. Introduce a tiny viewport trait or adapter boundary before any full GPU renderer lands.
|
|
4. Add a WGPU-backed viewport only once the render pipeline actually needs GPU surfaces, textures, and custom passes.
|
|
|
|
Why this order:
|
|
|
|
- `eframe` already gives a working egui host with the least glue.
|
|
- CLI builds stay GPU-free because the app stays behind the `app` feature.
|
|
- The CPU renderer remains the reference implementation for determinism and testability.
|
|
- WGPU can then become an implementation detail of the viewport, not a rewrite of the app state model.
|
|
|
|
## Module boundaries
|
|
|
|
Keep the following responsibilities separate:
|
|
|
|
### Core domain
|
|
|
|
- `terrain.rs`: immutable height grid and sampling rules.
|
|
- `terrain_gen.rs`: deterministic procedural generation inputs and output grid creation.
|
|
- `import.rs`: import boundary and source metadata.
|
|
- `scene.rs`: camera, lighting, hydrology, and palette-linked scene state.
|
|
- `scene_file.rs`: `.ovp.toml` persistence.
|
|
- `script.rs` / `script_exec.rs`: project-owned script language and executor.
|
|
- `path.rs`: MakePath-style camera path generation.
|
|
- `render.rs`: deterministic CPU render outputs.
|
|
- `colormap.rs`: palette / band mapping.
|
|
|
|
### CLI adapter
|
|
|
|
- `cli.rs` should stay focused on argument parsing and orchestration.
|
|
- Keep it thin enough that the same core operations can be called from future automation or from the app shell.
|
|
|
|
### Interactive shell state
|
|
|
|
- `app_state.rs` should remain pure state plus reducers / actions.
|
|
- `ui_shell.rs` should own section ordering, labels, and placeholder metadata.
|
|
- Avoid leaking egui types into either file.
|
|
|
|
### egui view/controller
|
|
|
|
- `app.rs` should remain the presentation layer that turns `AppData` into panels, menus, and a preview texture.
|
|
- The shell should consume state snapshots and call backend actions, not embed render or import logic inline.
|
|
|
|
### Future GPU viewport
|
|
|
|
- Introduce a narrow backend boundary for viewport rendering before the first custom WGPU renderer lands.
|
|
- Keep surface creation, texture upload, and draw passes out of `AppData`.
|
|
- Prefer a dedicated GPU adapter module over scattering WGPU setup across the UI code.
|
|
|
|
## Minimal first app shell
|
|
|
|
The smallest durable shell is:
|
|
|
|
- a stable top command bar,
|
|
- a left or right dock for section-specific controls,
|
|
- a central viewport that can show the CPU preview now and a GPU surface later,
|
|
- a status bar for file paths, script status, and render feedback,
|
|
- a tiny about/help dialog for orientation.
|
|
|
|
That is already enough to validate layout, interaction, and state management without pretending the GPU renderer exists yet.
|
|
|
|
## Testing strategy
|
|
|
|
Keep the test surface split the same way as the code.
|
|
|
|
### Unit tests
|
|
|
|
- `AppData` reducers and state transitions.
|
|
- `UiShellState` navigation order and section metadata.
|
|
- render-mode selection and preview-state plumbing.
|
|
- scene / script / path / importer behavior.
|
|
|
|
### Smoke commands
|
|
|
|
Use existing CLI and app entry points as smoke tests for the architecture:
|
|
|
|
- `cargo run -- info`
|
|
- `cargo run -- render --preset fractal --seed 1337 --width 64 --height 64 --output /tmp/openvistapro-fractal.png`
|
|
- `cargo run --features app --bin openvistapro_app` when a display is available
|
|
|
|
### Later integration tests
|
|
|
|
Once the GPU viewport exists, add lightweight screenshot or frame-smoke coverage around the viewport adapter rather than baking WGPU assumptions into the core state model.
|
|
|
|
## Next tasks
|
|
|
|
1. Add a small viewport abstraction so the egui shell can switch between CPU preview and a future GPU backend without changing `AppData`.
|
|
2. Keep the CPU renderer as the reference implementation for deterministic validation.
|
|
3. Add a dedicated GPU adapter module only when the WGPU surface truly exists.
|
|
4. Revisit a workspace split after the GPU path forces a second hard boundary.
|
|
5. Keep `docs/knowledgebase/architecture-notes.md` and `docs/knowledgebase/ui-panel-map.md` aligned with any later shell or viewport changes.
|
|
|
|
## Recommendation summary
|
|
|
|
Stay monolithic now, keep egui as the host shell, and treat WGPU as a future viewport backend rather than the reason to split the crate today. That gives OpenVistaPro the fastest path to a usable interactive app while protecting the CLI and deterministic renderer from churn.
|