Files
fn_registry/dev/issues/completed/0045-cpp-extract-pure-logic.md
T

4.8 KiB

id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
id title status type domain scope priority depends blocks related created updated tags
0045 Extraer logica pura de componentes C++ impuros (sql_workbench, process_runner, file_watcher) completado refactor
cpp-stack
registry-quality
registry-only media
2026-05-17 2026-05-17

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

./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