refactor(companion): unify screen save-on-exit via UITask::savePrefsIfDirty()

The "_dirty bool, then if (_dirty) the_mesh.savePrefs() on exit" pattern was
duplicated across 9 screens with subtle divergence: some cleared the flag
after saving, some left it set and relied on onShow() to reset. Replace all
12 exit sites with a single _task->savePrefsIfDirty(flag) helper that saves
once only if dirty and always clears the flag, so the "did we touch flash?"
answer lives in one place and the reset is consistent.

Edit sites still mark the flag manually (inherent to change tracking); only
the persist-on-exit boilerplate is centralised.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MarekZegare4
2026-06-29 18:47:51 +02:00
co-authored by Claude Opus 4.8
parent 15716d2b03
commit 0e6bd743a6
11 changed files with 24 additions and 16 deletions
@@ -51,7 +51,7 @@ public:
bool handleInput(char c) override { bool handleInput(char c) override {
if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) { if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) {
if (_dirty) the_mesh.savePrefs(); _task->savePrefsIfDirty(_dirty);
_task->gotoToolsScreen(); _task->gotoToolsScreen();
return true; return true;
} }
+1 -1
View File
@@ -141,7 +141,7 @@ public:
} }
if (cancel) { if (cancel) {
if (_dirty) the_mesh.savePrefs(); _task->savePrefsIfDirty(_dirty);
_task->gotoToolsScreen(); _task->gotoToolsScreen();
return true; return true;
} }
@@ -65,7 +65,7 @@ public:
bool handleInput(char c) override { bool handleInput(char c) override {
if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) { if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) {
if (_dirty) the_mesh.savePrefs(); _task->savePrefsIfDirty(_dirty);
_task->gotoHomeScreen(); _task->gotoHomeScreen();
return true; return true;
} }
@@ -161,7 +161,7 @@ public:
bool handleInput(char c) override { bool handleInput(char c) override {
if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) { if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) {
if (_dirty) { the_mesh.savePrefs(); _dirty = false; } _task->savePrefsIfDirty(_dirty);
_task->gotoToolsScreen(); _task->gotoToolsScreen();
return true; return true;
} }
@@ -293,7 +293,7 @@ public:
return true; return true;
} }
if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) { if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) {
if (_dirty) { the_mesh.savePrefs(); _dirty = false; } // engine re-seeded per edit _task->savePrefsIfDirty(_dirty); // engine re-seeded per edit
_task->gotoToolsScreen(); _task->gotoToolsScreen();
return true; return true;
} }
@@ -1606,9 +1606,7 @@ public:
// sel == 1 (Notif) and sel == 2 (Melody): already cycled via LEFT/RIGHT; ENTER just closes. // sel == 1 (Notif) and sel == 2 (Melody): already cycled via LEFT/RIGHT; ENTER just closes.
} }
} }
if (res != PopupMenu::NONE && _ctx_dirty) { if (res != PopupMenu::NONE) _task->savePrefsIfDirty(_ctx_dirty);
the_mesh.savePrefs(); _ctx_dirty = false;
}
return true; return true;
} }
if (c == KEY_CANCEL) { _room_mode = false; _phase = MODE_SELECT; return true; } if (c == KEY_CANCEL) { _room_mode = false; _phase = MODE_SELECT; return true; }
@@ -1718,9 +1716,7 @@ public:
} }
// sel 1/2/3 already handled by LEFT/RIGHT; ENTER just closes. // sel 1/2/3 already handled by LEFT/RIGHT; ENTER just closes.
} }
if (res != PopupMenu::NONE && _ctx_dirty) { if (res != PopupMenu::NONE) _task->savePrefsIfDirty(_ctx_dirty);
the_mesh.savePrefs(); _ctx_dirty = false;
}
return true; return true;
} }
if (c == KEY_CANCEL) { _phase = MODE_SELECT; return true; } if (c == KEY_CANCEL) { _phase = MODE_SELECT; return true; }
@@ -211,7 +211,7 @@ public:
} }
if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) { if (c == KEY_CANCEL || c == KEY_CONTEXT_MENU) {
if (_dirty) the_mesh.savePrefs(); _task->savePrefsIfDirty(_dirty);
_task->gotoToolsScreen(); _task->gotoToolsScreen();
return true; return true;
} }
@@ -754,7 +754,7 @@ public:
} }
if (c == KEY_CANCEL) { if (c == KEY_CANCEL) {
if (_dirty) the_mesh.savePrefs(); _task->savePrefsIfDirty(_dirty);
_task->gotoHomeScreen(); _task->gotoHomeScreen();
return true; return true;
} }
@@ -192,16 +192,16 @@ public:
case ACT_EXPORT: handleExport(); break; case ACT_EXPORT: handleExport(); break;
case ACT_EXPORT_SAVED: handleExportSaved(); break; case ACT_EXPORT_SAVED: handleExportSaved(); break;
} }
if (_cfg_dirty) { the_mesh.savePrefs(); _cfg_dirty = false; } _task->savePrefsIfDirty(_cfg_dirty);
} else if (res == PopupMenu::CANCELLED) { } else if (res == PopupMenu::CANCELLED) {
if (_cfg_dirty) { the_mesh.savePrefs(); _cfg_dirty = false; } _task->savePrefsIfDirty(_cfg_dirty);
if (_menu_level != ML_MAIN) buildMainMenu(); // Cancel backs out of a submenu if (_menu_level != ML_MAIN) buildMainMenu(); // Cancel backs out of a submenu
} }
return true; return true;
} }
if (c == KEY_CANCEL) { if (c == KEY_CANCEL) {
if (_cfg_dirty) { the_mesh.savePrefs(); _cfg_dirty = false; } _task->savePrefsIfDirty(_cfg_dirty);
if (_return_home) _task->gotoHomeScreen(); if (_return_home) _task->gotoHomeScreen();
else _task->gotoToolsScreen(); else _task->gotoToolsScreen();
return true; return true;
@@ -1758,6 +1758,13 @@ void UITask::setCurrScreen(UIScreen* c) {
_next_refresh = 100; _next_refresh = 100;
} }
bool UITask::savePrefsIfDirty(bool& dirty) {
if (!dirty) return false;
the_mesh.savePrefs();
dirty = false;
return true;
}
/* /*
hardware-agnostic pre-shutdown activity should be done here hardware-agnostic pre-shutdown activity should be done here
*/ */
+5
View File
@@ -355,6 +355,11 @@ public:
void applyPowerSave(); // hardware duty-cycle RX on/off from prefs void applyPowerSave(); // hardware duty-cycle RX on/off from prefs
void applyApc(); // Adaptive Power Control on/off from prefs void applyApc(); // Adaptive Power Control on/off from prefs
void applyRadioParams(); // freq/bw/sf/cr from prefs (radio preset change) void applyRadioParams(); // freq/bw/sf/cr from prefs (radio preset change)
// Save-on-exit helper for the screen `_dirty` pattern: persists NodePrefs once
// only if `dirty`, then clears the flag. Standardises the screens' exit paths
// (some used to leave the flag set, relying on onShow() to reset it) and keeps
// the "did we touch flash?" answer in one place. Returns whether it saved.
bool savePrefsIfDirty(bool& dirty);
void applyFont(); void applyFont();
void applyRotation(); void applyRotation();
void applyFullRefreshInterval(); void applyFullRefreshInterval();