Files
fn_registry/dev/issues/completed/0109b-skill-tree-rings.md
T
egutierrez b9716a7cd6 chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1
del flow 0008 (kanban_cpp + agent_runner_api + DoD schema).

Incluye:
- dev/flows/0008-kanban-cpp-and-agent-workflows.md
- dev/issues/0112-0119*.md (7 sub-issues)
- WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:17:08 +02:00

70 lines
3.3 KiB
Markdown

---
id: "0109b"
title: "skill_tree layout anillos + render canvas ImDrawList con cards"
status: completado
type: feature
domain:
- meta
- cpp-stack
scope: app-scoped
priority: media
depends:
- "0109a"
blocks:
- "0109c"
related:
- "0109"
created: 2026-05-17
updated: 2026-05-17
tags:
- skill-tree
- cpp
- imgui
- layout
- canvas
---
# 0109b — skill_tree layout anillos + render canvas
Segundo slice del epic 0109. Reemplaza la lista textual del Tree por un canvas interactivo basado en `ImDrawList`. Pivote desde `graph_renderer_cpp_viz` (GPU) → `ImDrawList` (CPU) para mantener simplicidad: 166 nodos no justifican el pipeline GPU.
## Decisiones tomadas durante la implementacion
- **Stack: `ImGui::ImDrawList`**, NO `graph_renderer_cpp_viz`. Razon: 166 nodos cabian de sobra en CPU; `graph_renderer` exige `init_gl_loader=true`, build de `GraphData` con tipos OSINT, shaders, FBO + texture flip-Y. Diferencia ~120 LOC + un monton de rebuilds para cero beneficio observable.
- **Sin fisicas** (el usuario lo pidio explicito). Layout deterministico via `compute_ring_layout_cpp_core`.
- **5 rings**: done (0), in-progress (1), unlocked (2), locked (3), deferred/bloqueado (4).
- **18 sectores radiales** = 18 dominios canonicos (`dev/TAXONOMY.md`). Labels en el aro exterior.
- **Lock derivation**: `pendiente` se subdivide en `pendiente_unlocked` (todos los `depends[]` en done) vs `pendiente_locked` (algun depends sin completar). Set de `done` IDs se computa al cargar y se cruza con cada `depends[]`.
- **Animacion lerp 1s** entre prev y current position cuando un nodo cambia de `status_eff` entre dos `reload_scan()`s. Ease-in-out cuadratica.
- **Cards con texto**: cada nodo muestra su ID en blanco con sombra negra para legibilidad sobre cualquier color de ring.
- **Diferencial visual flows vs issues**: issues = circulos, flows = rombos.
- **Pan**: drag con boton derecho o medio.
- **Zoom**: rueda del raton, centrado en cursor (re-anchora coordenadas mundo bajo el puntero).
- **Picking**: O(N) radius check (166 nodos = trivial; spatial hash innecesario).
## Tareas
1. Crear funcion del registry `compute_ring_layout_cpp_core` (pure, 10 tests Catch2, FNV-1a determinista para sub-jitter angular).
2. Reescribir `main.cpp::draw_tree()` como canvas con `ImGui::InvisibleButton` + `ImDrawList`.
3. Implementar `derive_status_eff()` para lock/unlock.
4. Implementar `apply_layout()` con preservacion de prev_x/prev_y para animacion.
5. Render: aristas curvas Bezier (depends + related) + nodos con outline + label ID + tooltip on hover.
6. HUD strip con LV/XP/contadores.
7. Self-test 0-exit cuando `parse_errors == 0 && unmapped == 0`.
8. Build Linux + deploy Windows.
## DoD
- [x] `compute_ring_layout_cpp_core` indexada (10/10 tests, 142 assertions).
- [x] `apps/skill_tree/main.cpp` usa `parse_md_frontmatter_cpp_core` + `compute_ring_layout_cpp_core`.
- [x] `app.md uses_functions` actualizado con ambas.
- [x] Self-test imprime breakdown por ring: `done=77 in-progress=2 unlocked=64 locked=22 deferred=1 unmapped=0`.
- [x] Linux build OK.
- [x] Windows deploy OK (PID corriendo).
- [x] Tarjeta visible en `app_hub_launcher`.
- [x] `fn doctor cpp-apps` limpio.
## Sigue
0109c: Inspector evolucionado con DoD parseado de la seccion `## DoD` del .md (checkboxes interactivos read-only) + lista de `uses_functions` del registry para esa issue.