fix crash on exiting editor

clean up invalidation of Song and Courses
This commit is contained in:
Chris Danford
2004-08-12 04:49:15 +00:00
parent cbe80105fb
commit 873c148f0e
7 changed files with 35 additions and 22 deletions
+4
View File
@@ -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();
+2
View File
@@ -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:
+10 -12
View File
@@ -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; i<m_vpSteps.size(); i++ )
SAFE_DELETE( m_vpSteps[i] );
FOREACH( Steps*, m_vpSteps, s )
SAFE_DELETE( *s );
m_vpSteps.clear();
/* We deleted some Steps*; clear stuff that used it. */
/* TODO: Don't make Song depend on SongManager. This is breaking
* encapsulation and placing confusing limitation on what can be done in
* SONGMAN->Invalidate(). -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; i<m_vpSteps.size(); i++ )
SAFE_DELETE( m_vpSteps[i] );
FOREACH( Steps*, m_vpSteps, s )
SAFE_DELETE( *s );
m_vpSteps.clear();
FOREACH_StepsType( st )
m_vpStepsByType[st].clear();
Song empty;
*this = empty;
// It's the responsibility of the owner of this Song to make sure
// that all pointers to this Song and its Steps are invalidated.
}
+7 -3
View File
@@ -671,10 +671,14 @@ void SongManager::Cleanup()
* pointers, which are updated explicitly in Song::RevertFromDisk. */
void SongManager::Invalidate( Song *pStaleSong )
{
/* Erase cached course info. */
FOREACH_CONST( Course*, m_pCourses, c )
(*c)->Invalidate( 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 );
}
+1 -1
View File
@@ -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() );
+10 -5
View File
@@ -142,14 +142,17 @@ void StepsID::FromSteps( const Steps *p )
* to have access to Song::m_LoadedFromProfile. */
static map<StepsID,Steps *> 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<StepsID,Steps *>::iterator it = g_StepsIDCache.find( *this );
if( it != g_StepsIDCache.end() )
return it->second;
if( bUseCache )
{
map<StepsID,Steps *>::iterator it = g_StepsIDCache.find( *this );
if( it != g_StepsIDCache.end() )
return it->second;
}
vector<Steps*> 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;
}
+1 -1
View File
@@ -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; }