From c8f3cbb0f93d07d6cde2393227a7ef193f8c062d Mon Sep 17 00:00:00 2001 From: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com> Date: Wed, 15 Oct 2025 03:06:59 -0400 Subject: [PATCH] Free Heap when not on Message screen --- src/MessageStore.cpp | 4 ++-- src/graphics/Screen.cpp | 20 +++++++++++++++++--- src/graphics/draw/MenuHandler.cpp | 4 +--- src/graphics/draw/MessageRenderer.cpp | 13 ++++++++++++- src/graphics/draw/MessageRenderer.h | 3 +++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/MessageStore.cpp b/src/MessageStore.cpp index 1e60fb646..0ad885448 100644 --- a/src/MessageStore.cpp +++ b/src/MessageStore.cpp @@ -251,7 +251,7 @@ void MessageStore::saveToFlash() void MessageStore::loadFromFlash() { - liveMessages.clear(); + std::deque().swap(liveMessages); resetMessagePool(); // reset pool when loading #ifdef FSCom @@ -289,7 +289,7 @@ void MessageStore::loadFromFlash() {} // Clear all messages (RAM + persisted queue) void MessageStore::clearAllMessages() { - liveMessages.clear(); + std::deque().swap(liveMessages); resetMessagePool(); #ifdef FSCom diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 4796e68c9..81c4805e2 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -715,6 +715,23 @@ int32_t Screen::runOnce() if (displayHeight == 0) { displayHeight = dispdev->getHeight(); } + + // Detect frame transitions and clear message cache when leaving text message screen + { + static int8_t lastFrameIndex = -1; + int8_t currentFrameIndex = ui->getUiState()->currentFrame; + int8_t textMsgIndex = framesetInfo.positions.textMessage; + + if (lastFrameIndex != -1 && currentFrameIndex != lastFrameIndex) { + + if (lastFrameIndex == textMsgIndex && currentFrameIndex != textMsgIndex) { + graphics::MessageRenderer::clearMessageCache(); + } + } + + lastFrameIndex = currentFrameIndex; + } + menuHandler::handleMenuSwitch(dispdev); // Show boot screen for first logo_timeout seconds, then switch to normal operation. @@ -1320,9 +1337,6 @@ void Screen::showFrame(FrameDirection direction) lastScreenTransition = millis(); setFastFramerate(); - - // Reset scroll state when switching away from text message screen - graphics::MessageRenderer::resetScrollState(); } } diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp index af42379cb..ea2107d27 100644 --- a/src/graphics/draw/MenuHandler.cpp +++ b/src/graphics/draw/MenuHandler.cpp @@ -481,6 +481,7 @@ void menuHandler::messageResponseMenu() } else if (selected == DismissAll) { messageStore.clearAllMessages(); graphics::MessageRenderer::clearThreadRegistries(); + graphics::MessageRenderer::clearMessageCache(); } else if (selected == DismissOldest) { auto mode = graphics::MessageRenderer::getThreadMode(); int ch = graphics::MessageRenderer::getThreadChannel(); @@ -919,9 +920,6 @@ void menuHandler::favoriteBaseMenu() graphics::MessageRenderer::setThreadMode(graphics::MessageRenderer::ThreadMode::DIRECT, -1, graphics::UIRenderer::currentFavoriteNodeNum); - // Reset scroll state for a fresh view - graphics::MessageRenderer::resetScrollState(); - // Manually create and send a UIFrameEvent to trigger the jump UIFrameEvent evt; evt.action = UIFrameEvent::Action::SWITCH_TO_TEXTMESSAGE; diff --git a/src/graphics/draw/MessageRenderer.cpp b/src/graphics/draw/MessageRenderer.cpp index 6317e8094..802343e84 100644 --- a/src/graphics/draw/MessageRenderer.cpp +++ b/src/graphics/draw/MessageRenderer.cpp @@ -209,8 +209,19 @@ void resetScrollState() scrollStartDelay = millis(); lastTime = millis(); - didReset = false; // <-- now valid + didReset = false; } + +// Fully free cached message data from heap +void clearMessageCache() +{ + std::vector().swap(cachedLines); + std::vector().swap(cachedHeights); + + // Reset scroll so we rebuild cleanly next time we enter the screen + resetScrollState(); +} + // Current thread state static ThreadMode currentMode = ThreadMode::ALL; static int currentChannel = -1; diff --git a/src/graphics/draw/MessageRenderer.h b/src/graphics/draw/MessageRenderer.h index 1bcd0e5da..4391519d9 100644 --- a/src/graphics/draw/MessageRenderer.h +++ b/src/graphics/draw/MessageRenderer.h @@ -60,6 +60,9 @@ void setThreadFor(const StoredMessage &sm, const meshtastic_MeshPacket &packet); // Handles a new incoming/outgoing message: banner, wake, thread select, scroll reset void handleNewMessage(const StoredMessage &sm, const meshtastic_MeshPacket &packet); +// Clear Message Line Cache from Message Renderer +void clearMessageCache(); + } // namespace MessageRenderer } // namespace graphics #endif \ No newline at end of file