[ai] quickwin memory optimiziations, wip
This commit is contained in:
parent
465e34e919
commit
3a34b1b8d0
|
|
@ -37,19 +37,20 @@ const std::vector<String> &DirectoryNode::getMP3Files() const
|
|||
return mp3Files;
|
||||
}
|
||||
|
||||
void DirectoryNode::setCurrentPlaying(const String mp3File)
|
||||
void DirectoryNode::setCurrentPlaying(const String &mp3File)
|
||||
{
|
||||
currentPlaying = mp3File;
|
||||
for (int i = 0; i < mp3Files.size(); i++)
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
if (mp3Files[i] == mp3File && ids.size() > i)
|
||||
{
|
||||
currentPlayingId = ids[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const String DirectoryNode::getCurrentPlaying() const
|
||||
const String &DirectoryNode::getCurrentPlaying() const
|
||||
{
|
||||
return currentPlaying;
|
||||
}
|
||||
|
|
@ -82,7 +83,7 @@ void DirectoryNode::setSecondsPlayed(const uint32_t seconds)
|
|||
secondsPlayed = seconds;
|
||||
}
|
||||
|
||||
uint32_t DirectoryNode::getSecondsPlayed()
|
||||
uint32_t DirectoryNode::getSecondsPlayed() const
|
||||
{
|
||||
return secondsPlayed;
|
||||
}
|
||||
|
|
@ -97,6 +98,9 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
|
|||
subdirectories.clear();
|
||||
mp3Files.clear();
|
||||
ids.clear();
|
||||
subdirectories.shrink_to_fit();
|
||||
mp3Files.shrink_to_fit();
|
||||
ids.shrink_to_fit();
|
||||
|
||||
// First collect entries so we can sort them alphabetically
|
||||
std::vector<String> dirNames;
|
||||
|
|
@ -113,27 +117,33 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
|
|||
|
||||
if (entry.isDirectory() && entry.name()[0] != '.' && strcmp(entry.name(), sys_dir))
|
||||
{
|
||||
dirNames.push_back(String(entry.name()));
|
||||
dirNames.emplace_back(entry.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
String entryName = entry.name();
|
||||
if (entryName.endsWith(".mp3") || entryName.endsWith(".MP3"))
|
||||
{
|
||||
fileNames.push_back(entryName);
|
||||
fileNames.push_back(std::move(entryName));
|
||||
}
|
||||
}
|
||||
entry.close();
|
||||
}
|
||||
rootDir.close();
|
||||
|
||||
// Case-insensitive alphabetical sort
|
||||
// Case-insensitive alphabetical sort without allocations
|
||||
auto ciLess = [](const String &a, const String &b) {
|
||||
String al = a;
|
||||
String bl = b;
|
||||
al.toLowerCase();
|
||||
bl.toLowerCase();
|
||||
return al.compareTo(bl) < 0;
|
||||
const char* pa = a.c_str();
|
||||
const char* pb = b.c_str();
|
||||
while (*pa && *pb) {
|
||||
char ca = *pa++;
|
||||
char cb = *pb++;
|
||||
if (ca >= 'A' && ca <= 'Z') ca += 'a' - 'A';
|
||||
if (cb >= 'A' && cb <= 'Z') cb += 'a' - 'A';
|
||||
if (ca < cb) return true;
|
||||
if (ca > cb) return false;
|
||||
}
|
||||
return *pa < *pb;
|
||||
};
|
||||
std::sort(dirNames.begin(), dirNames.end(), ciLess);
|
||||
std::sort(fileNames.begin(), fileNames.end(), ciLess);
|
||||
|
|
@ -165,7 +175,7 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
|
|||
fullPath += "/";
|
||||
fullPath += fileName;
|
||||
|
||||
mp3Files.push_back(fullPath);
|
||||
mp3Files.push_back(std::move(fullPath));
|
||||
ids.push_back(getNextId());
|
||||
}
|
||||
}
|
||||
|
|
@ -174,7 +184,7 @@ void DirectoryNode::printDirectoryTree(int level) const
|
|||
{
|
||||
for (int i = 0; i < level; i++)
|
||||
{
|
||||
Serial.print(" ");
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
Serial.println(name);
|
||||
|
||||
|
|
@ -182,7 +192,7 @@ void DirectoryNode::printDirectoryTree(int level) const
|
|||
{
|
||||
for (int i = 0; i <= level; i++)
|
||||
{
|
||||
Serial.print(" ");
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
Serial.println(mp3File);
|
||||
}
|
||||
|
|
@ -256,15 +266,16 @@ DirectoryNode *DirectoryNode::advanceToMP3(const uint16_t id)
|
|||
}
|
||||
|
||||
// If we get here, no song with this ID was found
|
||||
Serial.println("advanceToMP3: No song found for ID: " + String(id));
|
||||
Serial.print(F("advanceToMP3: No song found for ID: "));
|
||||
Serial.println(id);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DirectoryNode *DirectoryNode::advanceToMP3(const String songName)
|
||||
DirectoryNode *DirectoryNode::advanceToMP3(const String &songName)
|
||||
{
|
||||
if (songName.isEmpty())
|
||||
{
|
||||
Serial.println("advanceToMP3: songName is empty");
|
||||
Serial.println(F("advanceToMP3: songName is empty"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -279,8 +290,6 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String songName)
|
|||
// Lowercased copies for case-insensitive comparisons (FAT can uppercase names)
|
||||
String lowTarget = songName;
|
||||
lowTarget.toLowerCase();
|
||||
String lowNormPath = normalizedPath;
|
||||
lowNormPath.toLowerCase();
|
||||
|
||||
// First, search in the current directory's MP3 files
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
|
|
@ -359,7 +368,8 @@ DirectoryNode *DirectoryNode::advanceToMP3(const String songName)
|
|||
}
|
||||
|
||||
// If we get here, no matching song was found
|
||||
Serial.println("advanceToMP3: No song found for: " + songName);
|
||||
Serial.print(F("advanceToMP3: No song found for: "));
|
||||
Serial.println(songName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -376,14 +386,14 @@ DirectoryNode *DirectoryNode::goToPreviousMP3(uint32_t thresholdSeconds)
|
|||
// Safety check for null pointer
|
||||
if (currentPlaying.isEmpty())
|
||||
{
|
||||
Serial.println("goToPreviousMP3: currentPlaying is empty");
|
||||
Serial.println(F("goToPreviousMP3: currentPlaying is empty"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If we've been playing for more than threshold seconds, restart current song
|
||||
if (secondsPlayed > thresholdSeconds)
|
||||
{
|
||||
Serial.println("goToPreviousMP3: Restarting current song (played > threshold)");
|
||||
Serial.println(F("goToPreviousMP3: Restarting current song (played > threshold)"));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +411,7 @@ DirectoryNode *DirectoryNode::goToPreviousMP3(uint32_t thresholdSeconds)
|
|||
// If current song found and not the first song, move to previous
|
||||
if (currentIndex > 0)
|
||||
{
|
||||
Serial.print("goToPreviousMP3: Moving to previous song in same directory: ");
|
||||
Serial.print(F("goToPreviousMP3: Moving to previous song in same directory: "));
|
||||
Serial.println(mp3Files[currentIndex - 1]);
|
||||
setCurrentPlaying(mp3Files[currentIndex - 1]);
|
||||
return this;
|
||||
|
|
@ -409,15 +419,15 @@ DirectoryNode *DirectoryNode::goToPreviousMP3(uint32_t thresholdSeconds)
|
|||
|
||||
// If we're at the first song or song not found in current directory,
|
||||
// we need to find the previous song globally
|
||||
Serial.println("goToPreviousMP3: At first song or song not found, looking for previous globally");
|
||||
Serial.println(F("goToPreviousMP3: At first song or song not found, looking for previous globally"));
|
||||
return nullptr; // Let the caller handle global previous logic
|
||||
}
|
||||
|
||||
DirectoryNode *DirectoryNode::findPreviousMP3Globally(const String currentGlobal)
|
||||
DirectoryNode *DirectoryNode::findPreviousMP3Globally(const String ¤tGlobal)
|
||||
{
|
||||
if (currentGlobal.isEmpty())
|
||||
{
|
||||
Serial.println("findPreviousMP3Globally: currentGlobal is null");
|
||||
Serial.println(F("findPreviousMP3Globally: currentGlobal is null"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -444,23 +454,25 @@ DirectoryNode *DirectoryNode::findPreviousMP3Globally(const String currentGlobal
|
|||
DirectoryNode *prevNode = allMP3s[currentGlobalIndex - 1].first;
|
||||
int prevFileIndex = allMP3s[currentGlobalIndex - 1].second;
|
||||
|
||||
Serial.print("findPreviousMP3Globally: Moving to previous song globally: ");
|
||||
Serial.print(F("findPreviousMP3Globally: Moving to previous song globally: "));
|
||||
Serial.println(prevNode->mp3Files[prevFileIndex]);
|
||||
|
||||
prevNode->setCurrentPlaying(prevNode->mp3Files[prevFileIndex]);
|
||||
return prevNode;
|
||||
}
|
||||
|
||||
Serial.println("findPreviousMP3Globally: No previous song found globally");
|
||||
Serial.println(F("findPreviousMP3Globally: No previous song found globally"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DirectoryNode::buildFlatMP3List(std::vector<std::pair<DirectoryNode *, int>> &allMP3s)
|
||||
{
|
||||
// Pre-reserve to reduce reallocations
|
||||
allMP3s.reserve(allMP3s.size() + mp3Files.size());
|
||||
// Add all MP3 files from this directory
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
allMP3s.push_back(std::make_pair(this, i));
|
||||
allMP3s.emplace_back(this, i);
|
||||
}
|
||||
|
||||
// Recursively add MP3 files from subdirectories
|
||||
|
|
@ -470,12 +482,12 @@ void DirectoryNode::buildFlatMP3List(std::vector<std::pair<DirectoryNode *, int>
|
|||
}
|
||||
}
|
||||
|
||||
const size_t DirectoryNode::getNumOfFiles()
|
||||
size_t DirectoryNode::getNumOfFiles() const
|
||||
{
|
||||
return subdirectories.size();
|
||||
}
|
||||
|
||||
DirectoryNode *DirectoryNode::advanceToNextMP3(const String currentGlobal)
|
||||
DirectoryNode *DirectoryNode::advanceToNextMP3(const String ¤tGlobal)
|
||||
{
|
||||
bool useFirst = false;
|
||||
Serial.println(currentGlobal.c_str());
|
||||
|
|
@ -534,7 +546,7 @@ DirectoryNode *DirectoryNode::advanceToNextMP3(const String currentGlobal)
|
|||
|
||||
// If we get here, there were no MP3 files or subdirectories left to check
|
||||
currentPlaying = "";
|
||||
Serial.println("no more nodes found");
|
||||
Serial.println(F("no more nodes found"));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -581,6 +593,3 @@ void DirectoryNode::streamDirectoryHTML(Print &out) const {
|
|||
yield(); // Final yield before completing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ public:
|
|||
const std::vector<DirectoryNode*>& getSubdirectories() const;
|
||||
const std::vector<String>& getMP3Files() const;
|
||||
|
||||
const size_t getNumOfFiles();
|
||||
size_t getNumOfFiles() const;
|
||||
|
||||
void setCurrentPlaying(const String mp3File);
|
||||
const String getCurrentPlaying() const;
|
||||
void setCurrentPlaying(const String& mp3File);
|
||||
const String& getCurrentPlaying() const;
|
||||
const uint16_t getCurrentPlayingId() const;
|
||||
|
||||
void setSecondsPlayed(const uint32_t seconds);
|
||||
uint32_t getSecondsPlayed();
|
||||
uint32_t getSecondsPlayed() const;
|
||||
|
||||
uint16_t getNextId();
|
||||
|
||||
|
|
@ -49,10 +49,10 @@ public:
|
|||
void addMP3File(const String& mp3File);
|
||||
void buildDirectoryTree(const char* currentPath);
|
||||
void printDirectoryTree(int level = 0) const;
|
||||
DirectoryNode* advanceToMP3(const String songName);
|
||||
DirectoryNode* advanceToNextMP3(const String currentGlobal);
|
||||
DirectoryNode* advanceToMP3(const String& songName);
|
||||
DirectoryNode* advanceToNextMP3(const String& currentGlobal);
|
||||
DirectoryNode* goToPreviousMP3(uint32_t thresholdSeconds = 3);
|
||||
DirectoryNode* findPreviousMP3Globally(const String currentGlobal);
|
||||
DirectoryNode* findPreviousMP3Globally(const String& currentGlobal);
|
||||
void buildFlatMP3List(std::vector<std::pair<DirectoryNode*, int>>& allMP3s);
|
||||
DirectoryNode* advanceToMP3(const uint16_t id);
|
||||
void advanceToFirstMP3InThisNode();
|
||||
|
|
|
|||
Loading…
Reference in New Issue