clean up Course cache logic
This commit is contained in:
@@ -256,6 +256,11 @@ void Course::LoadFromCRSFile( CString sPath )
|
||||
m_sMainTitleTranslit = title.TitleTranslit;
|
||||
}
|
||||
|
||||
void Course::RevertFromDisk()
|
||||
{
|
||||
LoadFromCRSFile( m_sPath );
|
||||
}
|
||||
|
||||
void Course::Init()
|
||||
{
|
||||
m_bIsAutogen = false;
|
||||
@@ -898,9 +903,9 @@ void Course::GetTrails( vector<Trail*> &AddTo, StepsType st ) 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;
|
||||
}
|
||||
|
||||
@@ -909,17 +914,44 @@ bool Course::HasMods() 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 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
|
||||
|
||||
@@ -127,6 +127,7 @@ public:
|
||||
bool IsFixed() const;
|
||||
|
||||
void LoadFromCRSFile( CString sPath );
|
||||
void RevertFromDisk();
|
||||
void Init();
|
||||
void Save();
|
||||
void AutogenEndlessFromGroup( CString sGroupName, Difficulty dc );
|
||||
@@ -140,8 +141,11 @@ public:
|
||||
|
||||
void UpdateCourseStats( StepsType st );
|
||||
|
||||
/* Call to generate Trails with random entries and if song or notes pointers change. */
|
||||
void RegenTrails();
|
||||
/* Call to regenerate Trails with random entries */
|
||||
void RegenerateNonFixedTrails();
|
||||
|
||||
/* Call when a Song or its Steps are deleted/changed. */
|
||||
void Invalidate( Song *pStaleSong );
|
||||
|
||||
private:
|
||||
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
|
||||
* SongManager::UpdateBest could be called). Erase the cache. */
|
||||
SONGMAN->FlushCaches();
|
||||
SONGMAN->RegenerateNonFixedCourses();
|
||||
|
||||
g_vPlayedStageStats.clear();
|
||||
|
||||
|
||||
@@ -1815,15 +1815,14 @@ void SaveChanges( void* papSongsQueue )
|
||||
void RevertChanges( void* papSongsQueue )
|
||||
{
|
||||
vector<Song*>& apSongsQueue = *(vector<Song*>*)papSongsQueue;
|
||||
for( unsigned i=0; i<apSongsQueue.size(); i++ )
|
||||
apSongsQueue[i]->RevertFromDisk();
|
||||
FOREACH( Song*, apSongsQueue, pSong )
|
||||
{
|
||||
(*pSong)->RevertFromDisk();
|
||||
|
||||
// We need to regen any Courses that have any of the songs we just reloaded.
|
||||
// Regen all Courses for now.
|
||||
vector<Course*> vpAllCourses;
|
||||
SONGMAN->GetAllCourses( vpAllCourses, true );
|
||||
FOREACH( Course*, vpAllCourses, pCourse )
|
||||
(*pCourse)->RegenTrails();
|
||||
// We need to regen any Courses that have any of the songs we just reloaded.
|
||||
// Regen all Courses for now.
|
||||
SONGMAN->Invalidate( *pSong );
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenGameplay::ShowSavePrompt( ScreenMessage SM_SendWhenDone )
|
||||
|
||||
@@ -86,7 +86,9 @@ Song::~Song()
|
||||
m_vpSteps.clear();
|
||||
|
||||
/* 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. */
|
||||
@@ -103,7 +105,7 @@ void Song::Reset()
|
||||
|
||||
/* Courses cache Notes* pointers. On the off chance that this isn't the last
|
||||
* 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 "UnlockSystem.h"
|
||||
#include "CatalogXml.h"
|
||||
#include "Foreach.h"
|
||||
|
||||
SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program
|
||||
|
||||
@@ -78,8 +79,8 @@ SongManager::SongManager()
|
||||
|
||||
SongManager::~SongManager()
|
||||
{
|
||||
FreeSongs();
|
||||
FreeCourses();
|
||||
FreeSongs();
|
||||
}
|
||||
|
||||
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
|
||||
* any of those are removed or changed. This doesn't touch GAMESTATE and StageStats
|
||||
* pointers, which are updated explicitly in Song::RevertFromDisk. */
|
||||
void SongManager::FlushCaches()
|
||||
void SongManager::Invalidate( Song *pStaleSong )
|
||||
{
|
||||
/* Erase cached course info. */
|
||||
for( unsigned i=0; i < m_pCourses.size(); i++ )
|
||||
m_pCourses[i]->RegenTrails();
|
||||
FOREACH_CONST( Course*, m_pCourses, c )
|
||||
(*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()
|
||||
|
||||
@@ -25,7 +25,10 @@ public:
|
||||
void InitSongsFromDisk( LoadingWindow *ld );
|
||||
void FreeSongs();
|
||||
void Cleanup();
|
||||
void FlushCaches();
|
||||
|
||||
void Invalidate( Song *pStaleSong );
|
||||
|
||||
void RegenerateNonFixedCourses();
|
||||
void SetPreferences();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
void LoadFromNode( const XNode* pNode );
|
||||
CString ToString() const;
|
||||
bool IsValid() const;
|
||||
static void FlushCache();
|
||||
static void Invalidate( Song *pStaleSong );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
XNode* CreateNode() const;
|
||||
void LoadFromNode( const XNode* pNode );
|
||||
bool IsValid() const;
|
||||
static void FlushCache();
|
||||
static void FlushCache( Song* pStaleSong );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+28
-1
@@ -51,7 +51,14 @@ bool TrailEntry::ContainsTransformOrTurn() 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;
|
||||
}
|
||||
@@ -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
|
||||
* All rights reserved.
|
||||
|
||||
@@ -66,6 +66,8 @@ public:
|
||||
int GetTotalMeter() const;
|
||||
float GetLengthSeconds() const;
|
||||
void GetDisplayBpms( DisplayBpms &AddTo );
|
||||
bool IsMystery() const;
|
||||
bool ContainsSong( Song* pSong ) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "GameConstantsAndTypes.h"
|
||||
|
||||
class Song;
|
||||
class Trail;
|
||||
class Course;
|
||||
struct XNode;
|
||||
@@ -24,7 +25,7 @@ public:
|
||||
void LoadFromNode( const XNode* pNode );
|
||||
CString ToString() const;
|
||||
bool IsValid() const;
|
||||
static void FlushCache();
|
||||
static void Invalidate( Song* pStaleSong );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user