aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConfuSomu2021-06-25 21:01:57 -0400
committerConfuSomu2021-06-25 21:01:57 -0400
commit6eb39240a6213ffd78d52ee8796e8e5a9723c44f (patch)
tree31dd96639e88f0601141c1c0281a1ae306da65f1
parenta2eac6cd3e29ea0db579cabd644a93996daaeeec (diff)
downloadpico-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.txt1
-rw-r--r--app_manager.cpp106
-rw-r--r--app_manager.hpp11
-rw-r--r--apps/home_menu.cpp2
-rw-r--r--base_app.hpp1
-rw-r--r--buttons.cpp3
-rw-r--r--pico-watch.cpp101
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("~~~==~~~");