diff --git a/src/activities/Activity.h b/src/activities/Activity.h index 0d890d97..cc3fe443 100644 --- a/src/activities/Activity.h +++ b/src/activities/Activity.h @@ -13,15 +13,17 @@ #include "RenderLock.h" class Activity { + friend class ActivityManager; + protected: std::string name; GfxRenderer& renderer; MappedInputManager& mappedInput; - public: ActivityResultHandler resultHandler; ActivityResult result; + public: explicit Activity(std::string name, GfxRenderer& renderer, MappedInputManager& mappedInput) : name(std::move(name)), renderer(renderer), mappedInput(mappedInput) {} virtual ~Activity() = default; diff --git a/src/activities/ActivityManager.cpp b/src/activities/ActivityManager.cpp index 52c506d7..cf14a5c8 100644 --- a/src/activities/ActivityManager.cpp +++ b/src/activities/ActivityManager.cpp @@ -232,7 +232,7 @@ RenderLock::RenderLock() { isLocked = true; } -RenderLock::RenderLock(Activity& /* unused */) { +RenderLock::RenderLock([[maybe_unused]] Activity&) { xSemaphoreTake(activityManager.renderingMutex, portMAX_DELAY); isLocked = true; } diff --git a/src/activities/ActivityManager.h b/src/activities/ActivityManager.h index 698b9a7a..bd206730 100644 --- a/src/activities/ActivityManager.h +++ b/src/activities/ActivityManager.h @@ -11,7 +11,6 @@ #include "GfxRenderer.h" #include "MappedInputManager.h" -#include "RenderLock.h" class Activity; // forward declaration class RenderLock; // forward declaration @@ -31,6 +30,8 @@ class RenderLock; // forward declaration * - onActivityResult is implemented via a callback instead of a separate method, for simplicity */ class ActivityManager { + friend class RenderLock; + protected: GfxRenderer& renderer; MappedInputManager& mappedInput; @@ -49,6 +50,10 @@ class ActivityManager { static void renderTaskTrampoline(void* param); [[noreturn]] virtual void renderTaskLoop(); + // Mutex to protect rendering operations from race conditions + // Must only be used via RenderLock + SemaphoreHandle_t renderingMutex = nullptr; + // Whether to trigger a render after the current loop() // This variable must only be set by the main loop, to avoid race conditions bool requestedUpdate = false; @@ -61,10 +66,6 @@ class ActivityManager { } ~ActivityManager() { assert(false); /* should never be called */ }; - // Mutex to protect rendering operations from race conditions - // Must only be used via RenderLock - SemaphoreHandle_t renderingMutex = nullptr; - void begin(); void loop(); diff --git a/src/activities/browser/OpdsBookBrowserActivity.cpp b/src/activities/browser/OpdsBookBrowserActivity.cpp index 62aeab38..5b43da4c 100644 --- a/src/activities/browser/OpdsBookBrowserActivity.cpp +++ b/src/activities/browser/OpdsBookBrowserActivity.cpp @@ -383,5 +383,6 @@ void OpdsBookBrowserActivity::onWifiSelectionComplete(const bool connected) { WiFi.mode(WIFI_OFF); state = BrowserState::ERROR; errorMessage = tr(STR_WIFI_CONN_FAILED); + requestUpdate(); } } diff --git a/src/activities/network/CalibreConnectActivity.cpp b/src/activities/network/CalibreConnectActivity.cpp index 4933178a..a42ab16e 100644 --- a/src/activities/network/CalibreConnectActivity.cpp +++ b/src/activities/network/CalibreConnectActivity.cpp @@ -63,7 +63,7 @@ void CalibreConnectActivity::onExit() { void CalibreConnectActivity::onWifiSelectionComplete(const bool connected) { if (!connected) { - activityManager.popActivity(); + finish(); return; } @@ -162,7 +162,7 @@ void CalibreConnectActivity::loop() { } if (exitRequested) { - activityManager.popActivity(); + finish(); return; } } diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index cc0a100b..b99cd07e 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -320,6 +320,7 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction std::make_unique(renderer, mappedInput, epub, path, spineIdx), [this](const ActivityResult& result) { if (!result.isCancelled && currentSpineIndex != std::get(result.data).spineIndex) { + RenderLock lock(*this); currentSpineIndex = std::get(result.data).spineIndex; nextPageNumber = 0; section.reset(); @@ -421,6 +422,7 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction if (!result.isCancelled) { const auto& sync = std::get(result.data); if (currentSpineIndex != sync.spineIndex || (section && section->currentPage != sync.page)) { + RenderLock lock(*this); currentSpineIndex = sync.spineIndex; nextPageNumber = sync.page; section.reset(); diff --git a/src/activities/settings/CalibreSettingsActivity.cpp b/src/activities/settings/CalibreSettingsActivity.cpp index 7cd6ac1b..8fcf9aba 100644 --- a/src/activities/settings/CalibreSettingsActivity.cpp +++ b/src/activities/settings/CalibreSettingsActivity.cpp @@ -27,7 +27,7 @@ void CalibreSettingsActivity::onExit() { Activity::onExit(); } void CalibreSettingsActivity::loop() { if (mappedInput.wasPressed(MappedInputManager::Button::Back)) { - activityManager.popActivity(); + finish(); return; } diff --git a/src/activities/settings/KOReaderSettingsActivity.cpp b/src/activities/settings/KOReaderSettingsActivity.cpp index b84076f2..7291c8c1 100644 --- a/src/activities/settings/KOReaderSettingsActivity.cpp +++ b/src/activities/settings/KOReaderSettingsActivity.cpp @@ -29,7 +29,7 @@ void KOReaderSettingsActivity::onExit() { Activity::onExit(); } void KOReaderSettingsActivity::loop() { if (mappedInput.wasPressed(MappedInputManager::Button::Back)) { - activityManager.popActivity(); + finish(); return; } diff --git a/src/activities/settings/OtaUpdateActivity.cpp b/src/activities/settings/OtaUpdateActivity.cpp index 8009adb3..c661a618 100644 --- a/src/activities/settings/OtaUpdateActivity.cpp +++ b/src/activities/settings/OtaUpdateActivity.cpp @@ -13,7 +13,7 @@ void OtaUpdateActivity::onWifiSelectionComplete(const bool success) { if (!success) { LOG_ERR("OTA", "WiFi connection failed, exiting"); - activityManager.popActivity(); + finish(); return; } @@ -172,7 +172,7 @@ void OtaUpdateActivity::loop() { } if (mappedInput.wasPressed(MappedInputManager::Button::Back)) { - activityManager.popActivity(); + finish(); } return; @@ -180,14 +180,14 @@ void OtaUpdateActivity::loop() { if (state == FAILED) { if (mappedInput.wasPressed(MappedInputManager::Button::Back)) { - activityManager.popActivity(); + finish(); } return; } if (state == NO_UPDATE) { if (mappedInput.wasPressed(MappedInputManager::Button::Back)) { - activityManager.popActivity(); + finish(); } return; }