diff --git a/stepmania/src/Course.cpp b/stepmania/src/Course.cpp index 542235a827..7fa160c148 100644 --- a/stepmania/src/Course.cpp +++ b/stepmania/src/Course.cpp @@ -258,6 +258,9 @@ void Course::LoadFromCRSFile( CString sPath ) void Course::RevertFromDisk() { + // trying to catch invalid an Course + ASSERT( !m_sPath.empty() ); + LoadFromCRSFile( m_sPath ); } @@ -268,6 +271,7 @@ void Course::Init() m_bRandomize = false; m_iLives = -1; m_bSortByMeter = false; + m_entries.clear(); FOREACH_Difficulty(dc) m_iCustomMeter[dc] = -1; m_entries.clear(); diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 79517e5f14..37d1e7fdb7 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -1337,9 +1337,11 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) case SM_GoToNextScreen: // Reload song from disk to discard changes. SONGMAN->RevertFromDisk( GAMESTATE->m_pCurSong, true ); + /* We might do something with m_pSteps (eg. UpdateTextInfo) before we end up * in ScreenEditMenu, and m_pSteps might be invalid due to RevertFromDisk. */ m_pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; + SCREENMAN->SetNewScreen( "ScreenEditMenu" ); break; case SM_BackFromMainMenu: diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 84ba1ed2a2..87924b789c 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -8,7 +8,6 @@ #include "RageSoundReader_FileReader.h" #include "RageSurface_Load.h" #include "RageException.h" -#include "SongManager.h" #include "SongCacheIndex.h" #include "GameManager.h" #include "PrefsManager.h" @@ -78,29 +77,28 @@ Song::Song() Song::~Song() { - for( unsigned i=0; iInvalidate(). -Chris */ - SONGMAN->Invalidate( this ); + + // It's the responsibility of the owner of this Song to make sure + // that all pointers to this Song and its Steps are invalidated. } /* Reset to an empty song. */ void Song::Reset() { - for( unsigned i=0; iInvalidate( pStaleSong ); + // It's a real pain to selectively invalidate only those Courses with + // dependencies on the stale Song. So, instead, just reload all Courses. + // It doesn't take very long. + FreeCourses(); + InitCoursesFromDisk( NULL ); + InitAutogenCourses(); + // invalidate cache StepsID::Invalidate( pStaleSong ); } diff --git a/stepmania/src/Steps.cpp b/stepmania/src/Steps.cpp index de9875070d..9d47216857 100644 --- a/stepmania/src/Steps.cpp +++ b/stepmania/src/Steps.cpp @@ -198,7 +198,7 @@ void Steps::Decompress() const StepsID ID; ID.FromSteps( this ); - Steps *pSteps = ID.ToSteps( &s, true ); + Steps *pSteps = ID.ToSteps( &s, true, false ); // don't use cache if( pSteps == NULL ) { LOG->Warn( "Couldn't find %s in \"%s\"", ID.ToString().c_str(), m_sFilename.c_str() ); diff --git a/stepmania/src/StepsUtil.cpp b/stepmania/src/StepsUtil.cpp index 768f64b4f6..c2aa95e5ed 100644 --- a/stepmania/src/StepsUtil.cpp +++ b/stepmania/src/StepsUtil.cpp @@ -142,14 +142,17 @@ void StepsID::FromSteps( const Steps *p ) * to have access to Song::m_LoadedFromProfile. */ static map g_StepsIDCache; -Steps *StepsID::ToSteps( const Song *p, bool bAllowNull ) const +Steps *StepsID::ToSteps( const Song *p, bool bAllowNull, bool bUseCache ) const { if( st == STEPS_TYPE_INVALID || dc == DIFFICULTY_INVALID ) return NULL; - map::iterator it = g_StepsIDCache.find( *this ); - if( it != g_StepsIDCache.end() ) - return it->second; + if( bUseCache ) + { + map::iterator it = g_StepsIDCache.find( *this ); + if( it != g_StepsIDCache.end() ) + return it->second; + } vector vNotes; if( dc == DIFFICULTY_EDIT ) @@ -163,7 +166,9 @@ Steps *StepsID::ToSteps( const Song *p, bool bAllowNull ) const else if( !bAllowNull ) RageException::Throw( "%i, %i, \"%s\"", st, dc, sDescription.c_str() ); - g_StepsIDCache[*this] = ret; + if( bUseCache ) + g_StepsIDCache[*this] = ret; + return ret; } diff --git a/stepmania/src/StepsUtil.h b/stepmania/src/StepsUtil.h index 39a77b6af4..8ef119e5a3 100644 --- a/stepmania/src/StepsUtil.h +++ b/stepmania/src/StepsUtil.h @@ -31,7 +31,7 @@ public: StepsID() { Unset(); } void Unset() { FromSteps(NULL); } void FromSteps( const Steps *p ); - Steps *ToSteps( const Song *p, bool bAllowNull ) const; + Steps *ToSteps( const Song *p, bool bAllowNull, bool bUseCache = true ) const; bool operator<( const StepsID &rhs ) const; bool MatchesStepsType( StepsType s ) const { return st == s; }