Skip to content

Commit

Permalink
not enough stack, let's use heap instead(sdBrowserMenu) (#8)
Browse files Browse the repository at this point in the history
keira: allow more than 32 items in sdBrowserMenu
keira: use unique_ptr to track Entry[] allocation
lib: add getEntryCount
  • Loading branch information
frostmorn authored Mar 19, 2024
1 parent be4835b commit 605d0b9
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 21 deletions.
42 changes: 21 additions & 21 deletions firmware/keira/src/apps/launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,44 +143,42 @@ void LauncherApp::sdBrowserMenu(String path) {
if (!lilka::sdcard.available()) {
alert("Помилка", "SD-карта не знайдена");
}
size_t _numEntries = lilka::sdcard.getEntryCount(path);
if (_numEntries == 0) {
alert("Помилка", "Директорія пуста або сталася помилка читання директорії");
return;
}

lilka::Entry* entries = new lilka::Entry[_numEntries];

lilka::Entry entries
[32]; // TODO - allocate dynamically (increasing to 64 causes task stack overflow which is limited by ARDUINO_LOOP_STACK_SIZE)
int numEntries = lilka::sdcard.listDir(path, entries);
std::unique_ptr<lilka::Entry[]> entriesPtr(entries);

if (numEntries == -1) {
// lilka::ui_alert(canvas, "Помилка", "Не вдалося прочитати директорію");
// Так як listDir має повертати -1 в разі помилки
// а countFilesIndir size_t >= 0 додаткові перевірки не потрібні
if (_numEntries != numEntries) {
alert("Помилка", "Не вдалося прочитати директорію");
return;
}

String filenames[32];
const menu_icon_t* icons[32];
uint16_t colors[32];
for (int i = 0; i < numEntries; i++) {
filenames[i] = entries[i].name;
icons[i] = entries[i].type == lilka::EntryType::ENT_DIRECTORY ? &folder : get_file_icon(filenames[i]);
colors[i] = entries[i].type == lilka::EntryType::ENT_DIRECTORY ? lilka::display.color565(255, 255, 200)
: get_file_color(filenames[i]);
}
filenames[numEntries++] = "<< Назад";
icons[numEntries - 1] = 0;
colors[numEntries - 1] = 0;

lilka::Menu menu("SD: " + path);
for (int i = 0; i < numEntries; i++) {
menu.addItem(filenames[i], icons[i], colors[i]);
String filename = entries[i].name;
const menu_icon_t* icon =
entries[i].type == lilka::EntryType::ENT_DIRECTORY ? &folder : get_file_icon(filename);
uint16_t color = entries[i].type == lilka::EntryType::ENT_DIRECTORY ? lilka::display.color565(255, 255, 200)
: get_file_color(filename);
menu.addItem(filename, icon, color);
}
menu.addItem("<< Назад", 0, 0);

while (1) {
menu.update();
menu.draw(canvas);
queueDraw();
int16_t index = menu.getSelectedIndex();
if (index != -1) {
if (index == numEntries - 1) {
return;
}
if (index >= numEntries - 1) break;
if (entries[index].type == lilka::EntryType::ENT_DIRECTORY) {
sdBrowserMenu(path + entries[index].name + "/");
} else {
Expand All @@ -189,6 +187,8 @@ void LauncherApp::sdBrowserMenu(String path) {
}
taskYIELD();
}

return;
}

void LauncherApp::spiffsBrowserMenu() {
Expand Down
31 changes: 31 additions & 0 deletions sdk/lib/lilka/src/lilka/sdcard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,37 @@ int SDCard::listDir(String path, Entry entries[]) {
return i;
}

size_t SDCard::getEntryCount(String path) {
size_t countFiles = 0;

while (!path.equals("/") && path.endsWith("/")) {
// Strip trailing slashes, unless it's the root directory
path.remove(path.length() - 1);
}
File root = fs->open(path);
// Below we assume if folder can't be open then it has zero files
// Btw we will show this error using serial
if (!root) {
serial_err("%s:%d:getEntryCount: failed to open directory: %s", __FILE__, __LINE__, path.c_str());
return 0;
}
if (!root.isDirectory()) {
serial_err("%s:%d:getEntryCount: not a directory: %s", __FILE__, __LINE__, path.c_str());
return 0;
}

File file = root.openNextFile();

while (file) {
file = root.openNextFile();
countFiles++;
}

root.close();

return countFiles;
}

String SDCard::abspath(String filename) {
while (filename.length() > 0 && filename[0] == '/') {
filename = filename.substring(1);
Expand Down
1 change: 1 addition & 0 deletions sdk/lib/lilka/src/lilka/sdcard.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class SDCard {
SDFS* fs;

int listDir(String path, Entry entries[]);
size_t getEntryCount(String path);
String abspath(String path);
};

Expand Down

0 comments on commit 605d0b9

Please sign in to comment.