clean up Course cache logic
This commit is contained in:
@@ -256,6 +256,11 @@ void Course::LoadFromCRSFile( CString sPath )
|
|||||||
m_sMainTitleTranslit = title.TitleTranslit;
|
m_sMainTitleTranslit = title.TitleTranslit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Course::RevertFromDisk()
|
||||||
|
{
|
||||||
|
LoadFromCRSFile( m_sPath );
|
||||||
|
}
|
||||||
|
|
||||||
void Course::Init()
|
void Course::Init()
|
||||||
{
|
{
|
||||||
m_bIsAutogen = false;
|
m_bIsAutogen = false;
|
||||||
@@ -898,9 +903,9 @@ void Course::GetTrails( vector<Trail*> &AddTo, StepsType st ) const
|
|||||||
|
|
||||||
bool Course::HasMods() const
|
bool Course::HasMods() const
|
||||||
{
|
{
|
||||||
for( unsigned i=0; i<m_entries.size(); i++ )
|
FOREACH_CONST( CourseEntry, m_entries, e )
|
||||||
{
|
{
|
||||||
if( !m_entries[i].modifiers.empty() || !m_entries[i].attacks.empty() )
|
if( !e->modifiers.empty() || !e->attacks.empty() )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -909,17 +914,44 @@ bool Course::HasMods() const
|
|||||||
|
|
||||||
bool Course::AllSongsAreFixed() const
|
bool Course::AllSongsAreFixed() const
|
||||||
{
|
{
|
||||||
for( unsigned i=0; i<m_entries.size(); i++ )
|
FOREACH_CONST( CourseEntry, m_entries, e )
|
||||||
{
|
{
|
||||||
if( m_entries[i].type != COURSE_ENTRY_FIXED )
|
if( e->type != COURSE_ENTRY_FIXED )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Course::RegenTrails()
|
void Course::Invalidate( Song *pStaleSong )
|
||||||
{
|
{
|
||||||
ZERO( m_TrailCacheValid );
|
FOREACH_CONST( CourseEntry, m_entries, e )
|
||||||
|
{
|
||||||
|
if( e->pSong == pStaleSong ) // a fixed entry that references the stale Song
|
||||||
|
{
|
||||||
|
RevertFromDisk();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalidate any Trails that contain this song.
|
||||||
|
// If we find a Trail that contains this song, then it's part of a
|
||||||
|
// non-fixed entry. So, regenerating the Trail will force different
|
||||||
|
// songs to be chosen.
|
||||||
|
FOREACH_StepsType( st )
|
||||||
|
FOREACH_ShownCourseDifficulty( cd )
|
||||||
|
if( m_TrailCacheValid[st][cd] && !m_TrailCacheNull[st][cd] )
|
||||||
|
if( GetTrail( st, cd )->ContainsSong( pStaleSong ) )
|
||||||
|
m_TrailCacheValid[st][cd] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Course::RegenerateNonFixedTrails()
|
||||||
|
{
|
||||||
|
// Only need to regen Trails if the Course has a random entry.
|
||||||
|
// We can create these Trails on demand because we don't
|
||||||
|
// calculate RadarValues for Trails with one or more non-fixed
|
||||||
|
// entry.
|
||||||
|
if( !IsFixed() )
|
||||||
|
ZERO( m_TrailCacheValid );
|
||||||
}
|
}
|
||||||
|
|
||||||
RageColor Course::GetColor() const
|
RageColor Course::GetColor() const
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ public:
|
|||||||
bool IsFixed() const;
|
bool IsFixed() const;
|
||||||
|
|
||||||
void LoadFromCRSFile( CString sPath );
|
void LoadFromCRSFile( CString sPath );
|
||||||
|
void RevertFromDisk();
|
||||||
void Init();
|
void Init();
|
||||||
void Save();
|
void Save();
|
||||||
void AutogenEndlessFromGroup( CString sGroupName, Difficulty dc );
|
void AutogenEndlessFromGroup( CString sGroupName, Difficulty dc );
|
||||||
@@ -140,8 +141,11 @@ public:
|
|||||||
|
|
||||||
void UpdateCourseStats( StepsType st );
|
void UpdateCourseStats( StepsType st );
|
||||||
|
|
||||||
/* Call to generate Trails with random entries and if song or notes pointers change. */
|
/* Call to regenerate Trails with random entries */
|
||||||
void RegenTrails();
|
void RegenerateNonFixedTrails();
|
||||||
|
|
||||||
|
/* Call when a Song or its Steps are deleted/changed. */
|
||||||
|
void Invalidate( Song *pStaleSong );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) const;
|
bool GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) const;
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ void GameState::Reset()
|
|||||||
|
|
||||||
/* We may have cached trails from before everything was loaded (eg. from before
|
/* We may have cached trails from before everything was loaded (eg. from before
|
||||||
* SongManager::UpdateBest could be called). Erase the cache. */
|
* SongManager::UpdateBest could be called). Erase the cache. */
|
||||||
SONGMAN->FlushCaches();
|
SONGMAN->RegenerateNonFixedCourses();
|
||||||
|
|
||||||
g_vPlayedStageStats.clear();
|
g_vPlayedStageStats.clear();
|
||||||
|
|
||||||
|
|||||||
@@ -1815,15 +1815,14 @@ void SaveChanges( void* papSongsQueue )
|
|||||||
void RevertChanges( void* papSongsQueue )
|
void RevertChanges( void* papSongsQueue )
|
||||||
{
|
{
|
||||||
vector<Song*>& apSongsQueue = *(vector<Song*>*)papSongsQueue;
|
vector<Song*>& apSongsQueue = *(vector<Song*>*)papSongsQueue;
|
||||||
for( unsigned i=0; i<apSongsQueue.size(); i++ )
|
FOREACH( Song*, apSongsQueue, pSong )
|
||||||
apSongsQueue[i]->RevertFromDisk();
|
{
|
||||||
|
(*pSong)->RevertFromDisk();
|
||||||
|
|
||||||
// We need to regen any Courses that have any of the songs we just reloaded.
|
// We need to regen any Courses that have any of the songs we just reloaded.
|
||||||
// Regen all Courses for now.
|
// Regen all Courses for now.
|
||||||
vector<Course*> vpAllCourses;
|
SONGMAN->Invalidate( *pSong );
|
||||||
SONGMAN->GetAllCourses( vpAllCourses, true );
|
}
|
||||||
FOREACH( Course*, vpAllCourses, pCourse )
|
|
||||||
(*pCourse)->RegenTrails();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenGameplay::ShowSavePrompt( ScreenMessage SM_SendWhenDone )
|
void ScreenGameplay::ShowSavePrompt( ScreenMessage SM_SendWhenDone )
|
||||||
|
|||||||
@@ -86,7 +86,9 @@ Song::~Song()
|
|||||||
m_vpSteps.clear();
|
m_vpSteps.clear();
|
||||||
|
|
||||||
/* We deleted some Steps*; clear stuff that used it. */
|
/* We deleted some Steps*; clear stuff that used it. */
|
||||||
SONGMAN->FlushCaches();
|
/* Don't make Song depend on SongManager. It's leading to some
|
||||||
|
* confusing limitation on what can be done in SONGMAN->FlushCaches(). */
|
||||||
|
SONGMAN->Invalidate( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset to an empty song. */
|
/* Reset to an empty song. */
|
||||||
@@ -103,7 +105,7 @@ void Song::Reset()
|
|||||||
|
|
||||||
/* Courses cache Notes* pointers. On the off chance that this isn't the last
|
/* Courses cache Notes* pointers. On the off chance that this isn't the last
|
||||||
* thing this screen does, clear that cache. */
|
* thing this screen does, clear that cache. */
|
||||||
SONGMAN->FlushCaches();
|
SONGMAN->Invalidate( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -348,7 +350,7 @@ void Song::RevertFromDisk( bool bAllowNotesLoss )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StepsID::FlushCache();
|
StepsID::Invalidate( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "RageFileManager.h"
|
#include "RageFileManager.h"
|
||||||
#include "UnlockSystem.h"
|
#include "UnlockSystem.h"
|
||||||
#include "CatalogXml.h"
|
#include "CatalogXml.h"
|
||||||
|
#include "Foreach.h"
|
||||||
|
|
||||||
SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program
|
SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program
|
||||||
|
|
||||||
@@ -78,8 +79,8 @@ SongManager::SongManager()
|
|||||||
|
|
||||||
SongManager::~SongManager()
|
SongManager::~SongManager()
|
||||||
{
|
{
|
||||||
FreeSongs();
|
|
||||||
FreeCourses();
|
FreeCourses();
|
||||||
|
FreeSongs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SongManager::InitAll( LoadingWindow *ld )
|
void SongManager::InitAll( LoadingWindow *ld )
|
||||||
@@ -665,13 +666,19 @@ void SongManager::Cleanup()
|
|||||||
/* Flush all Song*, Steps* and Course* caches. This is called on reload, and when
|
/* Flush all Song*, Steps* and Course* caches. This is called on reload, and when
|
||||||
* any of those are removed or changed. This doesn't touch GAMESTATE and StageStats
|
* any of those are removed or changed. This doesn't touch GAMESTATE and StageStats
|
||||||
* pointers, which are updated explicitly in Song::RevertFromDisk. */
|
* pointers, which are updated explicitly in Song::RevertFromDisk. */
|
||||||
void SongManager::FlushCaches()
|
void SongManager::Invalidate( Song *pStaleSong )
|
||||||
{
|
{
|
||||||
/* Erase cached course info. */
|
/* Erase cached course info. */
|
||||||
for( unsigned i=0; i < m_pCourses.size(); i++ )
|
FOREACH_CONST( Course*, m_pCourses, c )
|
||||||
m_pCourses[i]->RegenTrails();
|
(*c)->Invalidate( pStaleSong );
|
||||||
|
|
||||||
StepsID::FlushCache();
|
StepsID::Invalidate( pStaleSong );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SongManager::RegenerateNonFixedCourses()
|
||||||
|
{
|
||||||
|
for( unsigned i=0; i < m_pCourses.size(); i++ )
|
||||||
|
m_pCourses[i]->RegenerateNonFixedTrails();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SongManager::SetPreferences()
|
void SongManager::SetPreferences()
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ public:
|
|||||||
void InitSongsFromDisk( LoadingWindow *ld );
|
void InitSongsFromDisk( LoadingWindow *ld );
|
||||||
void FreeSongs();
|
void FreeSongs();
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
void FlushCaches();
|
|
||||||
|
void Invalidate( Song *pStaleSong );
|
||||||
|
|
||||||
|
void RegenerateNonFixedCourses();
|
||||||
void SetPreferences();
|
void SetPreferences();
|
||||||
|
|
||||||
void LoadAllFromProfiles(); // song, edits
|
void LoadAllFromProfiles(); // song, edits
|
||||||
|
|||||||
@@ -184,8 +184,9 @@ XNode* StepsID::CreateNode() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StepsID::FlushCache()
|
void StepsID::Invalidate( Song *pStaleSong )
|
||||||
{
|
{
|
||||||
|
// FIXME: Only flush entries with the stale song
|
||||||
g_StepsIDCache.clear();
|
g_StepsIDCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public:
|
|||||||
void LoadFromNode( const XNode* pNode );
|
void LoadFromNode( const XNode* pNode );
|
||||||
CString ToString() const;
|
CString ToString() const;
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
static void FlushCache();
|
static void Invalidate( Song *pStaleSong );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
XNode* CreateNode() const;
|
XNode* CreateNode() const;
|
||||||
void LoadFromNode( const XNode* pNode );
|
void LoadFromNode( const XNode* pNode );
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
static void FlushCache();
|
static void FlushCache( Song* pStaleSong );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+28
-1
@@ -51,7 +51,14 @@ bool TrailEntry::ContainsTransformOrTurn() const
|
|||||||
|
|
||||||
RadarValues Trail::GetRadarValues() const
|
RadarValues Trail::GetRadarValues() const
|
||||||
{
|
{
|
||||||
if( m_bRadarValuesCached )
|
if( IsMystery() )
|
||||||
|
{
|
||||||
|
// Don't calculate RadarValues for a non-fixed Course. They values are
|
||||||
|
// worthless because they'll change every time this Trail is
|
||||||
|
// regenerated.
|
||||||
|
return RadarValues();
|
||||||
|
}
|
||||||
|
else if( m_bRadarValuesCached )
|
||||||
{
|
{
|
||||||
return m_CachedRadarValues;
|
return m_CachedRadarValues;
|
||||||
}
|
}
|
||||||
@@ -152,6 +159,26 @@ void Trail::GetDisplayBpms( DisplayBpms &AddTo )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Trail::IsMystery() const
|
||||||
|
{
|
||||||
|
FOREACH_CONST( TrailEntry, m_vEntries, e )
|
||||||
|
{
|
||||||
|
if( e->bMystery )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Trail::ContainsSong( Song* pSong ) const
|
||||||
|
{
|
||||||
|
FOREACH_CONST( TrailEntry, m_vEntries, e )
|
||||||
|
{
|
||||||
|
if( e->pSong == pSong )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2001-2004 Chris Danford, Glenn Maynard
|
* (c) 2001-2004 Chris Danford, Glenn Maynard
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ public:
|
|||||||
int GetTotalMeter() const;
|
int GetTotalMeter() const;
|
||||||
float GetLengthSeconds() const;
|
float GetLengthSeconds() const;
|
||||||
void GetDisplayBpms( DisplayBpms &AddTo );
|
void GetDisplayBpms( DisplayBpms &AddTo );
|
||||||
|
bool IsMystery() const;
|
||||||
|
bool ContainsSong( Song* pSong ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
|
|
||||||
|
class Song;
|
||||||
class Trail;
|
class Trail;
|
||||||
class Course;
|
class Course;
|
||||||
struct XNode;
|
struct XNode;
|
||||||
@@ -24,7 +25,7 @@ public:
|
|||||||
void LoadFromNode( const XNode* pNode );
|
void LoadFromNode( const XNode* pNode );
|
||||||
CString ToString() const;
|
CString ToString() const;
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
static void FlushCache();
|
static void Invalidate( Song* pStaleSong );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user