125 lines
5.0 KiB
Markdown
125 lines
5.0 KiB
Markdown
# 0041 — C++ app shell estandarizado: BEST_PRACTICES + AppConfig extendido
|
|
|
|
## Metadata
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **ID** | 0041 |
|
|
| **Estado** | pendiente |
|
|
| **Prioridad** | alta |
|
|
| **Tipo** | feature — C++ framework (`cpp/framework/`) + docs |
|
|
|
|
## Dependencias
|
|
|
|
Ninguna. Habilita **0043** (estandarizar apps existentes) y todo desarrollo futuro de apps C++.
|
|
|
|
---
|
|
|
|
## Objetivo
|
|
|
|
1. Documentar el patron canonico de apps C++ del registry en `cpp/PATTERNS.md` con checklist obligatorio.
|
|
2. Extender `fn::AppConfig` para que `fn::run_app()` registre About + paneles + theming en una sola llamada, eliminando boilerplate por app.
|
|
|
|
## Contexto
|
|
|
|
La auditoria muestra que `chart_demo`, `primitives_gallery`, `shaders_lab` y `registry_dashboard` arrancan distinto: solo `shaders_lab` aprovecha `app_menubar` con paneles, solo `registry_dashboard` registra About + Settings, `primitives_gallery` llama `apply_dark_theme()` + `gl_loader_init()` a mano que el resto delega a `run_app()`. Sin estandar, cada app proxima reinventa esto.
|
|
|
|
## Arquitectura
|
|
|
|
```
|
|
cpp/
|
|
├── PATTERNS.md # NEW — checklist y patrones
|
|
├── framework/
|
|
│ ├── app_base.h # MOD — extender AppConfig
|
|
│ └── app_base.cpp # MOD — aplicar nuevos campos
|
|
└── functions/core/
|
|
└── (sin cambios — app_menubar/app_about/app_settings ya existen)
|
|
```
|
|
|
|
### AppConfig extendido (propuesta)
|
|
|
|
```cpp
|
|
struct AppAboutInfo {
|
|
const char* name = nullptr;
|
|
const char* version = nullptr;
|
|
const char* description = nullptr;
|
|
};
|
|
|
|
struct AppConfig {
|
|
const char* title = "fn app";
|
|
int width = 1280;
|
|
int height = 800;
|
|
bool vsync = true;
|
|
bool viewports = false;
|
|
ThemeMode theme = ThemeMode::FnDark;
|
|
float bg_r=0,bg_g=0,bg_b=0;
|
|
|
|
// NEW — registra About si name != nullptr.
|
|
AppAboutInfo about{};
|
|
|
|
// NEW — paneles toggleables del menubar (si != nullptr).
|
|
const fn_ui::PanelToggle* panels = nullptr;
|
|
size_t panel_count = 0;
|
|
|
|
// NEW — callbacks de layouts persistentes (si != nullptr).
|
|
fn_ui::LayoutCallbacks* layouts_cb = nullptr;
|
|
|
|
// NEW — si true, llama gl_loader_init() antes del primer frame.
|
|
bool init_gl_loader = false;
|
|
};
|
|
```
|
|
|
|
`run_app()` aplica:
|
|
- Si `about.name != nullptr` → `fn_ui::about_window_set_info(...)`.
|
|
- Si `init_gl_loader` → `fn::gfx::gl_loader_init()` tras crear el contexto GL.
|
|
- Cada frame, si `panels != nullptr` o `layouts_cb != nullptr`, llama `app_menubar(panels, panel_count, layouts_cb)` automaticamente — la app NO la llama.
|
|
|
|
## Tareas
|
|
|
|
### Fase 1 — Doc
|
|
|
|
1.1 Crear `cpp/PATTERNS.md` con checklist:
|
|
- Usa `fn::run_app()` con `AppConfig` (jamas `glfwInit` directo).
|
|
- Registra About via `AppConfig::about` o `about_window_set_info()`.
|
|
- Registra Settings extras via `settings_window_add_section()`.
|
|
- Si tienes paneles, define `static constexpr fn_ui::PanelToggle panels[]` y pasalo en `AppConfig::panels`.
|
|
- Si necesitas layouts, implementa `LayoutCallbacks` y pasalas en `AppConfig::layouts_cb`.
|
|
- Usa `fn_tokens::colors|spacing|radius` siempre. Nunca colores hex literales.
|
|
- Evita `ImGui::BeginTable / Selectable / BeginPopupModal / BeginChild` con styling manual — usa `dashboard_grid`, `tree_view`/`select`, `modal_dialog`, `dashboard_panel`.
|
|
|
|
### Fase 2 — Framework
|
|
|
|
2.1 Anadir campos `about`, `panels`, `panel_count`, `layouts_cb`, `init_gl_loader` a `AppConfig` en `app_base.h`.
|
|
2.2 En `run_app()` (`app_base.cpp`):
|
|
- Tras `gl_loader_init` opcional.
|
|
- Tras `about_window_set_info` si procede.
|
|
- Antes del `render_fn()` por frame, llama `app_menubar(panels, panel_count, layouts_cb)` si alguno != nullptr.
|
|
2.3 Backward-compat: campos nuevos opcionales con defaults — apps existentes compilan sin tocarlas.
|
|
|
|
### Fase 3 — Validacion
|
|
|
|
3.1 Compilar todas las apps existentes sin cambios, verificar que no rompe.
|
|
3.2 Build Linux + cross-compile Windows.
|
|
|
|
### Fase 4 — Indexar
|
|
|
|
4.1 `./fn index` para refrescar metadata (no cambia funciones — solo doc).
|
|
|
|
## Decisiones de diseno
|
|
|
|
- `AppConfig` con campos opcionales (no nuevos overloads de `run_app`) — minimiza la API surface.
|
|
- La menubar se llama desde `run_app` solo si la app declara paneles/layouts; en otro caso la app puede llamar `app_menubar(nullptr,0,nullptr)` ella misma (compat).
|
|
|
|
## Riesgos
|
|
|
|
- Apps que ya llaman `app_menubar` manualmente con `panels` distintos al `AppConfig`: documentar — `run_app` la llama una vez al inicio del frame, la app puede dejar de hacerlo.
|
|
|
|
## Validacion
|
|
|
|
- `cpp/PATTERNS.md` legible en GitHub.
|
|
- `chart_demo` (la mas simple) puede ahora declararse asi:
|
|
```cpp
|
|
fn::run_app({.title="chart demo", .about={.name="chart demo", .version="0.1", .description="..."}}, render);
|
|
```
|
|
- Tests de compilacion OK para shaders_lab/chart_demo/primitives_gallery/registry_dashboard sin modificar.
|