[ai] memory optimizations, wifi reset, battery

This commit is contained in:
2025-11-30 17:06:20 +01:00
parent 34c499bd49
commit 9c937dc62d
8 changed files with 220 additions and 68 deletions

View File

@@ -234,9 +234,24 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
mp3Files.reserve(fileNames.size());
ids.reserve(fileNames.size());
// Create subdirectories in alphabetical order
for (const String &dirName : dirNames)
// Add MP3 files in alphabetical order first to free fileNames memory before recursing
for (const String &fileName : fileNames)
{
mp3Files.push_back(fileName);
ids.push_back(getNextId());
}
// Free memory used by fileNames vector
{
std::vector<String> empty;
fileNames.swap(empty);
}
// Create subdirectories in alphabetical order
// Use index loop and std::move to free strings in dirNames as we go, reducing stack memory usage during recursion
for (size_t i = 0; i < dirNames.size(); ++i)
{
String dirName = std::move(dirNames[i]); // Move string content out of vector
DirectoryNode *newNode = new DirectoryNode(dirName);
if (!newNode)
{
@@ -261,13 +276,6 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
newNode->buildDirectoryTree(childPath.c_str());
}
// Add MP3 files in alphabetical order (store only filenames; build full paths on demand)
for (const String &fileName : fileNames)
{
mp3Files.push_back(fileName);
ids.push_back(getNextId());
}
}
void DirectoryNode::printDirectoryTree(int level) const
@@ -648,50 +656,3 @@ DirectoryNode *DirectoryNode::advanceToNextMP3(const String &currentGlobal)
Serial.println(F("no more nodes found"));
return this;
}
/**
* @brief Not used anymore due to new
* backpressure-safe, low-heap HTML streaming solution to prevent AsyncTCP cbuf resize OOM during /directory.
*
* @param out
*/
void DirectoryNode::streamDirectoryHTML(Print &out) const {
#ifdef DEBUG
Serial.printf("StreamDirectoryHTML name=%s numOfFiles=%i\n", name, mp3Files.size());
#endif
if (name == "/") {
out.println(F("<ul>"));
}
if (name != "/") {
out.print(F("<li data-id=\""));
out.print(id);
out.print(F("\"><b>"));
out.print(name);
out.println(F("</b></li>"));
yield(); // Yield to allow network stack to send buffered data
}
for (size_t i = 0; i < mp3Files.size(); i++) {
out.print(F("<li data-id=\""));
out.print(ids[i]);
out.print(F("\">"));
out.print(mp3Files[i].c_str());
out.println(F("</li>"));
// Yield every few items to allow the async web server to send buffered data
if (i % 5 == 4) {
yield();
}
}
for (DirectoryNode* child : subdirectories) {
child->streamDirectoryHTML(out);
}
if (name == "/") {
out.println(F("</ul>"));
yield(); // Final yield before completing
}
}