diff options
author | ConfuSomu | 2021-02-20 14:17:03 -0500 |
---|---|---|
committer | ConfuSomu | 2021-02-20 14:17:03 -0500 |
commit | 06d5f492eca8e57bc8ce7479ec6149fbc6a15d08 (patch) | |
tree | 6eec7b65d57843cd5ed73baa63a57081d6049ca1 | |
parent | 5686f56e4fad9130ca8f46f3aa3ff36bc41dbeb1 (diff) | |
download | pico-watch-06d5f492eca8e57bc8ce7479ec6149fbc6a15d08.tar pico-watch-06d5f492eca8e57bc8ce7479ec6149fbc6a15d08.tar.gz pico-watch-06d5f492eca8e57bc8ce7479ec6149fbc6a15d08.zip |
Use dynamic allocation of app variables/data
Stop using APPS_DATA. Dynamic allocation allows to avoid having memory
used by unloaded apps, thus giving more memory to running apps. Make
sure to correctly deallocate with `delete` to avoid memory leaks!
Exceptions to allocate memory will have to be handled...
-rw-r--r-- | apps/home_menu.cpp | 50 | ||||
-rw-r--r-- | apps/home_menu.hpp | 10 | ||||
-rw-r--r-- | apps/main_clock.cpp | 29 | ||||
-rw-r--r-- | apps/main_clock.hpp | 10 | ||||
-rw-r--r-- | pico-watch.cpp | 21 |
5 files changed, 55 insertions, 65 deletions
diff --git a/apps/home_menu.cpp b/apps/home_menu.cpp index 30caed0..7f53447 100644 --- a/apps/home_menu.cpp +++ b/apps/home_menu.cpp @@ -16,6 +16,8 @@ extern bool rtc_get_datetime(datetime_t *t); namespace app_home_menu { const char* APPS_NAME[NUMBER_OF_APPS][12] = {"Home", "Clock"}; + char *pressed_button; + int *selected_app; void title_str(char *buf, uint buf_size, const datetime_t *t) { snprintf(buf, @@ -38,56 +40,60 @@ namespace app_home_menu { } // Rendering of app - int render(SSOLED *oled, char *data, uint data_size) { + int render(SSOLED *oled) { show_title(oled); - oledWriteString(oled, 0,0,2, &data[0], FONT_6x8, 0, 1); - oledWriteString(oled, 0,5,3, const_cast<char*>(APPS_NAME[data[1]][0]), FONT_12x16, 0, 1); // FIXME: The name does not update, it seems that the second string is empty… but data[1]'s content is correct, as BUTTON_SELECT switches to the correct app. + oledWriteString(oled, 0,0,2, pressed_button, FONT_6x8, 0, 1); + oledWriteString(oled, 0,5,3, const_cast<char*>(APPS_NAME[0][*selected_app]), FONT_12x16, 0, 1); return 0; } - // Interpret button inputs - int btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio) { + // Example of how button inputs could be interpreted. + // Drawing on screen should be done in the render function. + int btnpressed(SSOLED *oled, uint gpio) { switch (gpio) { case BUTTON_HOME: - data[0] = 'H'; break; + *pressed_button = 'H'; break; case BUTTON_SELECT: - data[0] = 'S'; - app_switch(0, data[1]); + *pressed_button = 'S'; + app_switch(0, *selected_app); break; case BUTTON_MODE: - data[0] = 'M'; break; + *pressed_button = 'M'; break; case BUTTON_DOWN: - data[0] = 'D'; - data[1]--; + *pressed_button = 'D'; + *selected_app--; break; case BUTTON_UP: - data[0] = 'U'; - data[1]++; + *pressed_button = 'U'; + *selected_app++; break; default: - data[0] = '?'; + *pressed_button = '?'; } - if (data[1] > NUMBER_OF_APPS-1) { - data[1] = NUMBER_OF_APPS-1; data[0] = '>'; - } else if (data[1] < NUMBER_OF_APPS-1) { - data[1] = 0; data[0] = '<'; + if (*selected_app > NUMBER_OF_APPS-1) { + *selected_app = NUMBER_OF_APPS-1; *pressed_button = '>'; + } else if (*selected_app < NUMBER_OF_APPS-1) { + *selected_app = 0; *pressed_button = '<'; } return 0; } // Initlisation of the app. - int init(SSOLED *oled, char *data, uint data_size) { - data[1] = 0; + int init(SSOLED *oled) { + pressed_button = new char; *pressed_button = '*'; + selected_app = new int; return 0; // return 1 when function not implemented } // 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 bgrefresh(SSOLED *oled, char *data, uint data_size, char in_foreground) { + int bgrefresh(SSOLED *oled, char in_foreground) { return 1; } // 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. - int destroy(SSOLED *oled, char *data, uint data_size) { + int destroy(SSOLED *oled) { + delete pressed_button; pressed_button = nullptr; + delete selected_app; selected_app = nullptr; return 1; } } diff --git a/apps/home_menu.hpp b/apps/home_menu.hpp index bd648d3..ebcc451 100644 --- a/apps/home_menu.hpp +++ b/apps/home_menu.hpp @@ -5,11 +5,11 @@ #include "../oled/ss_oled.h" namespace app_home_menu { - int init(SSOLED *oled, char *data, uint data_size); - int render(SSOLED *oled, char *data, uint data_size); - int btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio); - int bgrefresh(SSOLED *oled, char *data, uint data_size, char in_foreground); - int destroy(SSOLED *oled, char *data, uint data_size); + int init(SSOLED *oled); + int render(SSOLED *oled); + int btnpressed(SSOLED *oled, uint gpio); + int bgrefresh(SSOLED *oled, char in_foreground); + int destroy(SSOLED *oled); } #endif diff --git a/apps/main_clock.cpp b/apps/main_clock.cpp index 326c0f4..f9be3e5 100644 --- a/apps/main_clock.cpp +++ b/apps/main_clock.cpp @@ -55,45 +55,30 @@ namespace app_main_clock { } // Rendering of the app - int render(SSOLED *oled, char *data, uint data_size) { + int render(SSOLED *oled) { oledWriteString(oled, 0,15,0, (char *)"Test clock", FONT_8x8, 0, 1); show_datetime(oled); - oledWriteString(oled, 0,0,0, &data[0], FONT_6x8, 0, 1); + //oledWriteString(oled, 0,0,0, &data[0], FONT_6x8, 0, 1); return 0; } - // Example of how button inputs could be interpreted. - // Drawing on screen should be done in the render function. - int btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio) { - switch (gpio) { - case BUTTON_HOME: // Apps will generally not receive the Home button press - data[0] = 'H'; break; - case BUTTON_SELECT: - data[0] = 'S'; break; - case BUTTON_MODE: - data[0] = 'M'; break; - case BUTTON_DOWN: - data[0] = 'D'; break; - case BUTTON_UP: - data[0] = 'U'; break; - default: - data[0] = '?'; - } + // Interpretation of button inputs + int btnpressed(SSOLED *oled, uint gpio) { return 0; } // Initlisation of the app. - int init(SSOLED *oled, char *data, uint data_size) { + int init(SSOLED *oled) { return 1; // return 1 when function not implemented } // 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 bgrefresh(SSOLED *oled, char *data, uint data_size, char in_foreground) { + int bgrefresh(SSOLED *oled, char in_foreground) { return 1; } // 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. - int destroy(SSOLED *oled, char *data, uint data_size) { + int destroy(SSOLED *oled) { return 1; } }
\ No newline at end of file diff --git a/apps/main_clock.hpp b/apps/main_clock.hpp index c20af0f..887dfa1 100644 --- a/apps/main_clock.hpp +++ b/apps/main_clock.hpp @@ -5,11 +5,11 @@ #include "../oled/ss_oled.h" namespace app_main_clock { - int init(SSOLED *oled, char *data, uint data_size); - int render(SSOLED *oled, char *data, uint data_size); - int btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio); - int bgrefresh(SSOLED *oled, char *data, uint data_size, char in_foreground); - int destroy(SSOLED *oled, char *data, uint data_size); + int init(SSOLED *oled); + int render(SSOLED *oled); + int btnpressed(SSOLED *oled, uint gpio); + int bgrefresh(SSOLED *oled, char in_foreground); + int destroy(SSOLED *oled); } #endif
\ No newline at end of file diff --git a/pico-watch.cpp b/pico-watch.cpp index 05d94e2..243f1e1 100644 --- a/pico-watch.cpp +++ b/pico-watch.cpp @@ -14,12 +14,11 @@ int current_app = 0; #define NUMBER_OF_APPS 2 #define APP_DATA_BUFFER_LEN 256 -int (*APPS_FUNC_INIT[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size) = {app_home_menu::init, app_main_clock::init}; -int (*APPS_FUNC_RENDER[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size) = {app_home_menu::render, app_main_clock::render}; -int (*APPS_FUNC_BTNPRESS[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size, uint gpio) = {app_home_menu::btnpressed, app_main_clock::btnpressed}; -int (*APPS_FUNC_BGREFRESH[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size, char in_foreground) = {app_home_menu::bgrefresh, app_main_clock::bgrefresh}; -int (*APPS_FUNC_DESTROY[NUMBER_OF_APPS])(SSOLED *oled, char *data, uint data_size) = {app_home_menu::destroy, app_main_clock::destroy}; -char APPS_DATA[NUMBER_OF_APPS][APP_DATA_BUFFER_LEN]; +int (*APPS_FUNC_INIT[NUMBER_OF_APPS])(SSOLED *oled) = {app_home_menu::init, app_main_clock::init}; +int (*APPS_FUNC_RENDER[NUMBER_OF_APPS])(SSOLED *oled) = {app_home_menu::render, app_main_clock::render}; +int (*APPS_FUNC_BTNPRESS[NUMBER_OF_APPS])(SSOLED *oled, uint gpio) = {app_home_menu::btnpressed, app_main_clock::btnpressed}; +int (*APPS_FUNC_BGREFRESH[NUMBER_OF_APPS])(SSOLED *oled, char in_foreground) = {app_home_menu::bgrefresh, app_main_clock::bgrefresh}; +int (*APPS_FUNC_DESTROY[NUMBER_OF_APPS])(SSOLED *oled) = {app_home_menu::destroy, app_main_clock::destroy}; int APPS_DESTROY_ON_EXIT[NUMBER_OF_APPS] = {0, 1}; int APPS_IS_INIT[NUMBER_OF_APPS] = {0, 0}; // Only run in background if init @@ -27,29 +26,29 @@ int app_init(int app_id) { oledFill(&oled, 0,1); // Clear OLED if (!APPS_IS_INIT[app_id]) { APPS_IS_INIT[app_id] = 1; - return (*APPS_FUNC_INIT[app_id])(&oled, &APPS_DATA[app_id][0], sizeof(APPS_DATA[app_id])); + return (*APPS_FUNC_INIT[app_id])(&oled); } } int app_render(int app_id) { - return (*APPS_FUNC_RENDER[app_id])(&oled, &APPS_DATA[app_id][0], sizeof(APPS_DATA[app_id])); + return (*APPS_FUNC_RENDER[app_id])(&oled); } int app_btnpressed(int app_id, uint gpio) { - return (*APPS_FUNC_BTNPRESS[app_id])(&oled, &APPS_DATA[app_id][0], sizeof(APPS_DATA[app_id]), gpio); + return (*APPS_FUNC_BTNPRESS[app_id])(&oled, gpio); } int app_destroy(int app_id) { // TODO: reset APPS_DATA for the app if (APPS_IS_INIT[app_id]) { APPS_IS_INIT[app_id] = 0; - return (*APPS_FUNC_DESTROY[app_id])(&oled, &APPS_DATA[app_id][0], sizeof(APPS_DATA[app_id])); + return (*APPS_FUNC_DESTROY[app_id])(&oled); } } int app_bgrefresh(int app_id) { if (APPS_IS_INIT[app_id]) - return (*APPS_FUNC_BGREFRESH[app_id])(&oled, &APPS_DATA[app_id][0], sizeof(APPS_DATA[app_id]), app_id==current_app); + return (*APPS_FUNC_BGREFRESH[app_id])(&oled, app_id==current_app); } bool apps_bgrefresh(struct repeating_timer *t) { // TODO: Refresh done on core1 |