diff options
-rw-r--r-- | api.hpp | 6 | ||||
-rw-r--r-- | app_manager.cpp | 60 | ||||
-rw-r--r-- | app_manager.hpp | 10 | ||||
-rw-r--r-- | apps/home_menu/main.cpp | 14 | ||||
-rw-r--r-- | apps/home_menu/main.hpp | 6 | ||||
-rw-r--r-- | apps/main_clock/main.cpp | 22 | ||||
-rw-r--r-- | apps/main_clock/main.hpp | 8 | ||||
-rw-r--r-- | apps/settings/main.cpp | 12 | ||||
-rw-r--r-- | apps/settings/main.hpp | 6 | ||||
-rw-r--r-- | base_app.hpp | 12 |
10 files changed, 108 insertions, 48 deletions
@@ -22,12 +22,8 @@ class Api { void gui_popup_intchoice_footer(int current_num, int min_num, int max_num); void gui_popup_strchoice_footer(const char selection[]); public: - // Allow button press to be registed by app and for app_switch (when HOME). Set to false for in Api internal gui. + // Allow button press to be registed by app and for app_switch (when HOME). Set to false when displaying Api's internal GUI. bool m_interpret_button_press = true; - enum app_init_return_status { - OK = 0, - MALLOC_FAILED = 1 - }; enum perf_modes { LOW_POWER, NORMAL_PERF, diff --git a/app_manager.cpp b/app_manager.cpp index 34d4b32..db35037 100644 --- a/app_manager.cpp +++ b/app_manager.cpp @@ -23,6 +23,25 @@ BaseApp* app_mgr::app_check_if_init(int app_id) { return nullptr; } +void app_mgr::app_act_on_return_value(BaseApp* app, BaseApp::AppReturnValues return_value) { + switch (return_value) { + case BaseApp::AppReturnValues::OK: + break; + + case BaseApp::AppReturnValues::CLOSE: + g_s.foreground_app = open_apps.front(); // The app has to be in foreground as the current function is called by app_render and app_btnpress + break; + + case BaseApp::AppReturnValues::QUIT: + app_destroy(app); + g_s.foreground_app = open_apps.front(); + break; + + default: + printf("Unidentified return value %d for app %d at %x", return_value, app->app_get_attributes().id, app); + } +} + BaseApp* app_mgr::app_create(int app_id) { BaseApp* new_app; @@ -63,28 +82,53 @@ BaseApp* app_mgr::app_init(int app_id) { return new_app; } -int app_mgr::app_render(BaseApp* app) { - return app->render(&app_api); +void app_mgr::app_render(BaseApp* app) { + app_act_on_return_value(app, app->render(&app_api)); } -int app_mgr::app_btnpressed(BaseApp* app, uint gpio, unsigned long delta) { - return app->btnpressed(&app_api, gpio, delta); +void app_mgr::app_btnpressed(BaseApp* app, uint gpio, unsigned long delta) { + app_act_on_return_value(app, app->btnpressed(&app_api, gpio, delta)); } -int app_mgr::app_destroy(BaseApp* to_erase) { +void app_mgr::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); } - - return 0; } void app_mgr::app_all_bgrefresh() { + std::vector<BaseApp*> to_erase; + bool do_erase = false; + for (auto app : open_apps) { - app->bgrefresh(&app_api, app->app_get_attributes().id == g_s.foreground_app->app_get_attributes().id); + bool is_foreground = app->app_get_attributes().id == g_s.foreground_app->app_get_attributes().id; + + switch (app->bgrefresh(&app_api, is_foreground)) { + case BaseApp::AppReturnValues::OK: + break; + + case BaseApp::AppReturnValues::QUIT: + do_erase = true; + to_erase.push_back(app); + // No break here! + + case BaseApp::AppReturnValues::CLOSE: + if (is_foreground) + g_s.foreground_app = open_apps.front(); + break; + + default: + printf("Unidentified return value in bgrefresh for app %d at %x", app->app_get_attributes().id, app); + } + } + + if (do_erase) { + for (auto app : to_erase) { + app_destroy(app); + } } } diff --git a/app_manager.hpp b/app_manager.hpp index 3657d93..8dfbb88 100644 --- a/app_manager.hpp +++ b/app_manager.hpp @@ -11,10 +11,10 @@ namespace app_mgr { BaseApp* app_init(int app_id); // Allow the running app, referenced by app_id, to invoke its render routine. - int app_render(BaseApp* app); + void app_render(BaseApp* app); // Delta is in ms, from time_since_button_press() - int app_btnpressed(BaseApp* app, uint gpio, unsigned long delta); + void app_btnpressed(BaseApp* app, uint gpio, unsigned long delta); // This should only be called by pico-watch.cpp before app rendering, to chage the current app. void app_switch(BaseApp* app, int new_appid); @@ -26,13 +26,17 @@ namespace app_mgr { void app_all_bgrefresh(); // Private functions following. I tried using anonymous namespaces but it was too complicated. I might come back to this later. Just don't use the following internal functions. + // 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); + // Check the return value of the called application method and act on it. + void app_act_on_return_value(BaseApp* app, BaseApp::AppReturnValues return_value); + // Called by app_init to create the app object. BaseApp* app_create(int app_id); // Quit the app referenced by the app_id. - int app_destroy(BaseApp* to_erase); + void app_destroy(BaseApp* to_erase); } diff --git a/apps/home_menu/main.cpp b/apps/home_menu/main.cpp index ff8ae4d..4508e38 100644 --- a/apps/home_menu/main.cpp +++ b/apps/home_menu/main.cpp @@ -28,19 +28,19 @@ void app_home_menu::show_title(Api *app_api) { } // Rendering of app -int app_home_menu::render(Api *app_api) { +BaseApp::AppReturnValues app_home_menu::render(Api *app_api) { show_title(app_api); app_api->display_write_string(0,5,3, display_app_name, FONT_12x16, 0, 1); - return 0; + return AppReturnValues::OK; } // Example of how button inputs could be interpreted. // Drawing on screen should be done in the render function. -int app_home_menu::btnpressed(Api *app_api, uint gpio, unsigned long delta) { +BaseApp::AppReturnValues app_home_menu::btnpressed(Api *app_api, uint gpio, unsigned long delta) { switch (gpio) { case BUTTON_SELECT: app_mgr::app_switch_request(selected_app); - return 0; + return AppReturnValues::OK; case BUTTON_DOWN: selected_app--; break; @@ -55,7 +55,7 @@ int app_home_menu::btnpressed(Api *app_api, uint gpio, unsigned long delta) { } // Add spaces to avoid "ghost" characters from app names displayed before snprintf(display_app_name, SIZE_APP_NAME, "%s ", APPS_NAME[selected_app]); - return 0; + return AppReturnValues::OK; } // Initlisation of the app. @@ -66,6 +66,6 @@ app_home_menu::app_home_menu(Api *app_api) { } // Processor intensive operations and functions related to drawing to the screen should only be done when the app is in_foreground(=1). This function is only called when the app is init. -int app_home_menu::bgrefresh(Api *app_api, bool in_foreground) { - return 1; +BaseApp::AppReturnValues app_home_menu::bgrefresh(Api *app_api, bool in_foreground) { + return AppReturnValues::OK; } diff --git a/apps/home_menu/main.hpp b/apps/home_menu/main.hpp index 155009b..d82e2a0 100644 --- a/apps/home_menu/main.hpp +++ b/apps/home_menu/main.hpp @@ -24,8 +24,8 @@ class app_home_menu : public BaseApp { } app_home_menu(Api *app_api); - int render(Api *app_api); - int btnpressed(Api *app_api, uint gpio, unsigned long delta); - int bgrefresh(Api *app_api, bool in_foreground); + AppReturnValues render(Api *app_api); + AppReturnValues btnpressed(Api *app_api, uint gpio, unsigned long delta); + AppReturnValues bgrefresh(Api *app_api, bool in_foreground); ~app_home_menu(); }; diff --git a/apps/main_clock/main.cpp b/apps/main_clock/main.cpp index 78be6fd..73a3103 100644 --- a/apps/main_clock/main.cpp +++ b/apps/main_clock/main.cpp @@ -52,7 +52,7 @@ void app_main_clock::show_datetime(Api *app_api) { } // Rendering of the app -int app_main_clock::render(Api *app_api) { +BaseApp::AppReturnValues app_main_clock::render(Api *app_api) { app_api->gui_header_text("Test clock", 17); show_datetime(app_api); if (*ask_user_choice) { @@ -60,14 +60,20 @@ int app_main_clock::render(Api *app_api) { *ask_user_choice = false; } app_api->gui_footer_text(choices[*user_choice],0,1); - return 0; + + if (*user_choice == 1) + return AppReturnValues::CLOSE; + else if (*user_choice == 2) + return AppReturnValues::QUIT; + + return AppReturnValues::OK; } // Interpretation of button inputs -int app_main_clock::btnpressed(Api *app_api, uint gpio, unsigned long delta) { +BaseApp::AppReturnValues app_main_clock::btnpressed(Api *app_api, uint gpio, unsigned long delta) { if (gpio == BUTTON_MODE) *ask_user_choice = true; - return 0; + return AppReturnValues::OK; } // Initlisation of the app. @@ -82,8 +88,12 @@ app_main_clock::app_main_clock(Api *app_api) { } // Processor intensive operations and functions related to drawing to the screen should only be done when the app is in_foreground(=1). This function is only called when the app is init. -int app_main_clock::bgrefresh(Api *app_api, bool in_foreground) { - return 1; +BaseApp::AppReturnValues app_main_clock::bgrefresh(Api *app_api, bool in_foreground) { + if (*user_choice == 3) + return AppReturnValues::CLOSE; + else if (*user_choice == 4) + return AppReturnValues::QUIT; + return AppReturnValues::OK; } // Destruction of app, deinitlisation should be done here. This is only called if the app's APPS_DESTROY_ON_EXIT is set to 1. When it is not a "service" app. diff --git a/apps/main_clock/main.hpp b/apps/main_clock/main.hpp index f00958e..7c07cb3 100644 --- a/apps/main_clock/main.hpp +++ b/apps/main_clock/main.hpp @@ -9,7 +9,7 @@ class app_main_clock : public BaseApp { private: bool *ask_user_choice; int *user_choice; - const char *choices[26] = {"One", "Two", "Three!", "This is looong!", "make sure to choose me!:p"}; + const char *choices[10] = {"One", "Close (fg)", "Quit (fg)", "Close (bg)", "Quit (bg)"}; void time_as_str(char *buf, uint buf_size, const datetime_t *t); void date_as_str(char *buf, uint buf_size, const datetime_t *t); @@ -22,8 +22,8 @@ class app_main_clock : public BaseApp { } app_main_clock(Api *app_api); - int render(Api *app_api); - int btnpressed(Api *app_api, uint gpio, unsigned long delta); - int bgrefresh(Api *app_api, bool in_foreground); + AppReturnValues render(Api *app_api); + AppReturnValues btnpressed(Api *app_api, uint gpio, unsigned long delta); + AppReturnValues bgrefresh(Api *app_api, bool in_foreground); ~app_main_clock(); }; diff --git a/apps/settings/main.cpp b/apps/settings/main.cpp index 555c2c1..d4c910a 100644 --- a/apps/settings/main.cpp +++ b/apps/settings/main.cpp @@ -119,7 +119,7 @@ void app_settings::set1_menu(Api *app_api) { } // Rendering of app -int app_settings::render(Api *app_api) { +BaseApp::AppReturnValues app_settings::render(Api *app_api) { show_title(app_api); app_api->display_write_string(0,0,3, display_setting_name, FONT_12x16, 0, 1); @@ -135,10 +135,10 @@ int app_settings::render(Api *app_api) { } } - return 0; + return AppReturnValues::OK; } -int app_settings::btnpressed(Api *app_api, uint gpio, unsigned long delta) { +BaseApp::AppReturnValues app_settings::btnpressed(Api *app_api, uint gpio, unsigned long delta) { switch (gpio) { case BUTTON_SELECT: selected = true; @@ -157,7 +157,7 @@ int app_settings::btnpressed(Api *app_api, uint gpio, unsigned long delta) { } // Add spaces to avoid "ghost" characters from app names displayed before snprintf(display_setting_name, SIZE_SETTING_NAME, "%s ", MAIN_SET_NAMES[selected_setting]); - return 0; + return AppReturnValues::OK; } app_settings::app_settings(Api *app_api) { @@ -168,8 +168,8 @@ app_settings::app_settings(Api *app_api) { snprintf(display_setting_name, SIZE_SETTING_NAME, "%s", MAIN_SET_NAMES[0]); } -int app_settings::bgrefresh(Api *app_api, bool in_foreground) { - return 1; +BaseApp::AppReturnValues app_settings::bgrefresh(Api *app_api, bool in_foreground) { + return AppReturnValues::OK; } app_settings::~app_settings() { diff --git a/apps/settings/main.hpp b/apps/settings/main.hpp index 589be70..d53b8a9 100644 --- a/apps/settings/main.hpp +++ b/apps/settings/main.hpp @@ -20,9 +20,9 @@ class app_settings : public BaseApp { } app_settings(Api *app_api); - int render(Api *app_api); - int btnpressed(Api *app_api, uint gpio, unsigned long delta); - int bgrefresh(Api *app_api, bool in_foreground); + AppReturnValues render(Api *app_api); + AppReturnValues btnpressed(Api *app_api, uint gpio, unsigned long delta); + AppReturnValues bgrefresh(Api *app_api, bool in_foreground); ~app_settings(); }; #include "strings-undef.hpp" diff --git a/base_app.hpp b/base_app.hpp index c9d8e85..06f608a 100644 --- a/base_app.hpp +++ b/base_app.hpp @@ -8,13 +8,19 @@ class BaseApp { uint id = 0; bool destroy_on_exit = true; }; + enum AppReturnValues { + OK = 0, + CLOSE, // Close app from foreground, not respecting AppAttribues::destroy_on_exit. + QUIT // Completely quit app; stop running in background + }; + // CHECK: Following have to be overwritten by derived classes virtual const AppAttributes& app_get_attributes() = 0; // Could be implemented as: // {return app_attributes;} // where app_attribues is an instance of AppAttributes - virtual int render(Api *app_api) = 0; // Has to be implemented - virtual int btnpressed(Api *app_api, uint gpio, unsigned long delta) {}; - virtual int bgrefresh(Api *app_api, bool in_foreground) {}; + virtual AppReturnValues render(Api *app_api) = 0; // Has to be implemented + virtual AppReturnValues btnpressed(Api *app_api, uint gpio, unsigned long delta) {return AppReturnValues::OK;}; + virtual AppReturnValues bgrefresh(Api *app_api, bool in_foreground) {return AppReturnValues::OK;}; }; |