Build instructions
This commit is contained in:
503
codex/STEPS.md
Normal file
503
codex/STEPS.md
Normal file
@@ -0,0 +1,503 @@
|
||||
# dpg-gauges Build Steps
|
||||
|
||||
There is no Step 0. Initial setup is listed separately, then implementation starts at Step 1.
|
||||
|
||||
## Workflow rules
|
||||
|
||||
1. Use `uv` for all Python package and dependency management.
|
||||
2. Always read `codex/FEATURES.md`, `codex/ARCHITECTURE.md`, and `codex/AGENTS.md` before making code changes.
|
||||
3. Keep `codex/AGENTS.md` as a rolling log of what has been done, what is broken, and what comes next.
|
||||
4. Update `README.md` and `docs/` whenever public behaviour or examples change.
|
||||
5. After every step, update `codex/AGENTS.md`, run relevant checks, and commit if working in git.
|
||||
6. Do not casually change public API once introduced.
|
||||
7. Dear PyGui calls must happen on the GUI thread only.
|
||||
8. Runtime gauge updates are GUI-thread-only unless explicitly documented otherwise.
|
||||
9. Prefer stable, boring implementation over clever drawing tricks.
|
||||
10. Keep each step shippable and tested before moving to the next.
|
||||
|
||||
## Initial setup instructions
|
||||
|
||||
Run these before Step 1 when starting from a clean repository:
|
||||
|
||||
```bash
|
||||
mkdir dpg-gauges
|
||||
cd dpg-gauges
|
||||
git init
|
||||
uv init --package dpg-gauges
|
||||
uv add dearpygui
|
||||
uv add --dev pytest ruff pyright
|
||||
```
|
||||
|
||||
Create this structure:
|
||||
|
||||
```text
|
||||
src/dpg_gauges/
|
||||
__init__.py
|
||||
api.py
|
||||
widget.py
|
||||
state.py
|
||||
renderer.py
|
||||
draw_layers.py
|
||||
sizing.py
|
||||
animation.py
|
||||
smoothing.py
|
||||
scales.py
|
||||
themes.py
|
||||
gauges.py
|
||||
diagnostics.py
|
||||
types.py
|
||||
exceptions.py
|
||||
examples/
|
||||
tests/
|
||||
docs/
|
||||
codex/FEATURES.md
|
||||
codex/ARCHITECTURE.md
|
||||
codex/STEPS.md
|
||||
codex/AGENTS.md
|
||||
README.md
|
||||
```
|
||||
|
||||
Recommended `pyproject.toml` additions:
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
line-length = 100
|
||||
target-version = "py311"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["E", "F", "I", "UP", "B", "SIM"]
|
||||
|
||||
[tool.pyright]
|
||||
typeCheckingMode = "basic"
|
||||
```
|
||||
|
||||
Initial checks:
|
||||
|
||||
```bash
|
||||
uv run python -c "import dpg_gauges; print(dpg_gauges.__name__)"
|
||||
uv run ruff check .
|
||||
uv run ruff format .
|
||||
```
|
||||
|
||||
## Step 1 - Public API contract and pure core
|
||||
|
||||
Goal: lock the public API surface and implement pure non-DPG components first.
|
||||
|
||||
Tasks:
|
||||
|
||||
1. Define public exports in `__init__.py`.
|
||||
|
||||
Required API names:
|
||||
|
||||
```python
|
||||
configure
|
||||
|
||||
GaugeTheme
|
||||
GaugeStyle
|
||||
AnimationConfig
|
||||
SmoothingConfig
|
||||
ThresholdBand
|
||||
GaugeMarker
|
||||
StatusState
|
||||
GaugeStats
|
||||
|
||||
analog_gauge
|
||||
digital_gauge
|
||||
bar_gauge
|
||||
level_gauge
|
||||
status_light
|
||||
segmented_gauge
|
||||
compass_gauge
|
||||
thermometer_gauge
|
||||
battery_gauge
|
||||
multi_value_gauge
|
||||
|
||||
gauge_panel
|
||||
gauge_grid
|
||||
|
||||
set_value
|
||||
get_value
|
||||
update_gauge
|
||||
configure_gauge
|
||||
set_thresholds
|
||||
set_markers
|
||||
set_show
|
||||
delete_gauge
|
||||
|
||||
get_gauge_debug_state
|
||||
```
|
||||
|
||||
2. Add exceptions in `exceptions.py`.
|
||||
3. Add shared dataclasses and types in `types.py`.
|
||||
4. Implement configuration normalization dataclasses in `gauges.py`.
|
||||
5. Implement pure scale helpers in `scales.py`.
|
||||
6. Implement lightweight theme/style presets in `themes.py`.
|
||||
7. Stub GUI-dependent public functions so imports succeed.
|
||||
8. Add tests for imports, dataclass construction, clamp/normalize math, tick generation, threshold validation, and formatting.
|
||||
|
||||
Checks:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
uv run ruff check .
|
||||
uv run ruff format --check .
|
||||
uv run pyright
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- public API imports cleanly
|
||||
- pure gauge config can be created and validated
|
||||
- value clamping and formatting are tested
|
||||
- no Dear PyGui context is required for Step 1 tests
|
||||
- API names are fixed before renderer work begins
|
||||
|
||||
Commit:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "step 1: lock public api and pure core"
|
||||
```
|
||||
|
||||
## Step 2 - State, sizing, animation, and smoothing model
|
||||
|
||||
Goal: build the logical model before rendering final visuals.
|
||||
|
||||
Tasks:
|
||||
|
||||
1. Implement `DpgGaugesConfig` and `configure(...)`.
|
||||
2. Implement `GaugeState` and global gauge registry.
|
||||
3. Implement `DirtyFlags`.
|
||||
4. Implement sizing helpers:
|
||||
- requested size vs measured size
|
||||
- last non-zero size preservation
|
||||
- square gauge rect
|
||||
- stretch gauge rect
|
||||
5. Implement animation interpolation in `animation.py`.
|
||||
6. Implement smoothing helpers in `smoothing.py`.
|
||||
7. Implement runtime state functions for `set_value`, `get_value`, `update_gauge`, `set_thresholds`, `set_markers`, `set_show`, and `delete_gauge` without final drawing complexity.
|
||||
8. Add tests for registry behaviour, value/clamped/displayed separation, dirty flags, sizing transitions, animation interpolation, smoothing progression, and invalid values.
|
||||
|
||||
Checks:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
uv run ruff check .
|
||||
uv run ruff format --check .
|
||||
uv run pyright
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- values clamp to min/max
|
||||
- non-finite values do not crash pure state helpers
|
||||
- dirty flags distinguish value, static, dynamic, text, size, and style changes
|
||||
- smoothing and animation are optional and testable without Dear PyGui
|
||||
- hidden/zero-size state does not erase last non-zero size
|
||||
|
||||
Commit:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "step 2: add gauge state sizing and animation model"
|
||||
```
|
||||
|
||||
## Step 3 - Widget shell and renderer foundation
|
||||
|
||||
Goal: create stable Dear PyGui gauge shells and a renderer that can draw placeholders without flicker.
|
||||
|
||||
Tasks:
|
||||
|
||||
1. Implement gauge creation context managers in `widget.py`.
|
||||
2. Create internal group/child/drawlist structures for gauge widgets.
|
||||
3. Register each gauge before yielding from the context manager.
|
||||
4. Implement `GaugeRenderer` foundation:
|
||||
- measure size
|
||||
- schedule frame callbacks where animation is active
|
||||
- draw placeholder background/frame/value text
|
||||
- expose debug state
|
||||
5. Implement `draw_layers.py` bookkeeping.
|
||||
6. Implement `gauge_panel` and `gauge_grid` as lightweight layout helpers.
|
||||
7. Add examples:
|
||||
- `examples/basic_digital.py`
|
||||
- `examples/basic_analog.py`
|
||||
- `examples/sizing.py`
|
||||
- `examples/dashboard.py`
|
||||
8. Add Dear PyGui context smoke tests where feasible.
|
||||
|
||||
Manual checks:
|
||||
|
||||
```bash
|
||||
uv run python examples/basic_digital.py
|
||||
uv run python examples/basic_analog.py
|
||||
uv run python examples/sizing.py
|
||||
uv run python examples/dashboard.py
|
||||
```
|
||||
|
||||
Automated checks:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
uv run ruff check .
|
||||
uv run ruff format --check .
|
||||
uv run pyright
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- gauge shells appear inside Dear PyGui windows
|
||||
- widgets respect basic width/height options
|
||||
- hidden/show-later layout does not permanently collapse sizes
|
||||
- debug state reports useful state
|
||||
- no flicker through empty drawlists on simple value changes
|
||||
|
||||
Commit:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "step 3: add widget shell and renderer foundation"
|
||||
```
|
||||
|
||||
## Step 4 - Digital, bar, level, and status gauges
|
||||
|
||||
Goal: implement the simplest high-value gauges first.
|
||||
|
||||
Tasks:
|
||||
|
||||
1. Implement `digital_gauge` rendering.
|
||||
2. Implement `bar_gauge` rendering with horizontal/vertical orientation.
|
||||
3. Implement `level_gauge` rendering.
|
||||
4. Implement `status_light` rendering.
|
||||
5. Implement threshold and marker drawing for bar/level where applicable.
|
||||
6. Implement optional tooltips and callbacks.
|
||||
7. Add examples:
|
||||
- `examples/basic_digital.py`
|
||||
- `examples/basic_bar.py`
|
||||
- `examples/basic_level.py`
|
||||
- `examples/basic_status.py`
|
||||
- `examples/thresholds_markers.py`
|
||||
8. Add tests for pure geometry and runtime update state.
|
||||
|
||||
Manual checks:
|
||||
|
||||
```bash
|
||||
uv run python examples/basic_digital.py
|
||||
uv run python examples/basic_bar.py
|
||||
uv run python examples/basic_level.py
|
||||
uv run python examples/basic_status.py
|
||||
uv run python examples/thresholds_markers.py
|
||||
```
|
||||
|
||||
Automated checks:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
uv run ruff check .
|
||||
uv run ruff format --check .
|
||||
uv run pyright
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- digital values format correctly
|
||||
- bar/level fill fraction is correct and clamped
|
||||
- status states display configured colors/text
|
||||
- thresholds and markers render visually without events
|
||||
- stretchable gauges behave in resizable layouts
|
||||
|
||||
Commit:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "step 4: add digital bar level and status gauges"
|
||||
```
|
||||
|
||||
## Step 5 - Analog, segmented, compass, thermometer, battery, and multi-value gauges
|
||||
|
||||
Goal: complete the first-release gauge catalogue.
|
||||
|
||||
Tasks:
|
||||
|
||||
1. Implement `analog_gauge`:
|
||||
- arcs
|
||||
- ticks
|
||||
- tick labels
|
||||
- needle
|
||||
- redline
|
||||
- markers
|
||||
2. Implement `segmented_gauge`.
|
||||
3. Implement `compass_gauge`.
|
||||
4. Implement `thermometer_gauge`.
|
||||
5. Implement `battery_gauge`.
|
||||
6. Implement `multi_value_gauge`.
|
||||
7. Ensure square gauges maintain aspect ratio by default.
|
||||
8. Add examples:
|
||||
- `examples/basic_segmented.py`
|
||||
- `examples/basic_compass.py`
|
||||
- `examples/basic_thermometer.py`
|
||||
- `examples/basic_battery.py`
|
||||
- `examples/basic_multi_value.py`
|
||||
9. Add tests for value-to-angle math, tick generation, compass wraparound, segment activation, battery clamp, and multi-value config validation.
|
||||
|
||||
Manual checks:
|
||||
|
||||
```bash
|
||||
uv run python examples/basic_analog.py
|
||||
uv run python examples/basic_segmented.py
|
||||
uv run python examples/basic_compass.py
|
||||
uv run python examples/basic_thermometer.py
|
||||
uv run python examples/basic_battery.py
|
||||
uv run python examples/basic_multi_value.py
|
||||
```
|
||||
|
||||
Automated checks:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
uv run ruff check .
|
||||
uv run ruff format --check .
|
||||
uv run pyright
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- all MVP gauge types render
|
||||
- analog redline and markers render correctly
|
||||
- compass wraps heading values sensibly
|
||||
- segmented gauges support dense shift-light style displays
|
||||
- square gauges do not distort in common layouts
|
||||
|
||||
Commit:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "step 5: complete first gauge catalogue"
|
||||
```
|
||||
|
||||
## Step 6 - High-rate updates, animation, and stress examples
|
||||
|
||||
Goal: prove gauges remain readable and stable under fast telemetry.
|
||||
|
||||
Tasks:
|
||||
|
||||
1. Integrate animation into renderer scheduling.
|
||||
2. Integrate optional smoothing into value rendering.
|
||||
3. Ensure repeated GUI-thread `set_value` calls coalesce naturally to the newest target.
|
||||
4. Add examples:
|
||||
- `examples/animations.py`
|
||||
- `examples/live_high_rate.py`
|
||||
- `examples/live_worst_case.py`
|
||||
5. High-rate examples should use a producer thread for data generation and GUI-thread frame callbacks for Dear PyGui updates.
|
||||
6. Add debug fields for animation/smoothing state.
|
||||
7. Add tests for animation convergence, smoothing reset behaviour, and latest-target wins.
|
||||
|
||||
Manual stress checks:
|
||||
|
||||
```bash
|
||||
uv run python examples/animations.py
|
||||
uv run python examples/live_high_rate.py
|
||||
uv run python examples/live_worst_case.py
|
||||
```
|
||||
|
||||
While examples run:
|
||||
|
||||
- drive updates above 60 Hz where possible
|
||||
- verify gauges do not flicker
|
||||
- verify values remain human-readable with smoothing enabled
|
||||
- verify animation can be disabled for immediate response
|
||||
- verify UI remains responsive
|
||||
|
||||
Automated checks:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
uv run ruff check .
|
||||
uv run ruff format --check .
|
||||
uv run pyright
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- high-rate examples remain stable
|
||||
- smoothing and animation are configurable per gauge
|
||||
- no unbounded update queue exists
|
||||
- renderer only schedules continuous frames while needed
|
||||
|
||||
Commit:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "step 6: add animation and high rate update stress tests"
|
||||
```
|
||||
|
||||
## Step 7 - Documentation, hardening, and beta release
|
||||
|
||||
Goal: make the package usable as a dependency in DataFlux and public projects.
|
||||
|
||||
Tasks:
|
||||
|
||||
1. Write `README.md` with:
|
||||
- install
|
||||
- minimal analog/digital examples
|
||||
- dashboard example
|
||||
- GUI-thread update contract
|
||||
- animation/smoothing explanation
|
||||
- threshold/marker examples
|
||||
2. Write docs:
|
||||
- `docs/GETTING_STARTED.md`
|
||||
- `docs/EXAMPLES.md`
|
||||
- `docs/API_REFERENCE.md`
|
||||
3. Add docstrings for all public functions.
|
||||
4. Review public API exports.
|
||||
5. Add hardening tests for:
|
||||
- unknown gauge
|
||||
- duplicate tag
|
||||
- invalid range
|
||||
- invalid threshold
|
||||
- invalid marker
|
||||
- non-finite value
|
||||
- deleted gauge updates
|
||||
- hidden layout sizing
|
||||
- animation disabled/enabled
|
||||
6. Run all examples manually.
|
||||
7. Test local editable install from another project:
|
||||
|
||||
```bash
|
||||
uv add --editable ../dpg-gauges
|
||||
uv run python -c "import dpg_gauges as dpgg; print(dpgg.__name__)"
|
||||
```
|
||||
|
||||
8. Bump version.
|
||||
|
||||
Suggested initial beta:
|
||||
|
||||
```text
|
||||
0.1.0b1
|
||||
```
|
||||
|
||||
Final checks:
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
uv run pytest
|
||||
uv run ruff check .
|
||||
uv run ruff format --check .
|
||||
uv run pyright
|
||||
```
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- all examples run
|
||||
- local editable dependency works
|
||||
- docs cover all public gauge types
|
||||
- high-rate examples are stable
|
||||
- README clearly documents Dear PyGui GUI-thread expectations
|
||||
- `codex/AGENTS.md` accurately describes status
|
||||
|
||||
Commit:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "step 7: harden docs and prepare beta"
|
||||
git tag v0.1.0b1
|
||||
```
|
||||
Reference in New Issue
Block a user