## Estandarizacion de apps C++ del registry **Fuentes autoritativas:** - `cpp/PATTERNS.md` — checklist y esqueleto del app shell (`fn::run_app`, AppConfig, panels, layouts, Settings, About). - `cpp/DESIGN_SYSTEM.md` — identidad visual (`fn_tokens`, ThemeMode, equivalencias `@fn_library` ↔ C++). Esta regla NO duplica esos documentos — los señala como obligatorios y añade convenciones estructurales que no aparecen alli. ### 1. Ubicacion | Caso | Donde vive | |---|---| | App independiente | `cpp/apps//` | | App de un proyecto | `projects//apps//` | NUNCA en `cpp/apps//` si pertenece a un proyecto, NUNCA fuera de `apps/` directamente. Ver `apps_location` en memoria + regla `apps_vs_functions.md`. ### 2. Estructura minima ``` / CMakeLists.txt # usa add_imgui_app(target ...) app.md # frontmatter de registro (ver §4) main.cpp # entry: parseo de args + fn::run_app + render() [data.{h,cpp}] # opcional: capa de datos (DB / HTTP / archivos) [views.{h,cpp}] # opcional: composicion de paneles [.{h,cpp}] # opcional: dominio especifico [vendor/] # opcional: deps no comunes (se prefieren las globales en cpp/vendor/) [.git/] # cada app es su propio repo Gitea (ver §6) ``` **Reglas de split:** - `main.cpp` SIEMPRE — punto de entrada con `int main()` + `fn::run_app(...)` + funcion `render()`. - Si la app supera ~400 lineas en `main.cpp`, partir en `data.{h,cpp}` (carga/persistencia) + `views.{h,cpp}` (UI por panel). - Modulos especificos del dominio en archivos propios (`compiler.cpp` en `shaders_lab`, `data_http.cpp` en `registry_dashboard`). - NO crear archivos de "utilidades genericas" dentro de la app — eso va al registry como funcion (`cpp/functions/...`). ### 3. CMakeLists.txt Patron canonico: ```cmake add_imgui_app( main.cpp [extra_modules.cpp] # Funciones del registry usadas (paths absolutos): ${CMAKE_SOURCE_DIR}/functions//.cpp ... ) target_include_directories( PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries( PRIVATE [SQLite::SQLite3] [imgui_node_editor] ...) if(WIN32) set_target_properties( PROPERTIES WIN32_EXECUTABLE TRUE) endif() ``` Reglas: - Usar SIEMPRE la macro `add_imgui_app(target ...)` — gestiona enlace con `fn_framework` y copia de TTFs. - Listar explicitamente cada `.cpp` del registry usado (no glob). Hace visible el grafo de dependencias. - NO listar `tokens.cpp`, `icon_font.cpp`, `app_settings.cpp`, `app_about.cpp`, `fps_overlay.cpp`, `panel_menu.cpp`, `app_menubar.cpp`, `layouts_menu.cpp`, `gl_loader.cpp`, `layout_storage.cpp` — viven en `fn_framework` y dan multiple-definition si se duplican. - En `WIN32`, marcar `WIN32_EXECUTABLE TRUE` para apps GUI (sin consola). ### 4. app.md (frontmatter) Plantilla minima para apps C++: ```yaml --- name: lang: cpp domain: description: "Frase corta — lo que hace y por que existe." tags: [imgui, ...] # si es service, anadir 'service' uses_functions: # IDs del registry — el indexer NO deduce C++ - _cpp_ - ... uses_types: [] framework: "imgui" entry_point: "main.cpp" dir_path: "cpp/apps/" o "projects//apps/" repo_url: "https://gitea-.../dataforge/" --- ``` Reglas: - `uses_functions` se rellena a mano con los IDs de las funciones del registry usadas en `CMakeLists.txt`. Auditar con: `sqlite3 registry.db "SELECT id FROM apps WHERE id='';"` + revisar diffs. - `framework: "imgui"` siempre que use `fn::run_app`. Otros valores solo si la app NO usa el shell (raro). - `tags`: incluir `service` si es daemon de larga duracion (ver `function_tags.md`). - `repo_url` apunta al sub-repo en Gitea (ver §6). ### 5. Registro en `cpp/CMakeLists.txt` Cada app nueva se registra al final de `cpp/CMakeLists.txt`: ```cmake # --- --- if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/apps//CMakeLists.txt) add_subdirectory(apps/) endif() ``` Para apps en proyectos (fuera del arbol `cpp/`): ```cmake # --- (lives in projects//apps/) --- set(__DIR ${CMAKE_SOURCE_DIR}/../projects//apps/) if(EXISTS ${__DIR}/CMakeLists.txt) add_subdirectory(${__DIR} ${CMAKE_BINARY_DIR}/apps/) endif() ``` El `if(EXISTS ...)` hace el registro tolerante a apps no clonadas (cada app es sub-repo separado). ### 6. Sub-repo Gitea (TBD obligatorio) Cada app C++ es su propio repo en `dataforge/` con branch `master`. Esto significa: - El directorio `/` esta en el `.gitignore` de `fn_registry` (excepto `app.md`). - El propio directorio tiene `.git/` apuntando al sub-repo. - TBD obligatorio mientras se desarrolla la app: ver `apps_tbd.md`. Trabajar en `issue/-` o `quick/`, mergear a `master` con `--no-ff`. - Sync entre PCs y push/pull se gestionan con `/full-git-push` y `/full-git-pull`. ### 7. Convenciones de runtime Cumplir el checklist completo de `cpp/PATTERNS.md`. Resumen de lo que NUNCA debe aparecer en una app: | Anti-patron | Sustituir por | |---|---| | `glfwInit()` en `main` | `fn::run_app(cfg, render)` | | `ImGui::StyleColorsDark()` | `cfg.theme = ThemeMode::FnDark` (default) | | `ImVec4(0.5,0.5,0.5,1)` | `fn_tokens::colors::*` | | `ImGui::Begin(u8"\xEF...")` | `ImGui::Begin(TI_HOME " ...")` | | Menubar inline cada frame | `cfg.panels` + `cfg.layouts_cb` | | About hardcoded en un panel | `cfg.about = {...}` | | `gl*` directo sin loader | `cfg.init_gl_loader = true` | | Tabla SQLite en la raiz del repo | `/.db` (operations.db es solo para entities/relations/executions) | ### 8. Tests visuales (recomendado, no obligatorio) Si la app tiene componentes que se quieren proteger contra regresiones visuales, anadir un demo en `cpp/apps/primitives_gallery/demos_.cpp` que use los mismos componentes/funciones del registry. El sistema de capture-and-compare de `primitives_gallery --capture` funciona como golden-image gate (ver final de `cpp/PATTERNS.md`). ### 9. Decisiones que cada app debe tomar y documentar en su `app.md` - `viewports`: `true` (default) si las ventanas pueden arrastrarse fuera del main; `false` si la app necesita estar siempre embebida. - `init_gl_loader`: `true` si llama `gl*` directo (renderers GPU custom como `graph_renderer`); `false` si solo usa ImGui/ImPlot. - `about` info: nombre, version (semver), descripcion 1 frase. - Persistencia: `.db` SQLite junto al exe; nunca tocar `registry.db` ni `operations.db` salvo lectura. - Modo CLI: si la app acepta args, documentarlos en el `app.md` con ejemplos.