diff options
author | ConfuSomu | 2021-03-16 12:33:29 -0400 |
---|---|---|
committer | ConfuSomu | 2021-03-16 12:33:29 -0400 |
commit | 5aa8fc267204835296914360647473e3e93001e6 (patch) | |
tree | 98004d748bce1cd72fd82b5692cc2297b61886d6 | |
parent | e864e2efdda9ae977a049bc5491495b421028902 (diff) | |
download | pico-watch-5aa8fc267204835296914360647473e3e93001e6.tar pico-watch-5aa8fc267204835296914360647473e3e93001e6.tar.gz pico-watch-5aa8fc267204835296914360647473e3e93001e6.zip |
Move display of popup in API to generic function
This allows implementing different popup types with more ease.
This new function made me notice that the application's heap (and maybe
stack) usage is high. When testing the updated gui_popup_text method, I
noticed that sometimes, the std::string cannot be allocated.
There are more details in the updated api header file.
-rw-r--r-- | api.cpp | 33 | ||||
-rw-r--r-- | api.hpp | 4 | ||||
-rw-r--r-- | oled/ss_oled.c | 2 | ||||
-rw-r--r-- | oled/ss_oled.h | 2 |
4 files changed, 26 insertions, 15 deletions
@@ -64,23 +64,22 @@ int Api::display_write_pixel(int x, int y, unsigned char ucColor, int bRender) { return oledSetPixel(&m_oled, x, y, ucColor, bRender); } -bool Api::gui_popup_text(std::string title, std::string body){ -#define CHARS_PER_LINE 13 - m_button_last_pressed = 0; - m_send_button_press_to_app = false; - +void Api::gui_popup_generic(std::string &title, std::string &body, int max_title_length, int max_body_length) { oledRectangle(&m_oled, 9,7, 119,63, 0, 1); // Background oledRectangle(&m_oled, 9,7, 119,63, 1, 0); // Popup border oledRectangle(&m_oled, 9,7, 119,16, 1, 1); // Title background, FIXME pixel bleeding - m_writebb_needed = true; this->display_write_backbuffer(); // Display rectangle and anything else behind it (drawn before) + m_writebb_needed = true; this->display_write_backbuffer(); // Display rectangle and anything else behind it (drawn before), could be moved after writing strings // Truncate longer strings to avoid wasting time in for loop and drawing on OLED - if (title.size() > 13) + if (max_title_length > 13) max_title_length = 13; + if (max_body_length > 78) max_body_length = 78; + if (title.size() > max_title_length) title.resize(13); - if (body.size() > 78) + if (body.size() > max_body_length) body.resize(78); // Make body fit by adding '\n' at a regular interval + #define CHARS_PER_LINE 13 int since_nl = 0; // Characters since newline for (std::string::size_type i = 0; i < body.size(); ++i) { if (body[i] == '\n') @@ -91,10 +90,18 @@ bool Api::gui_popup_text(std::string title, std::string body){ } } // See https://stackoverflow.com/questions/1986966/does-s0-point-to-contiguous-characters-in-a-stdstring - oledWriteString(&m_oled, 0, 15,1, &title[0], FONT_8x8, 1, 1); // Draw title - oledWriteString(&m_oled, 0, 13,2, &body[0], FONT_8x8, 0, 1); // Draw body + oledWriteString(&m_oled, 0, 15,1, title.c_str(), FONT_8x8, 1, 1); // Draw title + oledWriteString(&m_oled, 0, 13,2, body.c_str(), FONT_8x8, 0, 1); // Draw body +} + +bool Api::gui_popup_text(std::string title, std::string body){ + m_button_last_pressed = 0; + m_send_button_press_to_app = false; + + gui_popup_generic(title, body); + while (m_button_last_pressed != BUTTON_SELECT) - sleep_ms(50); + sleep_ms(50); // TODO: use _wfi() // Give back control to running app oledFill(&m_oled, 0, 1); m_send_button_press_to_app = true; @@ -118,7 +125,7 @@ bool Api::gui_footer_text(std::string text, int offset_x, int offset_row, bool i oledRectangle(&m_oled, 0,56-offset_row*8, 127,64-offset_row*8, invert, 1); m_writebb_needed = true; } - oledWriteString(&m_oled, 0,offset_x,7-offset_row, &text[0], font, invert, 0); + oledWriteString(&m_oled, 0,offset_x,7-offset_row, text.c_str(), font, invert, 0); } bool Api::gui_header_text(std::string text, int offset_x, int offset_row, bool invert, bool no_bg) { @@ -139,7 +146,7 @@ bool Api::gui_header_text(std::string text, int offset_x, int offset_row, bool i oledRectangle(&m_oled, 0,0+offset_row*8, 127,8+offset_row*8, invert, 1); m_writebb_needed = true; } - oledWriteString(&m_oled, 0,offset_x,0+offset_row, &text[0], font, invert, 0); + oledWriteString(&m_oled, 0,offset_x,0+offset_row, text.c_str(), font, invert, 0); } bool Api::performance_set(int perf) { @@ -16,6 +16,10 @@ class Api { uint m_button_last_pressed = 0; int m_app_render_interval = 500; void init_display(); + // Careful of large heap usage with long strings! Heap seems to be fragmented, so shorter strings work best. More details on findings below: + // When the string cannot be created, this comes from the fact that we, on some runs, allocation can be very close to the SRAM's boundry: 0x20041f88 with boundry at 0x20042000. The heap is nearly full. Even just appending to a string moves the allocation lower. I think that the best course of action would be to have more static variables and pull in less things to save SRAM. + // When char* directly passed as parameter: The memory is possibly fragmented as long strings (>215) push the allocation downwards, into lower (higher address) in the heap. title is at 0x20041f90 and body at 0x200045e8, for length of 215 chars. + void gui_popup_generic(std::string &title, std::string &body, int max_title_length = 13, int max_body_length = 78); public: bool m_send_button_press_to_app = true; enum perf_modes { diff --git a/oled/ss_oled.c b/oled/ss_oled.c index 3375bde..ff40451 100644 --- a/oled/ss_oled.c +++ b/oled/ss_oled.c @@ -1460,7 +1460,7 @@ void oledSetTextWrap(SSOLED *pOLED, int bWrap) // Draw a string of normal (8x8), small (6x8) or large (16x32) characters // At the given col+row // -int oledWriteString(SSOLED *pOLED, int iScroll, int x, int y, char *szMsg, int iSize, int bInvert, int bRender) +int oledWriteString(SSOLED *pOLED, int iScroll, int x, int y, const char *szMsg, int iSize, int bInvert, int bRender) { int i, iFontOff, iLen, iFontSkip; unsigned char c, *s, ucTemp[40]; diff --git a/oled/ss_oled.h b/oled/ss_oled.h index fe6f399..78b68d4 100644 --- a/oled/ss_oled.h +++ b/oled/ss_oled.h @@ -129,7 +129,7 @@ void oledSetTextWrap(SSOLED *pOLED, int bWrap); // // Returns 0 for success, -1 for invalid parameter // -int oledWriteString(SSOLED *pOLED, int iScrollX, int x, int y, char *szMsg, int iSize, int bInvert, int bRender); +int oledWriteString(SSOLED *pOLED, int iScrollX, int x, int y, const char *szMsg, int iSize, int bInvert, int bRender); // // Fill the frame buffer with a byte pattern // e.g. all off (0x00) or all on (0xff) |