aboutsummaryrefslogtreecommitdiffstats
path: root/app_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app_manager.cpp')
-rw-r--r--app_manager.cpp109
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;
}