[ai] further memory optimizations
This commit is contained in:
@@ -37,12 +37,42 @@ const std::vector<String> &DirectoryNode::getMP3Files() const
|
||||
return mp3Files;
|
||||
}
|
||||
|
||||
const String &DirectoryNode::getDirPath() const
|
||||
{
|
||||
return dirPath;
|
||||
}
|
||||
|
||||
String DirectoryNode::getFullPathByIndex(size_t index) const
|
||||
{
|
||||
if (index < mp3Files.size())
|
||||
{
|
||||
return buildFullPath(mp3Files[index]);
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
String DirectoryNode::buildFullPath(const String &fileName) const
|
||||
{
|
||||
if (dirPath == "/")
|
||||
{
|
||||
String p = "/";
|
||||
p += fileName;
|
||||
return p;
|
||||
}
|
||||
String p = dirPath;
|
||||
p += "/";
|
||||
p += fileName;
|
||||
return p;
|
||||
}
|
||||
|
||||
void DirectoryNode::setCurrentPlaying(const String &mp3File)
|
||||
{
|
||||
currentPlaying = mp3File;
|
||||
bool isAbs = (mp3File.length() > 0) && (mp3File.charAt(0) == '/');
|
||||
const String &fileName = isAbs ? mp3File.substring(mp3File.lastIndexOf('/') + 1) : mp3File;
|
||||
currentPlaying = isAbs ? mp3File : buildFullPath(fileName);
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
if (mp3Files[i] == mp3File && ids.size() > i)
|
||||
if (mp3Files[i] == fileName && ids.size() > i)
|
||||
{
|
||||
currentPlayingId = ids[i];
|
||||
break;
|
||||
@@ -102,6 +132,14 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
|
||||
mp3Files.shrink_to_fit();
|
||||
ids.shrink_to_fit();
|
||||
|
||||
// Set directory path for this node (normalize: keep "/" or remove trailing slash)
|
||||
String path = String(currentPath);
|
||||
if (path.length() > 1 && path.endsWith("/"))
|
||||
{
|
||||
path.remove(path.length() - 1);
|
||||
}
|
||||
dirPath = path;
|
||||
|
||||
// First collect entries so we can sort them alphabetically
|
||||
std::vector<String> dirNames;
|
||||
std::vector<String> fileNames;
|
||||
@@ -167,15 +205,10 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
|
||||
newNode->buildDirectoryTree(childPath.c_str());
|
||||
}
|
||||
|
||||
// Add MP3 files in alphabetical order
|
||||
// Add MP3 files in alphabetical order (store only filenames; build full paths on demand)
|
||||
for (const String &fileName : fileNames)
|
||||
{
|
||||
String fullPath = String(currentPath);
|
||||
if (!fullPath.endsWith("/"))
|
||||
fullPath += "/";
|
||||
fullPath += fileName;
|
||||
|
||||
mp3Files.push_back(std::move(fullPath));
|
||||
mp3Files.push_back(fileName);
|
||||
ids.push_back(getNextId());
|
||||
}
|
||||
}
|
||||
@@ -194,7 +227,7 @@ void DirectoryNode::printDirectoryTree(int level) const
|
||||
{
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
Serial.println(mp3File);
|
||||
Serial.println(buildFullPath(mp3File));
|
||||
}
|
||||
|
||||
for (DirectoryNode *childNode : subdirectories)
|
||||
@@ -241,7 +274,7 @@ DirectoryNode *DirectoryNode::advanceToMP3(const uint16_t id)
|
||||
if (id == ids[i])
|
||||
{
|
||||
// Found the current MP3 file
|
||||
currentPlaying = mp3Files[i];
|
||||
currentPlaying = buildFullPath(mp3Files[i]);
|
||||
currentPlayingId = id;
|
||||
return this;
|
||||
}
|
||||
@@ -296,7 +329,7 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String &songName)
|
||||
{
|
||||
if (isAbsolutePath)
|
||||
{
|
||||
if (mp3Files[i].equalsIgnoreCase(songName))
|
||||
if (buildFullPath(mp3Files[i]).equalsIgnoreCase(songName))
|
||||
{
|
||||
setCurrentPlaying(mp3Files[i]);
|
||||
return this;
|
||||
@@ -317,13 +350,10 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String &songName)
|
||||
// Then search in subdirectories
|
||||
for (auto subdir : subdirectories)
|
||||
{
|
||||
// Absolute folder target: match directory by its full path derived from its files
|
||||
if (isAbsolutePath && subdir->mp3Files.size() > 0)
|
||||
// Absolute folder target: match directory by its full path (dirPath)
|
||||
if (isAbsolutePath)
|
||||
{
|
||||
String anyFile = subdir->mp3Files[0];
|
||||
int lastSlash = anyFile.lastIndexOf('/');
|
||||
String subdirPath = (lastSlash >= 0) ? anyFile.substring(0, lastSlash) : String();
|
||||
if (subdirPath.equalsIgnoreCase(normalizedPath))
|
||||
if (subdir->getDirPath().equalsIgnoreCase(normalizedPath))
|
||||
{
|
||||
subdir->advanceToFirstMP3InThisNode();
|
||||
return subdir;
|
||||
@@ -342,7 +372,7 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String &songName)
|
||||
|
||||
if (isAbsolutePath)
|
||||
{
|
||||
if (subdir->mp3Files[i].equalsIgnoreCase(songName))
|
||||
if (subdir->buildFullPath(subdir->mp3Files[i]).equalsIgnoreCase(songName))
|
||||
{
|
||||
subdir->setCurrentPlaying(subdir->mp3Files[i]);
|
||||
return subdir;
|
||||
@@ -401,7 +431,7 @@ DirectoryNode *DirectoryNode::goToPreviousMP3(uint32_t thresholdSeconds)
|
||||
int currentIndex = -1;
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
if (currentPlaying == mp3Files[i])
|
||||
if (currentPlaying == buildFullPath(mp3Files[i]))
|
||||
{
|
||||
currentIndex = i;
|
||||
break;
|
||||
@@ -412,7 +442,7 @@ DirectoryNode *DirectoryNode::goToPreviousMP3(uint32_t thresholdSeconds)
|
||||
if (currentIndex > 0)
|
||||
{
|
||||
Serial.print(F("goToPreviousMP3: Moving to previous song in same directory: "));
|
||||
Serial.println(mp3Files[currentIndex - 1]);
|
||||
Serial.println(buildFullPath(mp3Files[currentIndex - 1]));
|
||||
setCurrentPlaying(mp3Files[currentIndex - 1]);
|
||||
return this;
|
||||
}
|
||||
@@ -441,7 +471,7 @@ DirectoryNode *DirectoryNode::findPreviousMP3Globally(const String ¤tGloba
|
||||
{
|
||||
DirectoryNode *node = allMP3s[i].first;
|
||||
int fileIndex = allMP3s[i].second;
|
||||
if (node->mp3Files[fileIndex] == currentGlobal)
|
||||
if (node->buildFullPath(node->mp3Files[fileIndex]) == currentGlobal)
|
||||
{
|
||||
currentGlobalIndex = i;
|
||||
break;
|
||||
@@ -455,7 +485,7 @@ DirectoryNode *DirectoryNode::findPreviousMP3Globally(const String ¤tGloba
|
||||
int prevFileIndex = allMP3s[currentGlobalIndex - 1].second;
|
||||
|
||||
Serial.print(F("findPreviousMP3Globally: Moving to previous song globally: "));
|
||||
Serial.println(prevNode->mp3Files[prevFileIndex]);
|
||||
Serial.println(prevNode->buildFullPath(prevNode->mp3Files[prevFileIndex]));
|
||||
|
||||
prevNode->setCurrentPlaying(prevNode->mp3Files[prevFileIndex]);
|
||||
return prevNode;
|
||||
@@ -495,7 +525,7 @@ DirectoryNode *DirectoryNode::advanceToNextMP3(const String ¤tGlobal)
|
||||
{
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
if (currentGlobal == mp3Files[i])
|
||||
if (currentGlobal == buildFullPath(mp3Files[i]))
|
||||
{
|
||||
// Found the current playing MP3 file
|
||||
if (i < mp3Files.size() - 1)
|
||||
@@ -525,7 +555,7 @@ DirectoryNode *DirectoryNode::advanceToNextMP3(const String ¤tGlobal)
|
||||
// Have each subdirectory advance its song
|
||||
for (size_t i = 0; i < subdir->mp3Files.size(); i++)
|
||||
{
|
||||
if (currentGlobal == subdir->mp3Files[i])
|
||||
if (currentGlobal == subdir->buildFullPath(subdir->mp3Files[i]))
|
||||
{
|
||||
// Found the current playing MP3 file
|
||||
if (i < subdir->mp3Files.size() - 1)
|
||||
@@ -573,10 +603,10 @@ void DirectoryNode::streamDirectoryHTML(Print &out) const {
|
||||
out.print(F("<li data-id=\""));
|
||||
out.print(ids[i]);
|
||||
out.print(F("\">"));
|
||||
out.print(mp3Files[i]);
|
||||
out.print(buildFullPath(mp3Files[i]));
|
||||
out.println(F("</li>"));
|
||||
#ifdef DEBUG
|
||||
Serial.printf("stream song: %s\n",mp3Files[i].c_str());
|
||||
Serial.printf("stream song: %s\n", buildFullPath(mp3Files[i]).c_str());
|
||||
#endif
|
||||
// Yield every few items to allow the async web server to send buffered data
|
||||
if (i % 5 == 4) {
|
||||
|
||||
Reference in New Issue
Block a user