aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConfuSomu2021-03-16 12:33:29 -0400
committerConfuSomu2021-03-16 12:33:29 -0400
commit5aa8fc267204835296914360647473e3e93001e6 (patch)
tree98004d748bce1cd72fd82b5692cc2297b61886d6
parente864e2efdda9ae977a049bc5491495b421028902 (diff)
downloadpico-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.cpp33
-rw-r--r--api.hpp4
-rw-r--r--oled/ss_oled.c2
-rw-r--r--oled/ss_oled.h2
4 files changed, 26 insertions, 15 deletions
diff --git a/api.cpp b/api.cpp
index 0d04772..1c08eb9 100644
--- a/api.cpp
+++ b/api.cpp
@@ -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) {
diff --git a/api.hpp b/api.hpp
index d6f551e..7f5015c 100644
--- a/api.hpp
+++ b/api.hpp
@@ -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)