Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.2 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 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0041 | C++ app shell estandarizado: BEST_PRACTICES + AppConfig extendido | completado | feature |
|
app-scoped | alta | 2026-05-17 | 2026-05-17 |
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
- Documentar el patron canonico de apps C++ del registry en
cpp/PATTERNS.mdcon checklist obligatorio. - Extender
fn::AppConfigpara quefn::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)
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 != nullptrolayouts_cb != nullptr, llamaapp_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()conAppConfig(jamasglfwInitdirecto). - Registra About via
AppConfig::aboutoabout_window_set_info(). - Registra Settings extras via
settings_window_add_section(). - Si tienes paneles, define
static constexpr fn_ui::PanelToggle panels[]y pasalo enAppConfig::panels. - Si necesitas layouts, implementa
LayoutCallbacksy pasalas enAppConfig::layouts_cb. - Usa
fn_tokens::colors|spacing|radiussiempre. Nunca colores hex literales. - Evita
ImGui::BeginTable / Selectable / BeginPopupModal / BeginChildcon styling manual — usadashboard_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_initopcional. - Tras
about_window_set_infosi procede. - Antes del
render_fn()por frame, llamaapp_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
AppConfigcon campos opcionales (no nuevos overloads derun_app) — minimiza la API surface.- La menubar se llama desde
run_appsolo si la app declara paneles/layouts; en otro caso la app puede llamarapp_menubar(nullptr,0,nullptr)ella misma (compat).
Riesgos
- Apps que ya llaman
app_menubarmanualmente conpanelsdistintos alAppConfig: documentar —run_appla llama una vez al inicio del frame, la app puede dejar de hacerlo.
Validacion
cpp/PATTERNS.mdlegible en GitHub.chart_demo(la mas simple) puede ahora declararse asi: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.