4.1 KiB
0042 — C++ layout_storage: extraer y publicar como API reutilizable
Metadata
| Campo | Valor |
|---|---|
| ID | 0042 |
| Estado | pendiente |
| Prioridad | alta |
| Tipo | feature — C++ core (cpp/functions/core) |
Dependencias
Ninguna. Habilita 0043 (estandarizar apps).
Objetivo
Extraer la persistencia de layouts ImGui (actualmente privada en shaders_lab/main.cpp lineas 415-447) a una funcion publica del registry: layout_storage_cpp_core. Cualquier app puede pasarla a app_menubar via LayoutCallbacks con un solo setup.
Contexto
shaders_lab guarda layouts (snapshots de imgui.ini) en SQLite via shaderlab_db_cpp_core. La logica que conecta SQLite con LayoutCallbacks (save, load, list, remove) esta inline en su main.cpp y no es reusable. Otras apps (registry_dashboard, primitives_gallery, chart_demo) no tienen layouts persistentes.
Arquitectura
cpp/functions/core/
├── layout_storage.h # NEW — API publica
├── layout_storage.cpp # NEW — impl con SQLite
├── layout_storage.md # NEW
└── (opcional) layouts_menu.h ya existe — sin cambios
cpp/apps/shaders_lab/
└── main.cpp # MOD — usa layout_storage en lugar de inline
API propuesta
namespace fn_ui {
struct LayoutStorage; // opaque
// Crea un storage que persiste layouts ImGui en una tabla SQLite del path dado.
// Si la BD no existe, la crea. Tabla: `imgui_layouts(name TEXT PRIMARY KEY, ini TEXT, updated_at)`.
LayoutStorage* layout_storage_open(const char* db_path);
void layout_storage_close(LayoutStorage* s);
// Helper que rellena un LayoutCallbacks usando este storage.
// El caller mantiene vivo el storage durante la vida de los callbacks.
void layout_storage_make_callbacks(LayoutStorage* s, LayoutCallbacks& out);
}
LayoutCallbacks ya esta definido en panel_menu.h/layouts_menu.h. Esta funcion solo wirea SQLite.
Tareas
Fase 1 — Codigo
1.1 Crear cpp/functions/core/layout_storage.{h,cpp,md}.
1.2 Implementar usando sqlite3 vendoreada (cpp/vendor/sqlite3). Tabla unica imgui_layouts.
1.3 Save: serializa ImGui::SaveIniSettingsToMemory() y hace UPSERT por nombre.
1.4 Load: lee ini y llama ImGui::LoadIniSettingsFromMemory(ini, len).
1.5 List: SELECT name FROM imgui_layouts ORDER BY updated_at DESC.
1.6 Remove: DELETE FROM imgui_layouts WHERE name=?.
1.7 Frontmatter .md con purity: impure, error_type: error_go_core, uses_types: [].
Fase 2 — Migrar shaders_lab
2.1 Reemplazar el bloque inline (l. 415-447) por:
auto* g_layouts = fn_ui::layout_storage_open("shaders_lab.db");
fn_ui::LayoutCallbacks layouts_cb;
fn_ui::layout_storage_make_callbacks(g_layouts, layouts_cb);
// ...pasar layouts_cb a app_menubar
2.2 Mantener shaderlab_db_cpp_core como esta (no es lo mismo: guarda shaders, no layouts) — pero quitar de el la parte de layouts si la tiene.
2.3 Verificar que los layouts existentes siguen cargando (compatibilidad de schema o migracion automatica).
Fase 3 — Tests
3.1 Test unitario: open → save("test", ini) → list() == ["test"] → load("test") devuelve el ini → remove("test") → list() == []. 3.2 Test de regresion en shaders_lab (build + abrir/cerrar layout manual).
Fase 4 — Indexar
4.1 ./fn index y verificar fn show layout_storage_cpp_core.
Decisiones de diseno
- BD SQLite por app (no compartida) — cada app gestiona sus layouts.
- Schema simple (
name PRIMARY KEY, ini, updated_at) — sin namespaces ni jerarquia. - API opaca (
LayoutStorage*) para no exponer sqlite3 en headers publicos.
Riesgos
- shaders_lab tiene layouts existentes en su
shaders_lab.db. Si la tabla actual difiere del schema nuevo: migracion automatica al primer open o conservar ambas tablas. - Threading: ImGui::SaveIniSettingsToMemory solo es seguro desde el thread principal — documentar.
Validacion
cd cpp/build && cmake --build . --target shaders_lab
# Abrir shaders_lab, guardar/cargar layouts, restart, verificar que persiste.
./fn show layout_storage_cpp_core