cache Course::GetCourseInfo results
This commit is contained in:
@@ -548,29 +548,42 @@ static vector<Song*> GetFilteredBestSongs( StepsType nt )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is called by many simple functions, like Course::GetTotalSeconds, and may
|
||||||
|
* be called on all songs to sort. It can take time to execute, so we cache the
|
||||||
|
* results. */
|
||||||
void Course::GetCourseInfo( StepsType nt, vector<Course::Info> &ci, int Difficult ) const
|
void Course::GetCourseInfo( StepsType nt, vector<Course::Info> &ci, int Difficult ) const
|
||||||
{
|
{
|
||||||
vector<CourseEntry> entries = m_entries;
|
const InfoParams params( nt, IsDifficult(Difficult) );
|
||||||
|
InfoCache::const_iterator it = m_InfoCache.find( params );
|
||||||
|
if( it != m_InfoCache.end() )
|
||||||
|
{
|
||||||
|
ci = it->second;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Different seed for each course, but the same for the whole round: */
|
/* Different seed for each course, but the same for the whole round: */
|
||||||
RandomGen rnd( GAMESTATE->m_iRoundSeed + GetHashForString(m_sName) );
|
RandomGen rnd( GAMESTATE->m_iRoundSeed + GetHashForString(m_sName) );
|
||||||
|
|
||||||
|
vector<CourseEntry> tmp_entries;
|
||||||
if( m_bRandomize )
|
if( m_bRandomize )
|
||||||
{
|
{
|
||||||
/* Always randomize the same way per round. Otherwise, the displayed course
|
/* Always randomize the same way per round. Otherwise, the displayed course
|
||||||
* will change every time it's viewed, and the displayed order will have no
|
* will change every time it's viewed, and the displayed order will have no
|
||||||
* bearing on what you'll actually play. */
|
* bearing on what you'll actually play. */
|
||||||
random_shuffle( entries.begin(), entries.end(), rnd );
|
tmp_entries = m_entries;
|
||||||
|
random_shuffle( tmp_entries.begin(), tmp_entries.end(), rnd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const vector<CourseEntry> &entries = m_bRandomize? tmp_entries:m_entries;
|
||||||
|
|
||||||
/* This can take some time, so don't fill it out unless we need it. */
|
/* This can take some time, so don't fill it out unless we need it. */
|
||||||
bool bMostPlayedSet = false;
|
bool bMostPlayedSet = false;
|
||||||
vector<Song*> vSongsByMostPlayed;
|
vector<Song*> vSongsByMostPlayed;
|
||||||
|
|
||||||
vector<Song*> AllSongsShuffled = SONGMAN->GetAllSongs();
|
bool bShuffledSet = false;
|
||||||
random_shuffle( AllSongsShuffled.begin(), AllSongsShuffled.end(), rnd );
|
vector<Song*> AllSongsShuffled;
|
||||||
int CurSong = 0; /* Current offset into AllSongsShuffled */
|
|
||||||
|
|
||||||
|
int CurSong = 0; /* Current offset into AllSongsShuffled */
|
||||||
ci.clear();
|
ci.clear();
|
||||||
|
|
||||||
for( unsigned i=0; i<entries.size(); i++ )
|
for( unsigned i=0; i<entries.size(); i++ )
|
||||||
@@ -602,6 +615,13 @@ void Course::GetCourseInfo( StepsType nt, vector<Course::Info> &ci, int Difficul
|
|||||||
case COURSE_ENTRY_RANDOM:
|
case COURSE_ENTRY_RANDOM:
|
||||||
case COURSE_ENTRY_RANDOM_WITHIN_GROUP:
|
case COURSE_ENTRY_RANDOM_WITHIN_GROUP:
|
||||||
{
|
{
|
||||||
|
if( !bShuffledSet )
|
||||||
|
{
|
||||||
|
AllSongsShuffled = SONGMAN->GetAllSongs();
|
||||||
|
random_shuffle( AllSongsShuffled.begin(), AllSongsShuffled.end(), rnd );
|
||||||
|
bShuffledSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
// find a song with the notes we want
|
// find a song with the notes we want
|
||||||
for( unsigned j=0; j<AllSongsShuffled.size(); j++ )
|
for( unsigned j=0; j<AllSongsShuffled.size(); j++ )
|
||||||
{
|
{
|
||||||
@@ -695,6 +715,14 @@ void Course::GetCourseInfo( StepsType nt, vector<Course::Info> &ci, int Difficul
|
|||||||
cinfo.Difficult = IsDifficult(Difficult);
|
cinfo.Difficult = IsDifficult(Difficult);
|
||||||
ci.push_back( cinfo );
|
ci.push_back( cinfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cache results. */
|
||||||
|
m_InfoCache[params] = ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Course::ClearCache()
|
||||||
|
{
|
||||||
|
m_InfoCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
RageColor Course::GetColor() const
|
RageColor Course::GetColor() const
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "PlayerNumber.h"
|
#include "PlayerNumber.h"
|
||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
#include "Attack.h"
|
#include "Attack.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
struct PlayerOptions;
|
struct PlayerOptions;
|
||||||
struct SongOptions;
|
struct SongOptions;
|
||||||
@@ -196,8 +197,16 @@ public:
|
|||||||
|
|
||||||
void UpdateCourseStats();
|
void UpdateCourseStats();
|
||||||
|
|
||||||
|
/* Call per-screen, and if song or notes pointers change: */
|
||||||
|
void ClearCache();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut, int Difficult = -1 ) const;
|
void GetMeterRange( int stage, int& iMeterLowOut, int& iMeterHighOut, int Difficult = -1 ) const;
|
||||||
|
|
||||||
|
typedef pair<StepsType,bool> InfoParams;
|
||||||
|
typedef vector<Course::Info> InfoData;
|
||||||
|
typedef map<InfoParams, InfoData> InfoCache;
|
||||||
|
mutable InfoCache m_InfoCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -477,6 +477,10 @@ Screen* ScreenManager::MakeNewScreen( CString sClassName )
|
|||||||
* screens turn this off in their ctor if they handle timers themselves (gameplay, edit). */
|
* screens turn this off in their ctor if they handle timers themselves (gameplay, edit). */
|
||||||
SOUND->HandleSongTimer( true );
|
SOUND->HandleSongTimer( true );
|
||||||
|
|
||||||
|
/* Cleanup song data. This can free up a fair bit of memory, so do it before
|
||||||
|
* creating the new screen, to lower peak memory usage slightly. */
|
||||||
|
SONGMAN->Cleanup();
|
||||||
|
|
||||||
Screen *ret = Screen::Create( sClassName );
|
Screen *ret = Screen::Create( sClassName );
|
||||||
|
|
||||||
/* Loading probably took a little while. Let's reset stats. This prevents us
|
/* Loading probably took a little while. Let's reset stats. This prevents us
|
||||||
@@ -485,9 +489,6 @@ Screen* ScreenManager::MakeNewScreen( CString sClassName )
|
|||||||
* apparent. */
|
* apparent. */
|
||||||
DISPLAY->ResetStats();
|
DISPLAY->ResetStats();
|
||||||
|
|
||||||
/* This is a convenient time to clean up our song cache. */
|
|
||||||
SONGMAN->CompressSongs();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "NoteData.h"
|
#include "NoteData.h"
|
||||||
#include "RageSound.h"
|
#include "RageSound.h"
|
||||||
#include "RageException.h"
|
#include "RageException.h"
|
||||||
|
#include "SongManager.h"
|
||||||
#include "SongCacheIndex.h"
|
#include "SongCacheIndex.h"
|
||||||
#include "GameManager.h"
|
#include "GameManager.h"
|
||||||
#include "PrefsManager.h"
|
#include "PrefsManager.h"
|
||||||
@@ -100,6 +101,10 @@ void Song::Reset()
|
|||||||
|
|
||||||
Song empty;
|
Song empty;
|
||||||
*this = empty;
|
*this = empty;
|
||||||
|
|
||||||
|
/* Courses cache Notes* pointers. On the off chance that this isn't the last
|
||||||
|
* thing this screen does, clear that cache. */
|
||||||
|
SONGMAN->Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -567,9 +567,10 @@ void SongManager::FreeCourses()
|
|||||||
|
|
||||||
/* Called periodically to wipe out cached NoteData. This is called when we change
|
/* Called periodically to wipe out cached NoteData. This is called when we change
|
||||||
* screens. */
|
* screens. */
|
||||||
void SongManager::CompressSongs()
|
void SongManager::Cleanup()
|
||||||
{
|
{
|
||||||
for( unsigned i=0; i<m_pSongs.size(); i++ )
|
unsigned i;
|
||||||
|
for( i=0; i<m_pSongs.size(); i++ )
|
||||||
{
|
{
|
||||||
Song* pSong = m_pSongs[i];
|
Song* pSong = m_pSongs[i];
|
||||||
for( unsigned n=0; n<pSong->m_apNotes.size(); n++ )
|
for( unsigned n=0; n<pSong->m_apNotes.size(); n++ )
|
||||||
@@ -578,6 +579,10 @@ void SongManager::CompressSongs()
|
|||||||
pNotes->Compress();
|
pNotes->Compress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Erase cached course info. */
|
||||||
|
for( i=0; i < m_pCourses.size(); i++ )
|
||||||
|
m_pCourses[i]->ClearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SongManager::GetAllCourses( vector<Course*> &AddTo, bool bIncludeAutogen )
|
void SongManager::GetAllCourses( vector<Course*> &AddTo, bool bIncludeAutogen )
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ public:
|
|||||||
|
|
||||||
void InitSongsFromDisk( LoadingWindow *ld );
|
void InitSongsFromDisk( LoadingWindow *ld );
|
||||||
void FreeSongs();
|
void FreeSongs();
|
||||||
void CompressSongs();
|
void Cleanup();
|
||||||
|
|
||||||
void LoadGroupSymLinks( CString sDir, CString sGroupFolder );
|
void LoadGroupSymLinks( CString sDir, CString sGroupFolder );
|
||||||
|
|
||||||
void InitCoursesFromDisk( LoadingWindow *ld );
|
void InitCoursesFromDisk( LoadingWindow *ld );
|
||||||
|
|||||||
Reference in New Issue
Block a user