mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-08-27 09:59:03 +00:00
Memory management improv.
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "rtc_time.hpp"
|
||||
#include "sd_card.hpp"
|
||||
#include <algorithm>
|
||||
#include "ui_external_items_menu_loader.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@@ -60,6 +61,7 @@ BtnGridView::BtnGridView(
|
||||
}
|
||||
|
||||
BtnGridView::~BtnGridView() {
|
||||
ExternalItemsMenuLoader::unload_external_items();
|
||||
}
|
||||
|
||||
void BtnGridView::set_max_rows(int rows) {
|
||||
@@ -87,6 +89,7 @@ void BtnGridView::set_parent_rect(const Rect new_parent_rect) {
|
||||
remove_child(item.get());
|
||||
|
||||
menu_item_views.clear();
|
||||
menu_item_views.shrink_to_fit();
|
||||
}
|
||||
|
||||
button_w = screen_width / rows_;
|
||||
@@ -137,6 +140,7 @@ void BtnGridView::set_arrow_down_enabled(bool enabled) {
|
||||
void BtnGridView::clear() {
|
||||
// clear vector and release memory, not using swap since it's causing capture to glitch/fault
|
||||
menu_items.clear();
|
||||
menu_items.shrink_to_fit();
|
||||
|
||||
// TODO(u-foka): Clean up my mess, move this somewhere to clear memory when the view is not visible, but not to be confused with clearing the menu items...
|
||||
for (auto& item : menu_item_views)
|
||||
@@ -144,10 +148,11 @@ void BtnGridView::clear() {
|
||||
|
||||
// clear vector and release memory, not using swap since it's causing capture to glitch/fault
|
||||
menu_item_views.clear();
|
||||
menu_item_views.shrink_to_fit();
|
||||
}
|
||||
|
||||
void BtnGridView::add_items(std::initializer_list<GridItem> new_items, bool inhibit_update) {
|
||||
for (auto item : new_items) {
|
||||
for (const auto& item : new_items) {
|
||||
if (!blacklisted_app(item))
|
||||
menu_items.push_back(item);
|
||||
}
|
||||
@@ -389,39 +394,34 @@ bool BtnGridView::on_encoder(const EncoderEvent event) {
|
||||
|
||||
/* BlackList ******************************************************/
|
||||
|
||||
std::unique_ptr<char> blacklist_ptr{};
|
||||
size_t blacklist_len{};
|
||||
std::string blacklist_data{};
|
||||
|
||||
void load_blacklist() {
|
||||
File f;
|
||||
|
||||
auto error = f.open(BLACKLIST);
|
||||
if (error)
|
||||
return;
|
||||
|
||||
// allocating two extra bytes for leading & trailing commas
|
||||
blacklist_ptr = std::unique_ptr<char>(new char[f.size() + 2]);
|
||||
if (f.read(blacklist_ptr.get() + 1, f.size())) {
|
||||
blacklist_len = f.size() + 2;
|
||||
|
||||
// replace any CR/LF characters with comma delineator, and add comma prefix/suffix, to simplify searching
|
||||
char* ptr = blacklist_ptr.get();
|
||||
*ptr = ',';
|
||||
*(ptr + blacklist_len - 1) = ',';
|
||||
for (size_t i = 0; i < blacklist_len; i++, ptr++) {
|
||||
if (*ptr == 0x0D || *ptr == 0x0A)
|
||||
*ptr = ',';
|
||||
// Resize string to fit file + 2 commas, filling it with commas by default
|
||||
blacklist_data.assign(f.size() + 2, ',');
|
||||
// Read directly into the string's buffer (offset by 1 to leave the first comma)
|
||||
if (f.read(blacklist_data.data() + 1, f.size())) {
|
||||
// Replace any CR/LF characters with commas
|
||||
for (char& c : blacklist_data) {
|
||||
if (c == '\r' || c == '\n') {
|
||||
c = ',';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
blacklist_data.clear(); // Clear if read fails
|
||||
}
|
||||
}
|
||||
|
||||
bool BtnGridView::blacklisted_app(GridItem new_item) {
|
||||
std::string app_name = "," + new_item.text + ",";
|
||||
|
||||
if (blacklist_len < app_name.size())
|
||||
if (blacklist_data.size() < app_name.size())
|
||||
return false;
|
||||
|
||||
return std::search(blacklist_ptr.get(), blacklist_ptr.get() + blacklist_len, app_name.begin(), app_name.end()) < blacklist_ptr.get() + blacklist_len;
|
||||
return blacklist_data.find(app_name) != std::string::npos;
|
||||
}
|
||||
|
||||
void BtnGridView::page_up() {
|
||||
|
||||
@@ -251,15 +251,13 @@ void GeoMap::map_read_line_bin(ui::Color* buffer, uint16_t pixels) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui::Color* zoom_out_buffer = new ui::Color[(pixels * (-map_zoom))];
|
||||
ui::Color zoom_out_buffer[(pixels * (-map_zoom))];
|
||||
map_file.read(zoom_out_buffer, (pixels * (-map_zoom)) << 1);
|
||||
|
||||
// Zoom out: Collapse each group of "-map_zoom" pixels into one pixel.
|
||||
// Future TODO: Average each group of pixels (in both X & Y directions if possible).
|
||||
for (int i = 0; i < width; i++) {
|
||||
buffer[i] = zoom_out_buffer[i * (-map_zoom)];
|
||||
}
|
||||
delete[] zoom_out_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,8 +331,9 @@ void GeoMap::set_osm_max_zoom(bool changeboth) {
|
||||
for (uint8_t i = map_osm_zoom; i > 0; i--) {
|
||||
int tile_x = lon2tile(lon_, i);
|
||||
int tile_y = lat2tile(lat_, i);
|
||||
std::string filename = "/OSM/" + to_string_dec_int(i) + "/" + to_string_dec_int(tile_x) + "/" + to_string_dec_int(tile_y) + ".bmp";
|
||||
std::filesystem::path file_path(filename);
|
||||
char path_buffer[64];
|
||||
snprintf(path_buffer, sizeof(path_buffer), "/OSM/%d/%d/%d.bmp", i, tile_x, tile_y);
|
||||
std::filesystem::path file_path(path_buffer);
|
||||
if (file_exists(file_path)) {
|
||||
map_osm_real_zoom = i;
|
||||
if (changeboth) map_osm_zoom = i;
|
||||
@@ -347,7 +346,7 @@ void GeoMap::set_osm_max_zoom(bool changeboth) {
|
||||
|
||||
// checks if the tile file presents or not. to determine if we got osm or not
|
||||
uint8_t GeoMap::find_osm_file_tile() {
|
||||
std::string filename = "/OSM/" + to_string_dec_int(0) + "/" + to_string_dec_int(0) + "/" + to_string_dec_int(0) + ".bmp";
|
||||
std::string filename = "/OSM/0/0/0.bmp";
|
||||
std::filesystem::path file_path(filename);
|
||||
if (file_exists(file_path)) return 1;
|
||||
return 0; // not found
|
||||
@@ -456,22 +455,24 @@ bool GeoMap::draw_osm_file(int zoom, int tile_x, int tile_y, int relative_x, int
|
||||
display.fill_rectangle(error_rect, Theme::getInstance()->bg_darkest->background);
|
||||
return false;
|
||||
}
|
||||
std::vector<ui::Color> line(clip_w);
|
||||
|
||||
map_line_buffer.resize(clip_w);
|
||||
|
||||
if (bmp.is_bottomup()) {
|
||||
for (int y = clip_h - 1; y >= 0; --y) {
|
||||
int source_row = src_y + y;
|
||||
int dest_row = dest_y + y;
|
||||
bmp.seek(src_x, source_row);
|
||||
bmp.read_next_px_cnt(line.data(), clip_w, false);
|
||||
display.draw_pixels({dest_x + r.left(), dest_row + r.top(), clip_w, 1}, line);
|
||||
bmp.read_next_px_cnt(map_line_buffer.data(), clip_w, false);
|
||||
display.draw_pixels({dest_x + r.left(), dest_row + r.top(), clip_w, 1}, map_line_buffer);
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < clip_h; ++y) {
|
||||
int source_row = src_y + y;
|
||||
int dest_row = dest_y + y;
|
||||
bmp.seek(src_x, source_row);
|
||||
bmp.read_next_px_cnt(line.data(), clip_w, false);
|
||||
display.draw_pixels({dest_x + r.left(), dest_row + r.top(), clip_w, 1}, line);
|
||||
bmp.read_next_px_cnt(map_line_buffer.data(), clip_w, false);
|
||||
display.draw_pixels({dest_x + r.left(), dest_row + r.top(), clip_w, 1}, map_line_buffer);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -479,11 +480,11 @@ bool GeoMap::draw_osm_file(int zoom, int tile_x, int tile_y, int relative_x, int
|
||||
|
||||
void GeoMap::paint(Painter& painter) {
|
||||
const auto r = screen_rect();
|
||||
std::vector<ui::Color> map_line_buffer;
|
||||
map_line_buffer.resize(r.width());
|
||||
int16_t zoom_seek_x, zoom_seek_y;
|
||||
|
||||
if (!use_osm) {
|
||||
map_line_buffer.resize(r.width());
|
||||
|
||||
// Ony redraw map if it moved by at least 1 pixel or the markers list was updated
|
||||
if (map_zoom <= 1) {
|
||||
// Zooming out, or no zoom
|
||||
@@ -755,7 +756,7 @@ void GeoMap::draw_bearing(const Point origin, const uint16_t angle, uint32_t siz
|
||||
display.draw_pixel(origin, color); // 1 pixel indicating center pivot point of bearing symbol
|
||||
}
|
||||
|
||||
void GeoMap::draw_marker(Painter& painter, const ui::Point itemPoint, const uint16_t itemAngle, const std::string itemTag, const Color color, const Color fontColor, const Color backColor) {
|
||||
void GeoMap::draw_marker(Painter& painter, const ui::Point itemPoint, const uint16_t itemAngle, const std::string& itemTag, const Color color, const Color fontColor, const Color backColor) {
|
||||
const auto r = screen_rect();
|
||||
|
||||
int tagOffset = 10;
|
||||
|
||||
@@ -247,7 +247,7 @@ class GeoMap : public Widget {
|
||||
ui::Point item_rect_pixel(GeoMarker& item);
|
||||
GeoPoint lat_lon_to_map_pixel(float lat, float lon);
|
||||
void draw_marker_item(Painter& painter, GeoMarker& item, const Color color, const Color fontColor = Color::white(), const Color backColor = Color::black());
|
||||
void draw_marker(Painter& painter, const ui::Point itemPoint, const uint16_t itemAngle, const std::string itemTag, const Color color = Color::red(), const Color fontColor = Color::white(), const Color backColor = Color::black());
|
||||
void draw_marker(Painter& painter, const ui::Point itemPoint, const uint16_t itemAngle, const std::string& itemTag, const Color color = Color::red(), const Color fontColor = Color::white(), const Color backColor = Color::black());
|
||||
void draw_markers(Painter& painter);
|
||||
void draw_mypos(Painter& painter);
|
||||
void draw_bearing(const Point origin, const uint16_t angle, uint32_t size, const Color color);
|
||||
@@ -264,6 +264,9 @@ class GeoMap : public Widget {
|
||||
double lat_to_pixel_y_tile(double lat, int zoom);
|
||||
double tile_pixel_x_to_lon(int x, int zoom);
|
||||
double tile_pixel_y_to_lat(int y, int zoom);
|
||||
|
||||
std::vector<ui::Color> map_line_buffer{};
|
||||
|
||||
uint8_t map_osm_zoom{5};
|
||||
uint8_t map_osm_real_zoom{5};
|
||||
double viewport_top_left_px = 0;
|
||||
|
||||
@@ -117,6 +117,7 @@ void MenuView::set_parent_rect(const Rect new_parent_rect) {
|
||||
remove_child(item.get());
|
||||
|
||||
menu_item_views.clear();
|
||||
menu_item_views.shrink_to_fit();
|
||||
}
|
||||
|
||||
for (size_t c = 0; c < displayed_max; c++) {
|
||||
@@ -149,6 +150,7 @@ void MenuView::clear() {
|
||||
item->set_item(nullptr);
|
||||
|
||||
menu_items.clear();
|
||||
menu_items.shrink_to_fit();
|
||||
highlighted_item = 0;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user