diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 64b5ec940e..2aa253b1f8 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -319,8 +319,6 @@ bool Song::ReloadFromSongDir( RString sDir ) { // This stepchart didn't exist in the file we reverted from delete *itOld; - // TODO: We should move the cache from StepsUtil to Song - StepsID::ClearCache(); } else { @@ -1233,8 +1231,6 @@ void Song::DeleteSteps( const Steps* pSteps, bool bReAutoGen ) { delete m_vpSteps[j]; m_vpSteps.erase( m_vpSteps.begin()+j ); - // TODO: We should move the cache from StepsUtil to Song - StepsID::ClearCache(); break; } } diff --git a/stepmania/src/SongManager.cpp b/stepmania/src/SongManager.cpp index 499d8559b9..381c00bd39 100644 --- a/stepmania/src/SongManager.cpp +++ b/stepmania/src/SongManager.cpp @@ -1590,9 +1590,6 @@ void SongManager::FreeAllLoadedFromProfile( ProfileSlot slot ) STATSMAN->GetStepsInUse( setInUse ); FOREACH( Song*, m_pSongs, s ) (*s)->FreeAllLoadedFromProfile( slot, &setInUse ); - - // After freeing some Steps pointers, the cache will be invalid. - StepsID::ClearCache(); } int SongManager::GetNumStepsLoadedFromProfile() diff --git a/stepmania/src/Steps.cpp b/stepmania/src/Steps.cpp index a1b57755c4..0a2d9464b2 100644 --- a/stepmania/src/Steps.cpp +++ b/stepmania/src/Steps.cpp @@ -26,6 +26,8 @@ #include +CACHED_REGISTER_CLASS(Steps); + Steps::Steps() { m_bSavedToDisk = false; @@ -243,7 +245,12 @@ void Steps::Decompress() const StepsID ID; ID.FromSteps( this ); - Steps *pSteps = ID.ToSteps( &s, true, false ); // don't use cache + /* We're using a StepsID to search in a different copy of a Song than + * the one it was created with. Clear the cache before doing this, + * or search results will come from cache and point to the original + * copy. */ + CachedObject::ClearCacheAll(); + Steps *pSteps = ID.ToSteps( &s, true ); if( pSteps == NULL ) { LOG->Warn( "Couldn't find %s in \"%s\"", ID.ToString().c_str(), m_sFilename.c_str() ); diff --git a/stepmania/src/Steps.h b/stepmania/src/Steps.h index 641ca3a657..284ae33cbd 100644 --- a/stepmania/src/Steps.h +++ b/stepmania/src/Steps.h @@ -9,6 +9,7 @@ #include "RadarValues.h" #include "Difficulty.h" #include "RageUtil_AutoPtr.h" +#include "RageUtil_CachedObject.h" class Profile; class NoteData; struct lua_State; @@ -67,6 +68,9 @@ public: void PushSelf( lua_State *L ); StepsType m_StepsType; + + CachedObject m_CachedObject; + private: inline const Steps *Real() const { return parent ? parent : this; } void DeAutogen( bool bCopyNoteData = true ); /* If this Steps is autogenerated, make it a real Steps. */ diff --git a/stepmania/src/StepsUtil.cpp b/stepmania/src/StepsUtil.cpp index b98dada954..d5bfa3a630 100644 --- a/stepmania/src/StepsUtil.cpp +++ b/stepmania/src/StepsUtil.cpp @@ -237,6 +237,8 @@ void StepsID::FromSteps( const Steps *p ) uHash = 0; } } + + m_Cache.Unset(); } /* XXX: Don't allow duplicate edit descriptions, and don't allow edit descriptions @@ -247,24 +249,14 @@ void StepsID::FromSteps( const Steps *p ) * them back out (which we don't do except in the editor), it won't be permanent. * We could do this during the actual Steps::GetID() call, instead, but then it'd have * to have access to Song::m_LoadedFromProfile. */ -typedef pair SongIDAndStepsID; -static map g_Cache; -Steps *StepsID::ToSteps( const Song *p, bool bAllowNull, bool bUseCache ) const +Steps *StepsID::ToSteps( const Song *p, bool bAllowNull ) const { if( st == StepsType_Invalid || dc == Difficulty_Invalid ) return NULL; SongID songID; songID.FromSong( p ); - SongIDAndStepsID sas = SongIDAndStepsID(songID,*this); - - if( bUseCache ) - { - map::iterator it = g_Cache.find( sas ); - if( it != g_Cache.end() ) - return it->second; - } Steps *pRet = NULL; if( dc == Difficulty_Edit ) @@ -279,8 +271,7 @@ Steps *StepsID::ToSteps( const Song *p, bool bAllowNull, bool bUseCache ) const if( !bAllowNull && pRet == NULL ) FAIL_M( ssprintf("%i, %i, \"%s\"", st, dc, sDescription.c_str()) ); - if( bUseCache ) - g_Cache[sas] = pRet; + m_Cache.Set( pRet ); return pRet; } @@ -300,12 +291,6 @@ XNode* StepsID::CreateNode() const return pNode; } - -void StepsID::ClearCache() -{ - g_Cache.clear(); -} - void StepsID::LoadFromNode( const XNode* pNode ) { ASSERT( pNode->GetName() == "Steps" ); @@ -328,6 +313,8 @@ void StepsID::LoadFromNode( const XNode* pNode ) sDescription = ""; uHash = 0; } + + m_Cache.Unset(); } RString StepsID::ToString() const diff --git a/stepmania/src/StepsUtil.h b/stepmania/src/StepsUtil.h index e601df7b32..00a98eaca3 100644 --- a/stepmania/src/StepsUtil.h +++ b/stepmania/src/StepsUtil.h @@ -3,6 +3,7 @@ #include "GameConstantsAndTypes.h" #include "Difficulty.h" +#include "RageUtil_CachedObject.h" class Steps; class Song; @@ -75,12 +76,13 @@ class StepsID Difficulty dc; RString sDescription; unsigned uHash; + mutable CachedObjectPointer m_Cache; public: StepsID() { Unset(); } void Unset() { FromSteps(NULL); } void FromSteps( const Steps *p ); - Steps *ToSteps( const Song *p, bool bAllowNull, bool bUseCache = true ) const; + Steps *ToSteps( const Song *p, bool bAllowNull ) const; bool operator<( const StepsID &rhs ) const; bool MatchesStepsType( StepsType s ) const { return st == s; } @@ -88,7 +90,6 @@ public: void LoadFromNode( const XNode* pNode ); RString ToString() const; bool IsValid() const; - static void ClearCache(); StepsType GetStepsType() const { return st; } Difficulty GetDifficulty() const { return dc; }