mirror of
https://github.com/pelgraine/Meck.git
synced 2026-05-03 03:52:39 +02:00
updated chunked save method so it doesn't occur when device is actively being used. The flow: user navigates (keypresses every ~200ms) → _lastUserInput stays fresh → userActive is true → save deferred. User stops navigating → 3 seconds pass → userActive goes false → chunked save starts/resumes, 20 contacts per loop iteration until done.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user