From 97498e131d4c43943d921101a78477bcdb4d09de Mon Sep 17 00:00:00 2001 From: pelgraine <140762863+pelgraine@users.noreply.github.com> Date: Sat, 2 May 2026 10:44:17 +1000 Subject: [PATCH] =?UTF-8?q?updated=20chunked=20save=20method=20so=20it=20d?= =?UTF-8?q?oesn't=20occur=20when=20device=20is=20actively=20being=20used.?= =?UTF-8?q?=20The=20flow:=20user=20navigates=20(keypresses=20every=20~200m?= =?UTF-8?q?s)=20=E2=86=92=20=5FlastUserInput=20stays=20fresh=20=E2=86=92?= =?UTF-8?q?=20userActive=20is=20true=20=E2=86=92=20save=20deferred.=20User?= =?UTF-8?q?=20stops=20navigating=20=E2=86=92=203=20seconds=20pass=20?= =?UTF-8?q?=E2=86=92=20userActive=20goes=20false=20=E2=86=92=20chunked=20s?= =?UTF-8?q?ave=20starts/resumes,=2020=20contacts=20per=20loop=20iteration?= =?UTF-8?q?=20until=20done.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/companion_radio/MyMesh.cpp | 15 +++++++++------ examples/companion_radio/MyMesh.h | 5 +++++ examples/companion_radio/main.cpp | 3 +++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 8cdf1406..90ca2c2d 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -114,6 +114,7 @@ #define DIRECT_SEND_PERHOP_FACTOR 6.0f #define DIRECT_SEND_PERHOP_EXTRA_MILLIS 250 #define LAZY_CONTACTS_WRITE_DELAY 5000 +#define USER_IDLE_SAVE_THRESHOLD 15000 // Defer saves until 15s after last keypress #define PUBLIC_GROUP_PSK "izOH6cXN6mrJ5e26oRXNcg==" @@ -3462,18 +3463,19 @@ void MyMesh::loop() { } // is there are pending dirty contacts write needed? + bool userActive = _lastUserInput && (millis() - _lastUserInput) < USER_IDLE_SAVE_THRESHOLD; if (dirty_contacts_expiry && millisHasNowPassed(dirty_contacts_expiry)) { #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM) // nRF52/STM32: blocking save (fast on internal flash, no chunking needed) - if (!_deferSaves) { + if (!_deferSaves && !userActive) { _store->saveContacts(this); dirty_contacts_expiry = 0; } else { dirty_contacts_expiry = futureMillis(2000); } #else - if (_deferSaves) { - // Voice session receiving — push save forward to avoid SPI contention + if (_deferSaves || userActive) { + // Voice session or active keyboard use -- push save forward dirty_contacts_expiry = futureMillis(2000); } else if (!_store->isSaveInProgress()) { _store->beginSaveContacts(this); @@ -3483,10 +3485,11 @@ void MyMesh::loop() { } #if !defined(NRF52_PLATFORM) && !defined(STM32_PLATFORM) - // Drive chunked contact save — write a batch each loop iteration - if (_store->isSaveInProgress() && !_deferSaves) { + // Drive chunked contact save -- write a batch each loop iteration + // Paused while user is actively pressing keys or voice session is receiving + if (_store->isSaveInProgress() && !_deferSaves && !userActive) { if (!_store->saveContactsChunk(20)) { // 20 contacts per chunk (~3KB, ~30ms) - _store->finishSaveContacts(); // Done or error — verify and commit + _store->finishSaveContacts(); // Done or error -- verify and commit } } #endif diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index a823e398..b95cfb11 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -160,6 +160,10 @@ public: void setDeferSaves(bool defer) { _deferSaves = defer; } bool isDeferSaves() const { return _deferSaves; } + // Notify that the user pressed a key — defers contact saves until idle. + // Call from main.cpp keyboard handler on every keypress. + void notifyUserInput() { _lastUserInput = millis(); } + // Repeater admin - UI-initiated operations bool uiLoginToRepeater(uint32_t contact_idx, const char* password, uint32_t& est_timeout_ms); bool uiSendCliCommand(uint32_t contact_idx, const char* command); @@ -274,6 +278,7 @@ private: VoiceEnvelopeHandler _voiceEnvHandler = nullptr; mutable bool _forceNextImport = false; bool _deferSaves = false; + unsigned long _lastUserInput = 0; // millis() of last keypress -- defer saves until idle uint32_t pending_login; uint32_t pending_status; uint32_t pending_telemetry, pending_discovery; // pending _TELEMETRY_REQ diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 9a073c15..d8bd365b 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -3619,6 +3619,9 @@ void handleKeyboardInput() { Serial.printf("handleKeyboardInput: key='%c' (0x%02X) composeMode=%d\n", key >= 32 ? key : '?', key, composeMode); + // Defer contact saves while user is actively pressing keys + the_mesh.notifyUserInput(); + // Alarm ringing: ANY key dismisses (highest priority after lock screen) #ifdef MECK_AUDIO_VARIANT {