aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConfuSomu2021-04-08 14:20:04 -0400
committerConfuSomu2021-04-08 14:20:04 -0400
commita8e8352f384ea90e722bbe7883b1e8965f655d5f (patch)
tree15e245270e1e05df48452540abccc85244107687
parentc4e404a01ea9460443155b5071e38e31129a134a (diff)
downloadpico-watch-a8e8352f384ea90e722bbe7883b1e8965f655d5f.tar
pico-watch-a8e8352f384ea90e722bbe7883b1e8965f655d5f.tar.gz
pico-watch-a8e8352f384ea90e722bbe7883b1e8965f655d5f.zip
Rewrite app_init to check for malloc/new failures
-rw-r--r--api.hpp6
-rw-r--r--pico-watch.cpp29
2 files changed, 29 insertions, 6 deletions
diff --git a/api.hpp b/api.hpp
index dbf3d43..1a6d33f 100644
--- a/api.hpp
+++ b/api.hpp
@@ -24,6 +24,10 @@ class Api {
void gui_popup_strchoice_footer(const char selection[]);
public:
bool m_send_button_press_to_app = true;
+ enum app_init_return_status {
+ OK = 0,
+ MALLOC_FAILED = 1
+ };
enum perf_modes {
LOW_POWER,
NORMAL_PERF,
@@ -95,7 +99,7 @@ class Api {
// FIXME: function currently does nothing!
// An app should choose the lowest performance that can make it function. Set in init(). Only when required, higher performance should be used.
// \param perf See Api::perf_modes enum for possible values
- bool performance_set(int perf);
+ bool performance_set(int perf_mode);
// Get the current datetime
// \param t Pointer to the datetime structure in which the datetime wil be stored
// \return true if the call to the SDK was successful, else false.
diff --git a/pico-watch.cpp b/pico-watch.cpp
index 88df2f2..e36c211 100644
--- a/pico-watch.cpp
+++ b/pico-watch.cpp
@@ -29,10 +29,31 @@ int APPS_IS_INIT[NUMBER_OF_APPS] = {0, 0}; // Only run in background if init
int app_init(int app_id) {
app_api.display_fill(0,1); // Clear OLED
app_api.performance_render_interval_set(500); // Reset interval
+
if (!APPS_IS_INIT[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 (*APPS_FUNC_INIT[app_id])(&app_api);
}
+ return app_id;
}
int app_render(int app_id) {
@@ -81,11 +102,9 @@ void app_switch(int old_appid, int new_appid) {
// FIXME: race condition when pressing on HOME while app is rendering!
// The system is blocked waiting for the app to finish rendering, which will never happen. To fix the problem, app switching has to be a flag (c.f struct) that is set, and checked before rendering app. "if (app_switching.requested) app_switch(...);" We will not need anymore the app_rendering flag, as the check is done while the app is not rendering.
while (app_rendering); // Wait for the app to finish rendering cycle
- if (APPS_DESTROY_ON_EXIT[old_appid]) {
+ if (APPS_DESTROY_ON_EXIT[old_appid])
app_destroy(old_appid);
- }
- app_init(new_appid);
- current_app = new_appid;
+ current_app = app_init(new_appid);
app_ready = true;
}