99 lines
4.5 KiB
Markdown
99 lines
4.5 KiB
Markdown
# 0045 — Extraer logica pura de componentes C++ impuros (sql_workbench, process_runner, file_watcher)
|
|
|
|
## Metadata
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **ID** | 0045 |
|
|
| **Estado** | pendiente |
|
|
| **Prioridad** | media |
|
|
| **Tipo** | refactor — `cpp/functions/core` |
|
|
|
|
## Dependencias
|
|
|
|
Ninguna.
|
|
|
|
---
|
|
|
|
## Objetivo
|
|
|
|
Extraer la parte pura (parsing, state machines, diff) de componentes hoy mezclados con I/O y UI. Resultado: cada uno se descompone en `<x>_pure_cpp_core` (testeable, sin ImGui ni I/O) + `<x>_ui_cpp_core` (thin wrapper impuro). Tambien aplica al compiler de `shaders_lab` que vive en su `main.cpp`.
|
|
|
|
## Contexto
|
|
|
|
- `sql_workbench_cpp_core` mezcla parsing SQL, ejecucion SQLite y render ImGui en una sola funcion.
|
|
- `process_runner_cpp_core` mezcla state machine de proceso (idle/running/success/error) con UI helpers.
|
|
- `file_watcher_cpp_core` mezcla polling de filesystem con notificaciones UI.
|
|
- `shaders_lab/main.cpp` tiene `compile_code()`, `compile_dag()`, `mark_code_dirty()` inline.
|
|
|
|
Sin separacion no hay tests unitarios, no es reutilizable y crece la deuda con cada feature.
|
|
|
|
## Arquitectura
|
|
|
|
```
|
|
cpp/functions/core/
|
|
├── sql_parse.{h,cpp,md} # NEW — pure
|
|
├── sql_workbench.{h,cpp,md} # MOD — thin wrapper, llama sql_parse
|
|
├── process_state_machine.{h,cpp,md} # NEW — pure (transiciones)
|
|
├── process_runner.{h,cpp,md} # MOD — usa process_state_machine
|
|
├── file_poll_diff.{h,cpp,md} # NEW — pure (calcula diff de snapshots)
|
|
└── file_watcher.{h,cpp,md} # MOD — usa file_poll_diff
|
|
|
|
cpp/apps/shaders_lab/
|
|
├── compiler.h # NEW
|
|
├── compiler.cpp # NEW (extrae compile_code/compile_dag)
|
|
└── main.cpp # MOD (461 → ~250 lineas)
|
|
```
|
|
|
|
## Tareas
|
|
|
|
### Fase 1 — sql_workbench
|
|
|
|
1.1 `sql_parse_cpp_core` (pure): tokeniza SQL minimal (separa statements por `;`, detecta keyword inicial: SELECT/INSERT/UPDATE/DELETE/CREATE/etc., devuelve struct `SqlStatement{kind, text, line}`).
|
|
1.2 `sql_workbench` pasa a llamar `sql_parse` para detectar tipo de statement antes de ejecutar; el parser puro es testeable sin SQLite.
|
|
1.3 Test unitario: dado SQL multi-statement, devuelve N statements con kind correcto.
|
|
|
|
### Fase 2 — process_runner
|
|
|
|
2.1 `process_state_machine_cpp_core` (pure): funcion `process_transition(current_state, event) -> new_state` con eventos `{Trigger, Spawned, Finished, Failed, Timeout}` y estados `{Idle, Running, Success, Error}`.
|
|
2.2 `process_runner` pasa a usar la maquina pura para gestionar transiciones; la parte impura solo dispara `popen`/`spawn`/`wait` y traduce a eventos.
|
|
2.3 Test unitario: secuencia de eventos → estado final esperado.
|
|
|
|
### Fase 3 — file_watcher
|
|
|
|
3.1 `file_poll_diff_cpp_core` (pure): dado dos snapshots `vector<FileEntry{path, size, mtime}>`, devuelve `FileDiff{added, modified, removed}`.
|
|
3.2 `file_watcher` pasa a hacer el polling impuro y delegar el diff al puro.
|
|
3.3 Test unitario: dado A=[a,b,c], B=[a,b',d] → modified=[b], added=[d], removed=[c].
|
|
|
|
### Fase 4 — shaders_lab compiler
|
|
|
|
4.1 Crear `cpp/apps/shaders_lab/compiler.{h,cpp}` con `compile_code(code, &out_log) -> bool`, `compile_dag(...)`, `mark_code_dirty(...)`. Estas funciones llaman al backend GLSL existente — no son del registry porque dependen de estado interno de shaders_lab.
|
|
4.2 Mover el codigo correspondiente desde `main.cpp`.
|
|
4.3 `main.cpp` queda <250 lineas.
|
|
|
|
### Fase 5 — Indexar y validar
|
|
|
|
5.1 `./fn index` para registrar las 3 nuevas funciones puras.
|
|
5.2 Verificar `purity: pure`, `returns_optional: false`, `error_type: ""` en cada una.
|
|
5.3 Build Linux + Windows. Tests pasan.
|
|
|
|
## Decisiones
|
|
|
|
- `sql_parse` es deliberadamente minimal — no es un parser SQL completo, solo distingue tipos de statement. Si en el futuro hace falta mas, se anade.
|
|
- `compile_code/compile_dag` quedan como utilities de la app, NO en el registry (dependen de tipos internos de shaders_lab).
|
|
|
|
## Riesgos
|
|
|
|
- Tests unitarios C++: no hay framework configurado todavia (issue 0047 lo monta). Mientras tanto, anadir tests dentro del archivo via `#ifdef TESTING` + un main pequeno, o esperar a 0047.
|
|
- Decision: usar `#ifdef TESTING` por ahora; cuando 0047 monte Catch2, migrar.
|
|
|
|
## Validacion
|
|
|
|
```bash
|
|
./fn run sql_parse_cpp_core # ejecuta el test si lo hay
|
|
./fn show sql_parse_cpp_core
|
|
./fn show process_state_machine_cpp_core
|
|
./fn show file_poll_diff_cpp_core
|
|
cmake --build cpp/build --target shaders_lab
|
|
```
|