[ai] memory optimizations, wifi reset, battery
This commit is contained in:
@@ -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 ¤tGlobal)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user