cache Course::GetCourseInfo results

This commit is contained in:
Glenn Maynard
2003-12-21 02:54:23 +00:00
parent be307e76bd
commit ef6b831ea3
6 changed files with 60 additions and 11 deletions
+33 -5
View File
@@ -548,29 +548,42 @@ static vector<Song*> GetFilteredBestSongs( StepsType nt )
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
{
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: */
RandomGen rnd( GAMESTATE->m_iRoundSeed + GetHashForString(m_sName) );
vector<CourseEntry> tmp_entries;
if( m_bRandomize )
{
/* 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
* 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. */
bool bMostPlayedSet = false;
vector<Song*> vSongsByMostPlayed;
vector<Song*> AllSongsShuffled = SONGMAN->GetAllSongs();
random_shuffle( AllSongsShuffled.begin(), AllSongsShuffled.end(), rnd );
int CurSong = 0; /* Current offset into AllSongsShuffled */
bool bShuffledSet = false;
vector<Song*> AllSongsShuffled;
int CurSong = 0; /* Current offset into AllSongsShuffled */
ci.clear();
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_WITHIN_GROUP:
{
if( !bShuffledSet )
{
AllSongsShuffled = SONGMAN->GetAllSongs();
random_shuffle( AllSongsShuffled.begin(), AllSongsShuffled.end(), rnd );
bShuffledSet = true;
}
// find a song with the notes we want
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);
ci.push_back( cinfo );
}
/* Cache results. */
m_InfoCache[params] = ci;
}
void Course::ClearCache()
{
m_InfoCache.clear();
}
RageColor Course::GetColor() const
+9
View File
@@ -14,6 +14,7 @@
#include "PlayerNumber.h"
#include "GameConstantsAndTypes.h"
#include "Attack.h"
#include <map>
struct PlayerOptions;
struct SongOptions;
@@ -196,8 +197,16 @@ public:
void UpdateCourseStats();
/* Call per-screen, and if song or notes pointers change: */
void ClearCache();
private:
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;
};
+4 -3
View File
@@ -477,6 +477,10 @@ Screen* ScreenManager::MakeNewScreen( CString sClassName )
* screens turn this off in their ctor if they handle timers themselves (gameplay, edit). */
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 );
/* Loading probably took a little while. Let's reset stats. This prevents us
@@ -485,9 +489,6 @@ Screen* ScreenManager::MakeNewScreen( CString sClassName )
* apparent. */
DISPLAY->ResetStats();
/* This is a convenient time to clean up our song cache. */
SONGMAN->CompressSongs();
return ret;
}
+5
View File
@@ -19,6 +19,7 @@
#include "NoteData.h"
#include "RageSound.h"
#include "RageException.h"
#include "SongManager.h"
#include "SongCacheIndex.h"
#include "GameManager.h"
#include "PrefsManager.h"
@@ -100,6 +101,10 @@ void Song::Reset()
Song 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();
}
+7 -2
View File
@@ -567,9 +567,10 @@ void SongManager::FreeCourses()
/* Called periodically to wipe out cached NoteData. This is called when we change
* 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];
for( unsigned n=0; n<pSong->m_apNotes.size(); n++ )
@@ -578,6 +579,10 @@ void SongManager::CompressSongs()
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 )
+2 -1
View File
@@ -34,7 +34,8 @@ public:
void InitSongsFromDisk( LoadingWindow *ld );
void FreeSongs();
void CompressSongs();
void Cleanup();
void LoadGroupSymLinks( CString sDir, CString sGroupFolder );
void InitCoursesFromDisk( LoadingWindow *ld );