diff options
author | ConfuSomu | 2021-06-25 21:01:57 -0400 |
---|---|---|
committer | ConfuSomu | 2021-06-25 21:01:57 -0400 |
commit | 6eb39240a6213ffd78d52ee8796e8e5a9723c44f (patch) | |
tree | 31dd96639e88f0601141c1c0281a1ae306da65f1 | |
parent | a2eac6cd3e29ea0db579cabd644a93996daaeeec (diff) | |
download | pico-watch-6eb39240a6213ffd78d52ee8796e8e5a9723c44f.tar pico-watch-6eb39240a6213ffd78d52ee8796e8e5a9723c44f.tar.gz pico-watch-6eb39240a6213ffd78d52ee8796e8e5a9723c44f.zip |
Move functions related to app lifecycle managment
They have been moved to a new file, to provide better encapulation.
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | app_manager.cpp | 106 | ||||
-rw-r--r-- | app_manager.hpp | 11 | ||||
-rw-r--r-- | apps/home_menu.cpp | 2 | ||||
-rw-r--r-- | base_app.hpp | 1 | ||||
-rw-r--r-- | buttons.cpp | 3 | ||||
-rw-r--r-- | pico-watch.cpp | 101 |
7 files changed, 122 insertions, 103 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b0cc8a..1cbc55d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ target_link_libraries(Oled pico_stdlib hardware_i2c) # Main code add_executable(pico-watch pico-watch.cpp + app_manager.cpp init.cpp init.hpp buttons.cpp diff --git a/app_manager.cpp b/app_manager.cpp new file mode 100644 index 0000000..3132efd --- /dev/null +++ b/app_manager.cpp @@ -0,0 +1,106 @@ +#include "app_manager.hpp" +#include "api.hpp" +#include "apps/main_clock.hpp" +#include "apps/home_menu.hpp" +#include "apps/settings/main.hpp" + +#define NUMBER_OF_APPS 3 +// From pico-watch.c: +extern Api app_api; + +std::vector<BaseApp*> open_apps; +int APPS_DESTROY_ON_EXIT[NUMBER_OF_APPS] = {0, 1, 1}; +int APPS_IS_INIT[NUMBER_OF_APPS] = {0}; // Only run in background if init + +// Called by app_init to create the app object. +int app_create(int app_id) { + switch (app_id) { + case 0: open_apps.push_back(new app_home_menu(&app_api)); break; + default: __breakpoint(); + } +} + +// Init a new app, that is not running. +int app_init(int app_id) { + app_api.display_fill(0,1); // Clear OLED + app_api.performance_render_interval_set(500); // Reset interval + + if (app_id > NUMBER_OF_APPS-1 or app_id < 0) { + printf("Tried to init app %d", app_id); + return app_init(0); + } + + if (!APPS_IS_INIT[app_id]) { + app_create(app_id); + /* int status = (*APPS_FUNC_INIT[app_id])(&app_api); + + switch (status) { + case Api::app_init_return_status::MALLOC_FAILED: + printf("App init failed (alloc), "); + for (int i=0; i<10; i++) { + if ((*APPS_FUNC_INIT[app_id])(&app_api) != Api::app_init_return_status::MALLOC_FAILED) { + printf("worked after %d tries\n", i); + APPS_IS_INIT[app_id] = 1; + return app_id; + } + } + // Instead, the current app could continue running: return current_app + printf("gave up, launching app 0\n"); + return app_init(0); // Note: this has to work (and should) + + default: // OK and unhandled status codes + printf("App init, status: %d\n", status); + break; + } */ + APPS_IS_INIT[app_id] = 1; + } + return app_id; +} + +// Allow the running app, referenced by app_id, to invoke its render routine. +int app_render(int app_id) { + for (auto app : open_apps) { + if (app_id == app->app_id) + return app->render(&app_api); + } +} + +// Delta is in ms, from time_since_button_press() +int app_btnpressed(int app_id, uint gpio, unsigned long delta) { + for (auto app : open_apps) { + if (app_id == app->app_id) + return app->btnpressed(&app_api, gpio, delta); + } +} + +// Quit the app referenced by the app_id. +int app_destroy(int app_id) { + BaseApp* to_destroy; + + for (auto app : open_apps) { + if (app_id == app->app_id) + to_destroy = app; + } + delete to_destroy; + // FIXME: Remove app from list + //open_apps.erase(std::remove(open_apps.begin(), open_apps.end(), to_destroy), open_apps.end()); // See https://stackoverflow.com/a/27306171/15578170 + + APPS_IS_INIT[app_id] = 0; + return 0; +} + +// Requests the current app to be replaced by an other one. The replacement will be done at the right moment. +void app_switch_request(int to_appid) { + if (!g_s.app_switch_requested) + g_s.app_switch_to_app = to_appid; + g_s.app_switch_requested = true; + app_api.performance_render_interval_set(0); // This will be reset on new app init +} + +void app_switch(int old_appid, int new_appid) { + g_s.app_ready = false; + if (APPS_DESTROY_ON_EXIT[old_appid]) + app_destroy(old_appid); + g_s.current_app = app_init(new_appid); + g_s.app_ready = true; +} diff --git a/app_manager.hpp b/app_manager.hpp new file mode 100644 index 0000000..6517ce9 --- /dev/null +++ b/app_manager.hpp @@ -0,0 +1,11 @@ +#pragma once +#include <vector> +#include "base_app.hpp" + +extern std::vector<BaseApp*> open_apps; + +int app_init(int app_id); +int app_render(int app_id); +int app_btnpressed(int app_id, uint gpio, unsigned long delta); +void app_switch(int old_appid, int new_appid); +void app_switch_request(int to_appid); diff --git a/apps/home_menu.cpp b/apps/home_menu.cpp index a450c8f..4761c46 100644 --- a/apps/home_menu.cpp +++ b/apps/home_menu.cpp @@ -40,7 +40,7 @@ int app_home_menu::render(Api *app_api) { int app_home_menu::btnpressed(Api *app_api, uint gpio, unsigned long delta) { switch (gpio) { case BUTTON_SELECT: - app_switch(0, selected_app); + app_switch(0, selected_app); // FIXME: Should call app_switch_request instead return 0; case BUTTON_DOWN: selected_app--; diff --git a/base_app.hpp b/base_app.hpp index 0950a01..58aeb2f 100644 --- a/base_app.hpp +++ b/base_app.hpp @@ -1,4 +1,5 @@ #pragma once +#include "api.hpp" // Base app class BaseApp { diff --git a/buttons.cpp b/buttons.cpp index 7aa82e8..df2beef 100644 --- a/buttons.cpp +++ b/buttons.cpp @@ -3,9 +3,8 @@ #include "buttons.hpp" #include "api.hpp" +#include "app_manager.hpp" // From pico-watch.c: -extern int app_btnpressed(int app_id, uint gpio, unsigned long delta); -extern void app_switch_request(int); extern Api app_api; //const uint BUTTON_PINS[] = {BUTTON_HOME, BUTTON_SELECT, BUTTON_MODE, BUTTON_UP, BUTTON_DOWN}; diff --git a/pico-watch.cpp b/pico-watch.cpp index 7ce2f98..05ee208 100644 --- a/pico-watch.cpp +++ b/pico-watch.cpp @@ -1,5 +1,4 @@ #include <stdio.h> -#include <vector> #include "pico/stdlib.h" #include "hardware/i2c.h" #include "hardware/sync.h" @@ -9,95 +8,12 @@ #include "init.hpp" #include "api.hpp" #include "buttons.hpp" -#include "base_app.hpp" -#include "apps/main_clock.hpp" -#include "apps/home_menu.hpp" -#include "apps/settings/main.hpp" +#include "app_manager.hpp" global_status g_s; user_settings g_user; Api app_api; -#define NUMBER_OF_APPS 3 - -std::vector<BaseApp*> open_apps; - -int APPS_DESTROY_ON_EXIT[NUMBER_OF_APPS] = {0, 1, 1}; -int APPS_IS_INIT[NUMBER_OF_APPS] = {0}; // Only run in background if init - -int app_create(int app_id) { - switch (app_id) { - case 0: open_apps.push_back(new app_home_menu(&app_api)); break; - default: __breakpoint(); - } -} - -int app_init(int app_id) { - app_api.display_fill(0,1); // Clear OLED - app_api.performance_render_interval_set(500); // Reset interval - - if (app_id > NUMBER_OF_APPS-1 or app_id < 0) { - printf("Tried to init app %d", app_id); - return app_init(0); - } - - if (!APPS_IS_INIT[app_id]) { - app_create(app_id); - /* int status = (*APPS_FUNC_INIT[app_id])(&app_api); - - switch (status) { - case Api::app_init_return_status::MALLOC_FAILED: - printf("App init failed (alloc), "); - for (int i=0; i<10; i++) { - if ((*APPS_FUNC_INIT[app_id])(&app_api) != Api::app_init_return_status::MALLOC_FAILED) { - printf("worked after %d tries\n", i); - APPS_IS_INIT[app_id] = 1; - return app_id; - } - } - // Instead, the current app could continue running: return current_app - printf("gave up, launching app 0\n"); - return app_init(0); // Note: this has to work (and should) - - default: // OK and unhandled status codes - printf("App init, status: %d\n", status); - break; - } */ - APPS_IS_INIT[app_id] = 1; - } - return app_id; -} - -int app_render(int app_id) { - for (auto app : open_apps) { - if (app_id == app->app_id) - return app->render(&app_api); - } -} - -// Delta is in ms, from time_since_button_press() -int app_btnpressed(int app_id, uint gpio, unsigned long delta) { - for (auto app : open_apps) { - if (app_id == app->app_id) - return app->btnpressed(&app_api, gpio, delta); - } -} - -int app_destroy(int app_id) { - BaseApp* to_destroy; - - for (auto app : open_apps) { - if (app_id == app->app_id) - to_destroy = app; - } - delete to_destroy; - // FIXME: Remove app from list - //open_apps.erase(std::remove(open_apps.begin(), open_apps.end(), to_destroy), open_apps.end()); // See https://stackoverflow.com/a/27306171/15578170 - - APPS_IS_INIT[app_id] = 0; - return 0; -} - bool repeating_callback(struct repeating_timer *t) { // Enter shallow sleep mode when needed auto time_since_last_press = time_since_button_press(); @@ -119,21 +35,6 @@ bool repeating_callback(struct repeating_timer *t) { return true; } -void app_switch_request(int to_appid) { - if (!g_s.app_switch_requested) - g_s.app_switch_to_app = to_appid; - g_s.app_switch_requested = true; - app_api.performance_render_interval_set(0); // This will be reset on new app init -} - -void app_switch(int old_appid, int new_appid) { - g_s.app_ready = false; - if (APPS_DESTROY_ON_EXIT[old_appid]) - app_destroy(old_appid); - g_s.current_app = app_init(new_appid); - g_s.app_ready = true; -} - int main() { init_all(); printf("~~~==~~~"); |