aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api.hpp6
-rw-r--r--app_manager.cpp60
-rw-r--r--app_manager.hpp10
-rw-r--r--apps/home_menu/main.cpp14
-rw-r--r--apps/home_menu/main.hpp6
-rw-r--r--apps/main_clock/main.cpp22
-rw-r--r--apps/main_clock/main.hpp8
-rw-r--r--apps/settings/main.cpp12
-rw-r--r--apps/settings/main.hpp6
-rw-r--r--base_app.hpp12
10 files changed, 108 insertions, 48 deletions
diff --git a/api.hpp b/api.hpp
index ad720e7..f162e58 100644
--- a/api.hpp
+++ b/api.hpp
@@ -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;};
};