diff options
-rw-r--r-- | buttons.cpp | 4 | ||||
-rw-r--r-- | buttons.hpp | 3 | ||||
-rw-r--r-- | pico-watch.cpp | 18 |
3 files changed, 17 insertions, 8 deletions
diff --git a/buttons.cpp b/buttons.cpp index c919562..15e0ff7 100644 --- a/buttons.cpp +++ b/buttons.cpp @@ -5,7 +5,7 @@ #include "api.hpp" // From pico-watch.c: extern int app_btnpressed(int app_id, uint gpio); -extern void app_switch(int old_appid, int new_appid); +extern void app_switch_request(int); extern Api app_api; //const uint BUTTON_PINS[] = {BUTTON_HOME, BUTTON_SELECT, BUTTON_MODE, BUTTON_UP, BUTTON_DOWN}; @@ -15,7 +15,7 @@ void gpio_interrupt_cb(uint gpio, uint32_t events) { if (app_api.m_interpret_button_press) { if (gpio == BUTTON_HOME && (g_s.current_app != 0)) // Home app - app_switch(g_s.current_app, 0); + app_switch_request(0); else app_btnpressed(g_s.current_app, gpio); } diff --git a/buttons.hpp b/buttons.hpp index b8ecbc3..fa05e4e 100644 --- a/buttons.hpp +++ b/buttons.hpp @@ -16,7 +16,8 @@ struct global_status { int current_app = 0; bool is_sleeping = false; bool app_ready = true; - bool app_rendering = false; + bool app_switch_requested = false; + int app_switch_to_app = 0; // Debounce control // See https://www.raspberrypi.org/forums/viewtopic.php?f=145&t=301522#p1812063 diff --git a/pico-watch.cpp b/pico-watch.cpp index f3b8e4a..d593d45 100644 --- a/pico-watch.cpp +++ b/pico-watch.cpp @@ -98,11 +98,15 @@ 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; - // 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 (g_s.app_rendering); // Wait for the app to finish rendering cycle if (APPS_DESTROY_ON_EXIT[old_appid]) app_destroy(old_appid); g_s.current_app = app_init(new_appid); @@ -120,12 +124,16 @@ int main() { app_init(g_s.current_app); while (1) { + if (g_s.app_switch_requested) { + app_switch(g_s.current_app, g_s.app_switch_to_app); + g_s.app_switch_requested = false; + } + if (g_s.app_ready && !g_s.is_sleeping) { - g_s.app_rendering = true; app_render(g_s.current_app); app_api.display_write_backbuffer(); - g_s.app_rendering = false; } + if (g_s.is_sleeping) __wfi(); else sleep_ms(app_api.performance_render_interval_get()); } |