refactor(ui): centralise EINK_DISPLAY_MODEL toggles in Features.h

Five sites in UITask.cpp + MyMesh.cpp branched on EINK_DISPLAY_MODEL
purely for runtime-shape decisions (blink rate, default pref values,
refresh intervals). Replace with a constexpr Features namespace:
IS_EINK, BLINK_INDICATORS, CLOCK_HIDE_SECONDS_DEFAULT, HOME_REFRESH_MS,
LOCKSCREEN_REFRESH_MS. Compiler dead-branch-eliminates so cost is
identical to the preprocessor branch, but the code stays reachable to
tooling and the policy lives in one file.

SettingsScreen and driver headers still need real #ifdef — they
condition enum members and class field layouts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-24 20:41:25 +02:00
co-authored by Claude Sonnet 4.6
parent e16ecbd690
commit 7c81ea0f52
3 changed files with 36 additions and 23 deletions
+26
View File
@@ -0,0 +1,26 @@
#pragma once
// Build-time feature flags derived from board defines.
// Use these instead of `#ifdef EINK_DISPLAY_MODEL` for runtime-shape decisions
// (booleans, timings, defaults). Compiler dead-branch-eliminates on the
// constexpr, so cost is identical to a preprocessor branch but the code
// remains readable and reachable to tooling. Conditional struct members
// (enum entries, NodePrefs fields) still need a real `#if defined(...)`.
namespace Features {
#if defined(EINK_DISPLAY_MODEL)
static constexpr bool IS_EINK = true;
static constexpr bool BLINK_INDICATORS = false; // e-ink avoids high-rate redraws
static constexpr bool CLOCK_HIDE_SECONDS_DEFAULT = true; // pref starting value
static constexpr unsigned HOME_REFRESH_MS = 30000; // slow display polls less
static constexpr unsigned LOCKSCREEN_REFRESH_MS = 30000;
#else
static constexpr bool IS_EINK = false;
static constexpr bool BLINK_INDICATORS = true;
static constexpr bool CLOCK_HIDE_SECONDS_DEFAULT = false;
static constexpr unsigned HOME_REFRESH_MS = 1000;
static constexpr unsigned LOCKSCREEN_REFRESH_MS = 1000;
#endif
} // namespace Features
+2 -3
View File
@@ -1,5 +1,6 @@
#include "MyMesh.h" #include "MyMesh.h"
#include "MsgExpand.h" #include "MsgExpand.h"
#include "Features.h"
#include <Arduino.h> // needed for PlatformIO #include <Arduino.h> // needed for PlatformIO
#include <Mesh.h> #include <Mesh.h>
@@ -952,9 +953,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
_prefs.dm_show_all = 1; // show all contacts by default _prefs.dm_show_all = 1; // show all contacts by default
memset(_prefs.dm_notif, 0, sizeof(_prefs.dm_notif)); memset(_prefs.dm_notif, 0, sizeof(_prefs.dm_notif));
_prefs.auto_off_secs = 15; // 15 seconds auto-off by default _prefs.auto_off_secs = 15; // 15 seconds auto-off by default
#ifdef EINK_DISPLAY_MODEL _prefs.clock_hide_seconds = Features::CLOCK_HIDE_SECONDS_DEFAULT ? 1 : 0;
_prefs.clock_hide_seconds = 1; // e-ink: seconds cause a panel refresh every second
#endif
_prefs.tz_offset_hours = 0; // UTC by default _prefs.tz_offset_hours = 0; // UTC by default
_prefs.low_batt_mv = 3400; // auto-shutdown at 3.4V by default _prefs.low_batt_mv = 3400; // auto-shutdown at 3.4V by default
_prefs.batt_display_mode = 0; // icon by default _prefs.batt_display_mode = 0; // icon by default
+8 -20
View File
@@ -2,6 +2,7 @@
#include <helpers/TxtDataHelpers.h> #include <helpers/TxtDataHelpers.h>
#include "../MyMesh.h" #include "../MyMesh.h"
#include "../MsgExpand.h" #include "../MsgExpand.h"
#include "../Features.h"
#include "target.h" #include "target.h"
#ifdef WIFI_SSID #ifdef WIFI_SSID
#include <WiFi.h> #include <WiFi.h>
@@ -337,11 +338,7 @@ class HomeScreen : public UIScreen {
// "A" indicator — left of BT; blinks on OLED, always shown on e-ink // "A" indicator — left of BT; blinks on OLED, always shown on e-ink
if (_node_prefs && _node_prefs->advert_auto_interval_sec > 0) { if (_node_prefs && _node_prefs->advert_auto_interval_sec > 0) {
int aX = leftmostX - ind; int aX = leftmostX - ind;
#ifdef EINK_DISPLAY_MODEL bool show_a = Features::BLINK_INDICATORS ? ((millis() % 4000) < 2000) : true;
bool show_a = true;
#else
bool show_a = (millis() % 4000) < 2000;
#endif
if (show_a) { if (show_a) {
display.setColor(DisplayDriver::LIGHT); display.setColor(DisplayDriver::LIGHT);
display.fillRect(aX, 0, ind, ind_h); display.fillRect(aX, 0, ind, ind_h);
@@ -447,11 +444,7 @@ public:
char buf[24]; char buf[24];
display.setColor(DisplayDriver::LIGHT); display.setColor(DisplayDriver::LIGHT);
display.setTextSize(2); display.setTextSize(2);
#ifdef EINK_DISPLAY_MODEL bool show_sec = !Features::IS_EINK && (!_node_prefs || !_node_prefs->clock_hide_seconds);
bool show_sec = false;
#else
bool show_sec = !_node_prefs || !_node_prefs->clock_hide_seconds;
#endif
bool h12 = _node_prefs && _node_prefs->clock_12h; bool h12 = _node_prefs && _node_prefs->clock_12h;
if (h12) { if (h12) {
int h = ti->tm_hour % 12; if (h == 0) h = 12; int h = ti->tm_hour % 12; if (h == 0) h = 12;
@@ -774,16 +767,15 @@ public:
} }
} }
bool auto_adv = _node_prefs && _node_prefs->advert_auto_interval_sec > 0; bool auto_adv = _node_prefs && _node_prefs->advert_auto_interval_sec > 0;
#ifdef EINK_DISPLAY_MODEL if (Features::IS_EINK) {
if (_page == HomePage::CLOCK) return 30000; // no seconds on e-ink; refresh every 30s // slow display: poll every 30 s; inbound msgs force immediate refresh via notify()
return 30000; // e-ink: limit base polling; new messages still force immediate refresh via notify() return Features::HOME_REFRESH_MS;
#else }
if (_page == HomePage::CLOCK) { if (_page == HomePage::CLOCK) {
bool show_sec = !_node_prefs || !_node_prefs->clock_hide_seconds; bool show_sec = !_node_prefs || !_node_prefs->clock_hide_seconds;
return auto_adv ? 1000 : (show_sec ? 1000 : 60000); return auto_adv ? 1000 : (show_sec ? 1000 : 60000);
} }
return auto_adv ? 1000 : 5000; return auto_adv ? 1000 : 5000;
#endif
} }
bool handleInput(char c) override { bool handleInput(char c) override {
@@ -1478,11 +1470,7 @@ void UITask::loop() {
_display->setCursor(hx, hy); _display->setCursor(hx, hy);
_display->print(hint); _display->print(hint);
_display->endFrame(); _display->endFrame();
#ifdef EINK_DISPLAY_MODEL _next_refresh = millis() + Features::LOCKSCREEN_REFRESH_MS;
_next_refresh = millis() + 30000;
#else
_next_refresh = millis() + 1000;
#endif
} else if (!_locked && millis() >= _next_refresh && curr) { } else if (!_locked && millis() >= _next_refresh && curr) {
_display->startFrame(); _display->startFrame();
int delay_millis = curr->render(*_display); int delay_millis = curr->render(*_display);