Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 57 additions & 48 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,27 @@ QTorres/
│ ├── labview-comportamiento.md # Arquitectura LabVIEW: renderizado, modos, estilos
│ └── GTK_ISSUES.md # Bugs del backend GTK en Linux
├── src/
│ ├── qtorres.red # Punto de entrada + toolbar + ventana principal (226 líneas)
│ ├── qtorres.red # Punto de entrada + toolbar + ventana principal
│ ├── graph/
│ │ ├── model.red # Modelo: make-label, base-element, make-node, make-wire, make-frame, gen-name (346 líneas)
│ │ └── blocks.red # Registro de bloques + dialecto block-def — 34 bloques (324 líneas)
│ │ ├── model.red # Modelo: make-label, make-node, make-wire, make-fp-item, set-config, find-node-by-id (635 líneas)
│ │ └── blocks.red # Registro de bloques + dialecto block-def — 40 bloques
│ ├── compiler/
│ │ └── compiler.red # Compilador: topo-sort, bind-emit, compile-body/diagram/structures (831 líneas)
│ │ └── compiler.red # Compilador: topo-sort, bind-emit, compile-body/diagram/panel (1165 líneas)
│ ├── runner/
│ │ └── runner.red # Runner: ejecución en memoria con do (33 líneas)
│ │ └── runner.red # Runner: ejecución en memoria con do
│ ├── io/
│ │ └── file-io.red # File I/O: serialize, format, save/load .qvi (647 líneas)
│ │ └── file-io.red # File I/O: serialize, format, save/load .qvi, save/load-panel (738 líneas)
│ └── ui/
│ ├── diagram/
│ │ └── canvas.red # Block Diagram canvas: render, hit-test, eventos (2383 líneas) ⚠️ SPLIT PENDIENTE
│ │ ├── canvas.red # BD canvas: hit-test, CRUD, actor render-diagram (1233 líneas)
│ │ ├── canvas-render.red # Render puro BD: constantes, geometría, Draw (934 líneas)
│ │ └── canvas-dialogs.red # Diálogos edición, paleta, SR helpers (413 líneas)
│ └── panel/
│ └── panel.red # Front Panel: render, hit-test, compile-panel (928 líneas)
│ ├── panel.red # FP: hit-test, diálogos, paleta, actor render-panel (570 líneas)
│ └── panel-render.red # Render puro FP: constantes, Draw, waveform (411 líneas)
├── tests/
│ ├── run-all.red # Runner de tests automatizados
│ ├── test-blocks.red # Tests del registro de bloques (34 bloques, puertos, emit)
│ ├── test-blocks.red # Tests del registro de bloques (40 bloques, puertos, emit)
│ ├── test-topo.red # Tests de topological sort (lineal, diamante, vacío, ciclos)
│ ├── test-model.red # Tests del modelo (make-node, make-wire, make-frame, make-structure)
│ └── test-compiler.red # Tests del compilador (bind-emit, compile-body, round-trip, estructuras)
Expand All @@ -98,20 +101,26 @@ QTorres/

**Fase 1 ✅ COMPLETADA.** Pipeline end-to-end funcional:
- Modelo de datos con composición (DT-022/023/024)
- 34 bloques registrados (math, I/O, boolean, compare, string, array, estructuras)
- 40 bloques registrados (math, I/O, boolean, compare, string, array, cluster, estructuras, waveform)
- Compilador con topo-sort (Kahn) y generación Red/View
- Runner en memoria, File I/O con round-trip, Front Panel con Draw
- Tests automatizados + CI en GitHub Actions

**Fase 2 — EN PROGRESO.** Tipos de datos y estructuras de control:
**Fase 2 ✅ COMPLETADA (pendiente merge PR#60).** Tipos de datos y estructuras de control:
- ~~#9 Tipo booleano~~ ✅
- ~~#10 Tipo string~~ ✅
- ~~#14 While Loop~~ ✅ (con shift registers)
- ~~#15 For Loop~~ ✅
- ~~#11 Array 1D~~ ✅ (bloques arr-const, build-array, index-array, array-size, array-subset)
- ~~#16 Case Structure~~ ✅ (PR#46 pendiente de merge — frames navegables, case/either)
- ~~#16 Case Structure~~ ✅
- ~~#12 Cluster~~ ✅
- ~~#13 Waveform Chart y Graph~~ ✅
- ~~#54 Cluster persiste campos~~ ✅ ~~#48/#50/#51 bugs menores~~ ✅
- QA-018/029: protecciones de integridad ✅
- Refactor 4A-4E: responsabilidades reorganizadas, ficheros grandes divididos ✅
- 462 tests PASS

**Próximo paso:** Issue #12 (Cluster).
**Próximo paso:** Fase 3 — #17 Sub-VI con connector pane.

## Decisiones técnicas clave

Expand Down Expand Up @@ -249,8 +258,8 @@ Trabajar siempre en orden de Fase. No empezar una fase sin completar la anterior
5. ~~#11 Array 1D~~ ✅
6. ~~#16 Case Structure~~ ✅ (PR#46 pendiente merge)
7. ~~#12 Cluster~~ ✅ (PR pendiente de merge)
8. #13 Waveform chart y graph
9. #28 Front Panel standalone (puede esperar)
8. ~~#13 Waveform chart y graph~~ ✅
9. #28 Front Panel standalone (pospuesto a Fase 3)

**Bugs detectados en pruebas (Fase 2):**
- #48 Bundle/Unbundle vacíos tienen altura excesiva (`canvas.red`)
Expand Down Expand Up @@ -373,50 +382,50 @@ Cubre sintaxis core, View, Draw, VID, Parse, patrones idiomáticos y gotchas.

### Responsabilidades mal ubicadas

| Función | Está en | Debería estar en | Por qué |
|---------|---------|-------------------|---------|
| `compile-panel`, `gen-panel-var-name`, `gen-standalone-code` | panel.red | compiler.red | Lógica de compilación en un módulo de UI |
| `save-panel-to-diagram`, `load-panel-from-diagram` | panel.red | file-io.red | Serialización en un módulo de UI |
| `make-diagram-model` | canvas.red | model.red | Creación de modelo en un módulo de UI |
| `make-fp-item` | panel.red | model.red | Constructor de datos en un módulo de UI |
| Lógica de `btn-run` (50+ líneas inline) | qtorres.red | función nombrada (ej: `run-diagram`) | Lógica de negocio inline en un actor de face |
> **Refactor 4A completado (2026-04-08, PR #60):** Las responsabilidades más críticas ya están en sus módulos correctos.

### Dependencia circular canvas.red <-> panel.red
| Función | Movida a | Estado |
|---------|----------|--------|
| `compile-panel`, `gen-panel-var-name`, `gen-standalone-code` | `compiler.red` | ✅ Movida |
| `save-panel-to-diagram`, `load-panel-from-diagram` | `file-io.red` | ✅ Movida |
| `make-diagram-model` | `model.red` | ✅ Movida |
| `make-fp-item`, `fp-cluster-fields`, `fp-default-label` | `model.red` | ✅ Movida |
| `find-node-by-id` | `model.red` | ✅ Añadida |
| `set-config` | `model.red` | ✅ Añadida |
| Lógica de `btn-run` (50+ líneas inline) | qtorres.red | ⚠️ Pendiente Fase 3 |

### Dependencia canvas.red <-> panel.red

- `canvas.red` llama a `render-fp-panel` (definida en panel.red)
- `panel.red` llama a `render-bd`, `gen-node-id` (definidas en canvas.red)
- `panel.red` llama a `render-bd`, `gen-node-id` (definidas en canvas-render.red)

Funciona porque el chain loading carga canvas antes que panel, pero:
- Ninguno puede testearse aisladamente
- El orden de `#include` es frágil
- **Regla para IA:** NO agravar esta dependencia. Si necesitas sincronizar BD↔FP, usar el patrón existente; no crear nuevas dependencias cruzadas.
El acoplamiento es **por diseño del dominio** (FP↔BD son una unidad 1:1) y no es deuda técnica.
- **Regla para IA:** NO agravar esta dependencia. Usar el patrón existente para sincronizar BD↔FP.

### Ficheros demasiado grandes (riesgo de pérdida de contexto)
### Ficheros y tamaños (2026-04-08)

| Fichero | Líneas | Riesgo |
|---------|--------|--------|
| canvas.red | 2383 | **CRÍTICO** — split urgente. Render, hit-test, eventos, diálogos, paleta, CRUD, modelo, estructuras, arrays. |
| panel.red | 928 | **ALTO** — Render + hit-test + eventos + serialización + compilación + diálogos + demo. |
| compiler.red | 831 | **ALTO** — compile-diagram + todas las estructuras. |
| file-io.red | 647 | Medio — `format-qvi` recorre `ui-layout` por índice (frágil). |
| Fichero | Líneas | Contenido |
|---------|--------|-----------|
| canvas.red | 1226 | Hit-test, CRUD, actor render-diagram |
| canvas-render.red | 932 | Constantes visuales, geometría, Draw |
| canvas-dialogs.red | 397 | Diálogos de edición, paleta, SR helpers |
| panel.red | 535 | Hit-test, diálogos FP, paleta FP, actor |
| panel-render.red | 411 | Constantes FP, render Draw, waveform |
| compiler.red | 1029 | compile-diagram + compile-panel + estructuras |
| file-io.red | 738 | serialize, save/load .qvi, save/load panel |
| model.red | 635 | Constructores, helpers, find-node-by-id, set-config |

**Regla para IA:** Al trabajar en canvas.red o panel.red, leer el fichero COMPLETO antes de hacer cambios. No asumir que entiendes la estructura por haber leído solo una parte.
**Regla para IA:** Al trabajar en canvas.red o panel.red y sus submódulos, leer el fichero COMPLETO antes de hacer cambios.

### Abstracciones que faltan
### Abstracciones pendientes

1. **`find-node-by-id`** — El patrón `foreach node model/nodes [if node/id = target-id [...]]` se repite ~15 veces en canvas.red, compiler.red, panel.red y qtorres.red. Debería ser una función en model.red.
2. **`set-config`** — El patrón `either pos: find node/config 'default [pos/2: val] [append node/config reduce ['default val]]` se repite 3 veces en canvas.red. Debería ser un helper en model.red.
3. **Conocimiento de tipos disperso** — El comportamiento por tipo (`bool-const`, `str-const`, etc.) está hardcodeado en canvas.red, panel.red, compiler.red y blocks.red. Añadir un tipo nuevo requiere tocar 4+ ficheros en 10+ ubicaciones. blocks.red debería llevar hints de renderizado/compilación.
1. **Conocimiento de tipos disperso** — El comportamiento por tipo (`bool-const`, `str-const`, etc.) está hardcodeado en canvas-render.red, panel-render.red, compiler.red y blocks.red. Añadir un tipo nuevo requiere tocar 4+ ficheros. blocks.red debería llevar hints de renderizado/compilación.

### Estado global compartido

`app-model` (definido en qtorres.red) es el único modelo compartido. canvas.red, panel.red y qtorres.red lo leen y mutan a través de `face/extra`. No hay mecanismo de notificación — cada módulo muta directamente y llama al render del otro.
`app-model` (definido en qtorres.red) es el único modelo compartido. canvas.red, panel.red y qtorres.red lo leen y mutan a través de `face/extra`. No hay mecanismo de notificación.

### Plan de corrección (NO ejecutar ahora)
### Plan de corrección (pendiente Fase 3)

Estos refactorings se harán como Issues dedicados cuando haya un hueco entre features:
1. Extraer `make-diagram-model` y `make-fp-item` → model.red
2. Mover `compile-panel` + helpers → compiler.red
3. Mover `save/load-panel-*` → file-io.red
4. Añadir `find-node-by-id` y `set-config` a model.red
5. Romper la dependencia circular canvas↔panel con callbacks
1. Centralizar conocimiento de tipos en blocks.red (hints de renderizado)
2. Extraer lógica de `btn-run` a función nombrada en qtorres.red
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# QTorres

> **v0.2.0** — Fase 2 completada (tipos, estructuras de control, waveform)

**LabVIEW open source construido sobre Red-Lang.**
Si sabes programar en LabVIEW, sabes programar en QTorres.

Expand Down Expand Up @@ -52,7 +54,11 @@ La estructura de ficheros replica las convenciones de LabVIEW. Donde LabVIEW gua

## Estado

**En desarrollo inicial.** El proyecto está en fase de diseño y prototipado.
**v0.2.0** — Alpha en desarrollo activo.

- Fase 0 (spike) y Fase 1 (pipeline end-to-end): completadas
- Fase 2 (tipos de datos y estructuras de control): completada — 40 bloques, 462 tests
- Fase 3 (Sub-VIs y extensibilidad): próxima

## Estructura del proyecto

Expand Down
149 changes: 113 additions & 36 deletions findings.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,110 @@
# Findings — Issue #13: Waveform Chart y Graph
# Findings — Transición Fase 2

## Investigación LabVIEW (2026-04-03)
## Bug #54 — Cluster no persiste campos

**Issue:** https://github.com/anlaco/QTorres/issues/54

**Síntomas:**
1. Al añadir campos a cluster-control en el editor → puertos no aparecen en BD
2. Al cerrar y reabrir el editor → campos desaparecen (no persisten)
3. Cluster-indicator no permite añadir ningún elemento

**Componentes sospechosos:**
- `src/ui/diagram/canvas.red` — editor de cluster, render de puertos
- `src/ui/panel/panel.red` — gestión de cluster-indicator

**Estado:** Pendiente de investigación con Task explore agent.

---

## Auditoría Fase 2 (2026-04-03)

**Documento:** `docs/auditoria-fase-2.md` (generado por qwen3-coder:480b)

**Veredicto:** 🟢 Verde funcional, 🟡 refactor bloqueante para Fase 3

**Hallazgos críticos:**
- panel.red (1255 líneas) tiene responsabilidades de compilación y serialización
- canvas.red (2557 líneas) demasiado grande — riesgo pérdida contexto
- Ciclo canvas↔panel impide testing aislado
- Abstracciones faltantes: `find-node-by-id` (ya implementado en #56), `set-config`

---

## Protecciones QA pendientes

Extraídas de plan QA antiguo, estado desconocido:

**QA-018:** Prohibir múltiples wires al mismo puerto entrada (Regla absoluta #6)
- Ubicación: `make-wire` en canvas.red o model.red

**QA-024:** Fix `fp-default-label` + asignación label en `open-edit-dialog`
- Ubicación: panel.red

**QA-029:** `save-panel-to-diagram` debe guardar `item/value`, no `item/default`
- Ubicación: panel.red
- Impacto: Round-trip incorrecto FP → qvi-diagram → FP

---

## Estado de Issues Fase 2

**Bugs abiertos:**
- #54 (cluster) — CRÍTICO bloqueante
- #48 (bundle/unbundle altura) — menor
- #49 (string auto-update) — menor, posible GTK
- #50 (headless no imprime) — menor
- #51 (nodos apilados) — menor

**Features pendientes:**
- #16 (Case Structure) — ¿completado? Verificar
- #13 (Waveform) — ✅ completado en #55
- #12 (Cluster) — ✅ completado en #52, pero #54 es regresión
- #28 (FP standalone) — decisión pendiente: ¿Fase 2 o 3?

---

## Arquitectura actual

**Líneas de código (2026-04-07):**
- canvas.red: 2557
- panel.red: 1255
- compiler.red: 891
- file-io.red: 647

**Dependencias problemáticas:**
- canvas.red → panel.red: `render-fp-panel`
- panel.red → canvas.red: `render-bd`, `gen-node-id`
- panel.red → compiler.red: ❌ NO (panel compila solo)
- panel.red → file-io.red: ❌ NO (panel serializa solo)

**Chain loading actual (qtorres.red):**
```red
#include %graph/model.red
#include %graph/blocks.red
#include %compiler/compiler.red
#include %io/file-io.red
#include %runner/runner.red
#include %ui/diagram/canvas.red
#include %ui/panel/panel.red
```

Orden crítico: canvas antes que panel (por dependencia circular).

---

## Próximas investigaciones

1. **Grep QA-018/024/029:** Verificar si ya están aplicadas en el código actual
2. **Task explore #54:** Flujo cluster-control editor → config/fields → render puertos
3. **Inventario canvas.red:** Agrupar funciones por categoría (render/eventos/dialogs)

---

## Histórico — Issue #13 (Waveform, completado)

<details>
<summary>Investigación LabVIEW (2026-04-03)</summary>

### Diferencia fundamental Chart vs Graph

Expand All @@ -11,54 +115,27 @@
| **Input** | Acepta scalar O array | Requiere array |
| **Uso** | Real-time, loops | Post-análisis |

### Comportamiento en loops

En LabVIEW:
- **Chart dentro de loop**: Se actualiza en CADA iteración. El wire conecta un valor escalar.
- **Graph dentro de loop**: Se actualiza al FINAL. El wire usa auto-indexing para acumular valores en un array.

### Default buffer size

LabVIEW usa 1024 puntos por defecto para el history buffer del Chart.

### Dimensiones

LabVIEW no documenta dimensiones fijas en pixels. El tamaño por defecto depende de la versión y resolución de pantalla. Para QTorres:
- Área de trazado: 200x160 px (razonable para ver señal)
- Con bordes: ~240x200 px total
LabVIEW usa 1024 puntos por defecto.

---

## Decisión de diseño para QTorres

### Waveform Chart
### Decisión de diseño QTorres

**Waveform Chart:**
```red
; fp-item
type: 'waveform-chart
data-type: 'number
config: [history-size 1024]
value: [] ; buffer circular
```

- Input: scalar (se añade al buffer) o array (se añade punto a punto)
- Buffer circular: cuando se llena, descarta el más antiguo
- Render: fondo negro, línea verde, escala automática

### Waveform Graph

**Waveform Graph:**
```red
; fp-item
type: 'waveform-graph
data-type: 'array
value: [] ; array completo a mostrar
value: [] ; array completo
```

- Input: array obligatorio
- Render: fondo negro, línea verde, escala automática
- No tiene buffer interno

### Wire colors
Wire colors: Chart naranja, Graph naranja doble borde (array).

- Chart input: naranja (numérico escalar)
- Graph input: naranja con borde doble (array numérico)
</details>
Loading
Loading