feat(framework): convencion local_files/ — separacion distribuible vs estado
Toda app C++ basada en fn::run_app coloca sus archivos escribibles
bajo <exe_dir>/local_files/. Los distribuibles (.exe, dlls, ttfs,
enrichers/, runtime/) siguen junto al .exe. Esto deja la carpeta
distribuible limpia para zippear y separa con claridad lo que
viaja con la app de lo que el PC genera.
API publica en fn:: (cpp/framework/app_base.h):
- exe_dir() directorio del ejecutable
- local_dir() <exe_dir>/local_files/, creado on-demand
- local_path(name) <local_dir>/<name>
- migrate_to_local_files(...) mueve archivos viejos desde cwd/exe_dir
Cambios:
- run_app configura io.IniFilename = local_path("imgui.ini") y
llama migrate_to_local_files(["imgui.ini","app_settings.ini"])
antes de settings_load(). Migracion idempotente para PCs con
instalacion previa.
- app_settings.cpp usa local_path("app_settings.ini") en lugar de
hardcoded "app_settings.ini" relativo al cwd.
- cpp_apps.md §7 documenta la convencion como obligatoria. Las
apps deben usar fn::local_path() para cualquier archivo
escribible nuevo.
Beneficios:
- zip distribuible no se "ensucia" con .ini/.db generados al usar.
- reset trivial: borrar local_files/.
- backup/sync per-PC: solo local_files/ es propio del PC.
- elimina la mezcla de paths Linux/Windows que generaba bugs como
"projects\\default\\operations.db" en builds cross-platform.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,10 +17,62 @@ namespace fn_ui {
|
||||
const char* version = nullptr;
|
||||
const char* description = nullptr;
|
||||
};
|
||||
|
||||
// Config de logging. Si file_path != nullptr, fn::run_app llama
|
||||
// fn_log::logger_init(file_path, level) al inicio y fn_log::logger_close()
|
||||
// al exit. file_path se interpreta relativo al cwd (junto al ejecutable,
|
||||
// igual que app_settings.ini). Si file_path == nullptr, no se escribe a
|
||||
// disco — la ventana Logs sigue funcionando contra el buffer in-memory.
|
||||
//
|
||||
// level: 0=Debug, 1=Info, 2=Warn, 3=Error. Default Info.
|
||||
struct AppLogConfig {
|
||||
const char* file_path = nullptr;
|
||||
int level = 1; // fn_log::Level::Info
|
||||
};
|
||||
}
|
||||
|
||||
namespace fn {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Local files — separacion de archivos distribuibles vs estado local.
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Convencion del registry: TODA app coloca sus archivos escribibles
|
||||
// (settings, DBs, layouts ImGui, caches, proyectos del usuario) bajo
|
||||
// `<exe_dir>/local_files/`. Los archivos distribuibles (.exe, .ttf,
|
||||
// .dll, runtime/, enrichers/) viven directos en `<exe_dir>/`.
|
||||
//
|
||||
// Esto mantiene la carpeta del .exe limpia para distribuir, separa
|
||||
// nitidamente "lo que vino con el zip" de "lo que el PC genero", y
|
||||
// facilita el reset (basta con borrar local_files/).
|
||||
//
|
||||
// `fn::run_app` configura `io.IniFilename = local_path("imgui.ini")` y
|
||||
// `app_settings.ini` se lee/escribe desde local_files/ automaticamente.
|
||||
// Cualquier archivo escribible adicional de la app debe usar
|
||||
// `fn::local_path("nombre")` al construir su path.
|
||||
//
|
||||
// La carpeta se crea on-demand en la primera llamada a `local_dir()`.
|
||||
// Si existen archivos viejos en el cwd (compat con versiones previas
|
||||
// del registry), `migrate_to_local_files()` los mueve.
|
||||
|
||||
// Devuelve el directorio del ejecutable actual (sin trailing slash).
|
||||
// "" si no se puede resolver (raro — fallback al cwd).
|
||||
const char* exe_dir();
|
||||
|
||||
// Devuelve el path absoluto a `<exe_dir>/local_files/`. Crea la
|
||||
// carpeta si no existe. Sin trailing slash.
|
||||
const char* local_dir();
|
||||
|
||||
// Construye `<local_dir>/<name>`. El puntero retornado apunta a un
|
||||
// std::string interno por-thread que permanece valido hasta la
|
||||
// proxima llamada — copia el valor si vas a guardarlo.
|
||||
const char* local_path(const char* name);
|
||||
|
||||
// Mueve los archivos listados de cwd o exe_dir a local_files/ si
|
||||
// existen ahi pero NO existen ya en local_files/. Idempotente. Las
|
||||
// apps lo llaman al iniciar para migrar instalaciones viejas.
|
||||
void migrate_to_local_files(const char* const* names, std::size_t n);
|
||||
|
||||
// Modos de tema para run_app.
|
||||
enum class ThemeMode {
|
||||
FnDark, // Identidad del registry (Mantine v9 dark + indigo). DEFAULT.
|
||||
@@ -58,6 +110,12 @@ struct AppConfig {
|
||||
// GL y antes del primer frame. Necesario para apps que llaman gl* directo
|
||||
// en Windows (en Linux es no-op).
|
||||
bool init_gl_loader = false;
|
||||
|
||||
// Logging opcional. Si log.file_path != nullptr, run_app inicializa el
|
||||
// logger global antes del primer frame y lo cierra al exit. La ventana
|
||||
// "Logs..." en el menubar siempre esta disponible (lee del buffer
|
||||
// in-memory aunque no haya archivo).
|
||||
fn_ui::AppLogConfig log{};
|
||||
};
|
||||
|
||||
// Run an ImGui application. The render_fn is called every frame
|
||||
|
||||
Reference in New Issue
Block a user