Something went wrong. Try again.
A fork of https://github.com/crosspoint-reader/crosspoint-reader
Something went wrong. Try again.
4.1 kB · 112 lines
C
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113#pragma once
#include <freertos/FreeRTOS.h>#include <freertos/semphr.h>#include <freertos/task.h>
#include <cassert>#include <memory>#include <string>#include <vector>
#include "GfxRenderer.h"#include "MappedInputManager.h"
class Activity; // forward declarationclass RenderLock; // forward declaration
/** * ActivityManager * * This mirrors the same concept of Activity in Android, where an activity represents a single screen of the UI. The * manager is responsible for launching activities, and ensuring that only one activity is active at a time. * * It also provides a stack mechanism to allow activities to launch sub-activities and get back the results when the * sub-activity is done. For example, the WebServer activity can launch a WifiSelect activity to let the user choose a * wifi network, and get back the selected network when the user is done. * * Main differences from Android's ActivityManager: * - No onPause/onResume, since we don't have a concept of background activities * - onActivityResult is implemented via a callback instead of a separate method, for simplicity */class ActivityManager { friend class RenderLock;
protected: GfxRenderer& renderer; MappedInputManager& mappedInput; std::vector<std::unique_ptr<Activity>> stackActivities; std::unique_ptr<Activity> currentActivity;
void exitActivity(const RenderLock& lock);
// Pending activity to be launched on next loop iteration std::unique_ptr<Activity> pendingActivity; enum class PendingAction { None, Push, Pop, Replace }; PendingAction pendingAction = PendingAction::None;
// Task to render and display the activity TaskHandle_t renderTaskHandle = nullptr; static void renderTaskTrampoline(void* param); [[noreturn]] virtual void renderTaskLoop();
// Set by requestUpdateAndWait(); read and cleared by the render task after render completes. // Note: only one waiting task is supported at a time TaskHandle_t waitingTaskHandle = nullptr;
// 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;
public: explicit ActivityManager(GfxRenderer& renderer, MappedInputManager& mappedInput) : renderer(renderer), mappedInput(mappedInput), renderingMutex(xSemaphoreCreateMutex()) { assert(renderingMutex != nullptr && "Failed to create rendering mutex"); stackActivities.reserve(10); } ~ActivityManager() { assert(false); /* should never be called */ };
void begin(); void loop();
// Will replace currentActivity and drop all activities on stack void replaceActivity(std::unique_ptr<Activity>&& newActivity);
// goTo... functions are convenient wrapper for replaceActivity() void goToFileTransfer(); void goToSettings(); void goToFileBrowser(std::string path = {}); void goToRecentBooks(); void goToBrowser(); void goToReader(std::string path); void goToSleep(); void goToBoot(); void goToFullScreenMessage(std::string message, EpdFontFamily::Style style = EpdFontFamily::REGULAR); void goToCrashReport(); void goHome();
// This will move current activity to stack instead of deleting it void pushActivity(std::unique_ptr<Activity>&& activity);
// Remove the currentActivity, returning the last one on stack // Note: if popActivity() on last activity on the stack, we will goHome() void popActivity();
bool preventAutoSleep() const; bool isReaderActivity() const; bool skipLoopDelay() const;
// If immediate is true, the update will be triggered immediately. // Otherwise, it will be deferred until the end of the current loop iteration. void requestUpdate(bool immediate = false);
// Trigger a render and block until it completes. // Must NOT be called from the render task or while holding a RenderLock. void requestUpdateAndWait();};
extern ActivityManager activityManager; // singleton, to be defined in main.cpp