From fbed947b9c4603b0664d52a3326c7742dce075ef Mon Sep 17 00:00:00 2001
From: teejusb <5017202+teejusb@users.noreply.github.com>
Date: Tue, 14 Mar 2023 12:02:21 -0700
Subject: [PATCH] Allow PreferredSongs/PreferredCourses to be set from absolute
paths
---
Docs/Luadoc/LuaDocumentation.xml | 12 +-
src/SongManager.cpp | 374 +++++++++++++++++--------------
src/SongManager.h | 2 +
3 files changed, 212 insertions(+), 176 deletions(-)
diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml
index 72c55222ce..38a87e6587 100644
--- a/Docs/Luadoc/LuaDocumentation.xml
+++ b/Docs/Luadoc/LuaDocumentation.xml
@@ -5888,11 +5888,15 @@ local args = {
Returns the shortened group name (based on entries in Translations.xml).
-
- Loads preferred courses from {theme}/Other/SongManager sListName.txt.
+
+ By default, loads preferred courses from {theme}/Other/SongManager sListName.txt.
+ (New since ITGmania 0.5.2) If the optional argument bIsAbsolute is set, instead treats
+ sListName as an absolute path instead of loading it from the Theme's Other directory.
-
- Loads preferred songs from {theme}/Other/SongManager sListName.txt.
+
+ By default, loads preferred songs from {theme}/Other/SongManager sListName.txt.
+ (New since ITGmania 0.5.2) If the optional argument bIsAbsolute is set, instead treats
+ sListName as an absolute path instead of loading it from the Theme's Other directory.
Returns the preferred sort section name for the specified Song.
diff --git a/src/SongManager.cpp b/src/SongManager.cpp
index e6de89464f..75208985b4 100644
--- a/src/SongManager.cpp
+++ b/src/SongManager.cpp
@@ -1593,188 +1593,202 @@ void SongManager::UpdateShuffled()
std::shuffle( m_pShuffledCourses.begin(), m_pShuffledCourses.end(), g_RandomNumberGenerator );
}
-void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferredCourses)
+void SongManager::SetPreferredSongs(RString sPreferredSongs, bool bIsAbsolute) {
+ ASSERT( UNLOCKMAN != nullptr );
+
+ m_vPreferredSongSort.clear();
+
+ std::vector asLines;
+ RString sFile = sPreferredSongs;
+ if (!bIsAbsolute)
+ sFile = THEME->GetPathO( "SongManager", sPreferredSongs );
+ GetFileContents( sFile, asLines );
+ if( asLines.empty() )
+ return;
+
+ PreferredSortSection section;
+ std::map mapSongToPri;
+
+ for (RString sLine : asLines)
+ {
+ bool bSectionDivider = BeginsWith(sLine, "---");
+ if( bSectionDivider )
+ {
+ if( !section.vpSongs.empty() )
+ {
+ m_vPreferredSongSort.push_back( section );
+ section = PreferredSortSection();
+ }
+
+ section.sName = sLine.Right( sLine.length() - RString("---").length() );
+ TrimLeft( section.sName );
+ TrimRight( section.sName );
+ }
+ else
+ {
+ /* if the line ends in slash-star, check if the section exists,
+ * and if it does, add all the songs in that group to the list. */
+ if( EndsWith(sLine,"/*") )
+ {
+ RString group = sLine.Left( sLine.length() - RString("/*").length() );
+ if( DoesSongGroupExist(group) )
+ {
+ // add all songs in group
+ const std::vector &vSongs = GetSongs( group );
+ for (Song *song : vSongs)
+ {
+ if( UNLOCKMAN->SongIsLocked(song) & LOCKED_SELECTABLE )
+ continue;
+ section.vpSongs.push_back( song );
+ }
+ }
+ }
+
+ Song *pSong = FindSong( sLine );
+ if( pSong == nullptr )
+ continue;
+ if( UNLOCKMAN->SongIsLocked(pSong) & LOCKED_SELECTABLE )
+ continue;
+ section.vpSongs.push_back( pSong );
+ }
+ }
+
+ if( !section.vpSongs.empty() )
+ {
+ m_vPreferredSongSort.push_back( section );
+ section = PreferredSortSection();
+ }
+
+ if( MOVE_UNLOCKS_TO_BOTTOM_OF_PREFERRED_SORT.GetValue() )
+ {
+ // move all unlock songs to a group at the bottom
+ PreferredSortSection PFSection;
+ PFSection.sName = "Unlocks";
+ for (UnlockEntry const &ue : UNLOCKMAN->m_UnlockEntries)
+ {
+ if( ue.m_Type == UnlockRewardType_Song )
+ {
+ Song *pSong = ue.m_Song.ToSong();
+ if( pSong )
+ PFSection.vpSongs.push_back( pSong );
+ }
+ }
+
+ for (std::vector::iterator v = m_vPreferredSongSort.begin(); v != m_vPreferredSongSort.end(); ++v)
+ {
+ for( int i=v->vpSongs.size()-1; i>=0; i-- )
+ {
+ Song *pSong = v->vpSongs[i];
+ if( find(PFSection.vpSongs.begin(),PFSection.vpSongs.end(),pSong) != PFSection.vpSongs.end() )
+ {
+ v->vpSongs.erase( v->vpSongs.begin()+i );
+ }
+ }
+ }
+
+ m_vPreferredSongSort.push_back( PFSection );
+ }
+
+ // prune empty groups
+ for( int i=m_vPreferredSongSort.size()-1; i>=0; i-- )
+ if( m_vPreferredSongSort[i].vpSongs.empty() )
+ m_vPreferredSongSort.erase( m_vPreferredSongSort.begin()+i );
+
+ for (PreferredSortSection const &i : m_vPreferredSongSort)
+ {
+ for (Song const *j : i.vpSongs)
+ {
+ ASSERT( j != nullptr );
+ }
+ }
+}
+
+void SongManager::SetPreferredCourses(RString sPreferredCourses, bool bIsAbsolute)
{
ASSERT( UNLOCKMAN != nullptr );
+ m_vPreferredCourseSort.clear();
+
+ std::vector asLines;
+ RString sFile = sPreferredCourses;
+ if (!bIsAbsolute)
+ sFile = THEME->GetPathO( "SongManager", sPreferredCourses );
+ if( !GetFileContents(sFile, asLines) )
+ return;
+
+ std::vector vpCourses;
+
+ for (RString sLine : asLines)
{
- m_vPreferredSongSort.clear();
-
- std::vector asLines;
- RString sFile = THEME->GetPathO( "SongManager", sPreferredSongs );
- GetFileContents( sFile, asLines );
- if( asLines.empty() )
- return;
-
- PreferredSortSection section;
- std::map mapSongToPri;
-
- for (RString sLine : asLines)
+ bool bSectionDivider = BeginsWith( sLine, "---" );
+ if( bSectionDivider )
{
- bool bSectionDivider = BeginsWith(sLine, "---");
- if( bSectionDivider )
+ if( !vpCourses.empty() )
{
- if( !section.vpSongs.empty() )
- {
- m_vPreferredSongSort.push_back( section );
- section = PreferredSortSection();
- }
-
- section.sName = sLine.Right( sLine.length() - RString("---").length() );
- TrimLeft( section.sName );
- TrimRight( section.sName );
- }
- else
- {
- /* if the line ends in slash-star, check if the section exists,
- * and if it does, add all the songs in that group to the list. */
- if( EndsWith(sLine,"/*") )
- {
- RString group = sLine.Left( sLine.length() - RString("/*").length() );
- if( DoesSongGroupExist(group) )
- {
- // add all songs in group
- const std::vector &vSongs = GetSongs( group );
- for (Song *song : vSongs)
- {
- if( UNLOCKMAN->SongIsLocked(song) & LOCKED_SELECTABLE )
- continue;
- section.vpSongs.push_back( song );
- }
- }
- }
-
- Song *pSong = FindSong( sLine );
- if( pSong == nullptr )
- continue;
- if( UNLOCKMAN->SongIsLocked(pSong) & LOCKED_SELECTABLE )
- continue;
- section.vpSongs.push_back( pSong );
+ m_vPreferredCourseSort.push_back( vpCourses );
+ vpCourses.clear();
}
+ continue;
}
- if( !section.vpSongs.empty() )
- {
- m_vPreferredSongSort.push_back( section );
- section = PreferredSortSection();
- }
-
- if( MOVE_UNLOCKS_TO_BOTTOM_OF_PREFERRED_SORT.GetValue() )
- {
- // move all unlock songs to a group at the bottom
- PreferredSortSection PFSection;
- PFSection.sName = "Unlocks";
- for (UnlockEntry const &ue : UNLOCKMAN->m_UnlockEntries)
- {
- if( ue.m_Type == UnlockRewardType_Song )
- {
- Song *pSong = ue.m_Song.ToSong();
- if( pSong )
- PFSection.vpSongs.push_back( pSong );
- }
- }
-
- for (std::vector::iterator v = m_vPreferredSongSort.begin(); v != m_vPreferredSongSort.end(); ++v)
- {
- for( int i=v->vpSongs.size()-1; i>=0; i-- )
- {
- Song *pSong = v->vpSongs[i];
- if( find(PFSection.vpSongs.begin(),PFSection.vpSongs.end(),pSong) != PFSection.vpSongs.end() )
- {
- v->vpSongs.erase( v->vpSongs.begin()+i );
- }
- }
- }
-
- m_vPreferredSongSort.push_back( PFSection );
- }
-
- // prune empty groups
- for( int i=m_vPreferredSongSort.size()-1; i>=0; i-- )
- if( m_vPreferredSongSort[i].vpSongs.empty() )
- m_vPreferredSongSort.erase( m_vPreferredSongSort.begin()+i );
-
- for (PreferredSortSection const &i : m_vPreferredSongSort)
- for (Song const *j : i.vpSongs)
- {
- ASSERT( j != nullptr );
- }
+ Course *pCourse = FindCourse( sLine );
+ if( pCourse == nullptr )
+ continue;
+ if( UNLOCKMAN->CourseIsLocked(pCourse) & LOCKED_SELECTABLE )
+ continue;
+ vpCourses.push_back( pCourse );
}
+ if( !vpCourses.empty() )
{
- m_vPreferredCourseSort.clear();
-
- std::vector asLines;
- RString sFile = THEME->GetPathO( "SongManager", sPreferredCourses );
- if( !GetFileContents(sFile, asLines) )
- return;
-
- std::vector vpCourses;
-
- for (RString sLine : asLines)
- {
- bool bSectionDivider = BeginsWith( sLine, "---" );
- if( bSectionDivider )
- {
- if( !vpCourses.empty() )
- {
- m_vPreferredCourseSort.push_back( vpCourses );
- vpCourses.clear();
- }
- continue;
- }
-
- Course *pCourse = FindCourse( sLine );
- if( pCourse == nullptr )
- continue;
- if( UNLOCKMAN->CourseIsLocked(pCourse) & LOCKED_SELECTABLE )
- continue;
- vpCourses.push_back( pCourse );
- }
-
- if( !vpCourses.empty() )
- {
- m_vPreferredCourseSort.push_back( vpCourses );
- vpCourses.clear();
- }
-
- if( MOVE_UNLOCKS_TO_BOTTOM_OF_PREFERRED_SORT.GetValue() )
- {
- // move all unlock Courses to a group at the bottom
- std::vector vpUnlockCourses;
- for (UnlockEntry const &ue : UNLOCKMAN->m_UnlockEntries)
- {
- if( ue.m_Type == UnlockRewardType_Course )
- if( ue.m_Course.IsValid() )
- vpUnlockCourses.push_back( ue.m_Course.ToCourse() );
- }
-
- for (auto v = m_vPreferredCourseSort.begin(); v != m_vPreferredCourseSort.end(); ++v)
- {
- for( int i=v->size()-1; i>=0; i-- )
- {
- Course *pCourse = (*v)[i];
- if( find(vpUnlockCourses.begin(),vpUnlockCourses.end(),pCourse) != vpUnlockCourses.end() )
- {
- v->erase( v->begin()+i );
- }
- }
- }
-
- m_vPreferredCourseSort.push_back( vpUnlockCourses );
- }
-
- // prune empty groups
- for( int i=m_vPreferredCourseSort.size()-1; i>=0; i-- )
- if( m_vPreferredCourseSort[i].empty() )
- m_vPreferredCourseSort.erase( m_vPreferredCourseSort.begin()+i );
-
- for (CoursePointerVector const &i : m_vPreferredCourseSort)
- for (Course *j : i)
- {
- ASSERT( j != nullptr );
- }
+ m_vPreferredCourseSort.push_back( vpCourses );
+ vpCourses.clear();
}
+
+ if( MOVE_UNLOCKS_TO_BOTTOM_OF_PREFERRED_SORT.GetValue() )
+ {
+ // move all unlock Courses to a group at the bottom
+ std::vector vpUnlockCourses;
+ for (UnlockEntry const &ue : UNLOCKMAN->m_UnlockEntries)
+ {
+ if( ue.m_Type == UnlockRewardType_Course )
+ if( ue.m_Course.IsValid() )
+ vpUnlockCourses.push_back( ue.m_Course.ToCourse() );
+ }
+
+ for (auto v = m_vPreferredCourseSort.begin(); v != m_vPreferredCourseSort.end(); ++v)
+ {
+ for( int i=v->size()-1; i>=0; i-- )
+ {
+ Course *pCourse = (*v)[i];
+ if( find(vpUnlockCourses.begin(),vpUnlockCourses.end(),pCourse) != vpUnlockCourses.end() )
+ {
+ v->erase( v->begin()+i );
+ }
+ }
+ }
+
+ m_vPreferredCourseSort.push_back( vpUnlockCourses );
+ }
+
+ // prune empty groups
+ for( int i=m_vPreferredCourseSort.size()-1; i>=0; i-- )
+ if( m_vPreferredCourseSort[i].empty() )
+ m_vPreferredCourseSort.erase( m_vPreferredCourseSort.begin()+i );
+
+ for (CoursePointerVector const &i : m_vPreferredCourseSort)
+ {
+ for (Course *j : i)
+ {
+ ASSERT( j != nullptr );
+ }
+ }
+}
+
+void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferredCourses)
+{
+ SetPreferredSongs(sPreferredSongs);
+ SetPreferredCourses(sPreferredCourses);
}
void SongManager::SortSongs()
@@ -2026,13 +2040,29 @@ class LunaSongManager: public Luna
public:
static int SetPreferredSongs( T* p, lua_State *L )
{
- p->UpdatePreferredSort( SArg(1), "PreferredCourses.txt" );
+ RString sPreferredSongs = SArg(1);
+ if ( lua_gettop(L) >= 2 && !lua_isnil(L, 2) )
+ {
+ p->SetPreferredSongs( sPreferredSongs, BArg(2) );
+ }
+ else
+ {
+ p->SetPreferredSongs( sPreferredSongs );
+ }
+
COMMON_RETURN_SELF;
}
-
static int SetPreferredCourses( T* p, lua_State *L )
{
- p->UpdatePreferredSort( "PreferredSongs.txt", SArg(1) );
+ RString sPreferredCourses = SArg(1);
+ if ( lua_gettop(L) >= 2 && !lua_isnil(L, 2) )
+ {
+ p->SetPreferredSongs( sPreferredCourses, BArg(2) );
+ }
+ else
+ {
+ p->SetPreferredSongs( sPreferredCourses );
+ }
COMMON_RETURN_SELF;
}
static int GetAllSongs( T* p, lua_State *L )
diff --git a/src/SongManager.h b/src/SongManager.h
index d7010ea697..1d7541d5b7 100644
--- a/src/SongManager.h
+++ b/src/SongManager.h
@@ -179,6 +179,8 @@ public:
void UpdatePopular();
void UpdateShuffled(); // re-shuffle songs and courses
+ void SetPreferredSongs(RString sPreferredSongs = "PreferredSongs.txt", bool bIsAbsolute = false);
+ void SetPreferredCourses(RString sPreferredCourses = "PreferredCourses.txt", bool bIsAbsolute = false);
void UpdatePreferredSort(RString sPreferredSongs = "PreferredSongs.txt", RString sPreferredCourses = "PreferredCourses.txt");
void SortSongs(); // sort m_pSongs by CompareSongPointersByTitle