diff options
Diffstat (limited to 'app_manager.cpp')
-rw-r--r-- | app_manager.cpp | 109 |
1 files changed, 50 insertions, 59 deletions
diff --git a/app_manager.cpp b/app_manager.cpp index 2926921..bd71c6a 100644 --- a/app_manager.cpp +++ b/app_manager.cpp @@ -1,7 +1,10 @@ +#include <algorithm> + #include "app_manager.hpp" #include "api.hpp" -#include "apps/main_clock.hpp" -#include "apps/home_menu.hpp" +#include "globals.hpp" +#include "apps/main_clock/main.hpp" +#include "apps/home_menu/main.hpp" #include "apps/settings/main.hpp" #define NUMBER_OF_APPS 3 @@ -10,18 +13,32 @@ 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 + +// Check if the specified app (via app_id) is already running. +// \return If app is init, pointer to app, else nullptr (more or less 0). +BaseApp* app_check_if_init(int app_id) { + for (auto app : open_apps) { + if (app_id == app->app_id) + return app; + } + return nullptr; +} // Called by app_init to create the app object. -int app_create(int app_id) { +BaseApp* app_create(int app_id) { switch (app_id) { case 0: open_apps.push_back(new app_home_menu(&app_api)); break; - default: __breakpoint(); + case 1: open_apps.push_back(new app_main_clock(&app_api)); break; + default: __breakpoint(); return open_apps.front(); // Should be home_menu } + // TODO: Check when new fails + + return open_apps.back(); } // Init a new app, that is not running. -int app_init(int app_id) { +BaseApp* app_init(int app_id) { + BaseApp* new_app; app_api.display_fill(0,1); // Clear OLED app_api.performance_render_interval_set(500); // Reset interval @@ -30,66 +47,34 @@ int app_init(int 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; + auto app_ptr = app_check_if_init(app_id); + if (app_ptr) + new_app = app_ptr; + else + new_app = app_create(app_id); + + return new_app; } // 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); - } +int app_render(BaseApp* app) { + 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_btnpressed(BaseApp* app, uint gpio, unsigned long delta) { + return app->btnpressed(&app_api, gpio, delta); } // Quit the app referenced by the app_id. -int app_destroy(int app_id) { - BaseApp* to_destroy; - - // FIXME: Does not work if the app is not open. An invalid item tries to get freed. - int to_delete_id = 0; - for (auto app : open_apps) { - if (app_id == app->app_id) { - to_destroy = app; - break; - } - to_delete_id++; +int app_destroy(BaseApp* to_erase) { + auto erase_it = std::find(open_apps.begin(), open_apps.end(), to_erase); // "it" meaning iterator + if (erase_it != open_apps.end()) { + //assert(to_erase == erase_it); + delete to_erase; + open_apps.erase(erase_it); } - delete to_destroy; - open_apps.erase(open_apps.begin() + to_delete_id); - APPS_IS_INIT[app_id] = 0; return 0; } @@ -101,10 +86,16 @@ void app_switch_request(int to_appid) { app_api.performance_render_interval_set(0); // This will be reset on new app init } -void app_switch(int old_appid, int new_appid) { +void app_switch(BaseApp* app, 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); + if (app->app_destroy_on_exit) + app_destroy(app); + + auto app_ptr = app_check_if_init(new_appid); + if (app_ptr) + g_s.current_app = app_ptr; + else + g_s.current_app = app_init(new_appid); + g_s.app_ready = true; } |