From d6c14eac6f388317942788ca0897c687adc08c75 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sun, 3 Jul 2005 06:13:30 +0000 Subject: [PATCH] If a screen is already prepared, don't reload it in PrepareScreen. Prepare backgrounds, too. Disallow calling SetNewScreen from a screen ctor/Init; it complicates things. When loading a new screen (through LoadDelayedScreen), load the screen with PrepareScreen, to reduce code paths. --- stepmania/src/ScreenManager.cpp | 83 ++++++++++++++++++++++++--------- stepmania/src/ScreenManager.h | 1 + 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/stepmania/src/ScreenManager.cpp b/stepmania/src/ScreenManager.cpp index 0722cd250d..c7394828a6 100644 --- a/stepmania/src/ScreenManager.cpp +++ b/stepmania/src/ScreenManager.cpp @@ -296,19 +296,45 @@ void ScreenManager::PrepareScreen( const CString &sScreenName ) { m_bZeroNextUpdate = true; - // Delete previously prepared versions of the screen. + // If the screen is already prepared, stop. for( int i = (int)m_vPreparedScreens.size()-1; i>=0; i-- ) { Screen *&pScreen = m_vPreparedScreens[i]; if( pScreen->m_sName == sScreenName ) - { - SAFE_DELETE( pScreen ); - m_vPreparedScreens.erase( m_vPreparedScreens.begin()+i ); - break; - } + return; } - m_vPreparedScreens.push_back( MakeNewScreen(sScreenName) ); + Screen* pNewScreen = MakeNewScreen(sScreenName); + m_vPreparedScreens.push_back( pNewScreen ); + + /* Don't delete previously prepared versions of the screen's background, + * and only prepare it if it's different than the current background + * and not already loaded. */ + CString sNewBGA; + if( pNewScreen->UsesBackground() ) + sNewBGA = THEME->GetPathB(sScreenName,"background"); + + if( !sNewBGA.empty() && sNewBGA != m_pSharedBGA->GetName() ) + { + Actor *pNewBGA = NULL; + FOREACH( Actor*, m_vPreparedBackgrounds, a ) + { + if( (*a)->m_sName == sNewBGA ) + { + pNewBGA = *a; + break; + } + } + + // Create the new background before deleting the previous so that we keep + // any common textures loaded. + if( pNewBGA == NULL ) + { + pNewBGA = ActorUtil::MakeActor( sNewBGA ); + pNewBGA->SetName( sNewBGA ); + m_vPreparedBackgrounds.push_back( pNewBGA ); + } + } } void ScreenManager::DeletePreparedScreens() @@ -318,6 +344,9 @@ void ScreenManager::DeletePreparedScreens() FOREACH( Screen*, m_vPreparedScreens, s ) SAFE_DELETE( *s ); m_vPreparedScreens.clear(); + FOREACH( Actor*, m_vPreparedBackgrounds, a ) + SAFE_DELETE( *a ); + m_vPreparedBackgrounds.clear(); TEXTUREMAN->DeleteCachedTextures(); } @@ -370,14 +399,15 @@ void ScreenManager::LoadDelayedScreen() EmptyDeleteQueue(); } -retry: CString sScreenName = m_sDelayedScreen; m_sDelayedScreen = ""; + // Load the screen, if it's not already prepared. + PrepareScreen( sScreenName ); + // - // Search prepped screens to see if we already have this screen available. - // If not prepped, then make it. + // Find the prepped screen. // Screen* pNewScreen = NULL; FOREACH( Screen*, m_vPreparedScreens, s ) @@ -389,32 +419,43 @@ retry: break; } } - if( pNewScreen == NULL ) - pNewScreen = MakeNewScreen(sScreenName); + ASSERT( pNewScreen != NULL ); if( m_sDelayedScreen != "" ) { - // While constructing this Screen, it's constructor called + // While constructing this Screen, its constructor called // SetNewScreen again! That SetNewScreen Command should // override this older one. - SAFE_DELETE( pNewScreen ); - goto retry; + + // This is no longer allowed. Instead, figure out which screen + // you really wanted in the first place with Lua, and don't waste + // time constructing an extra screen. + + FAIL_M( ssprintf("%s, %s", sScreenName.c_str(), m_sDelayedScreen.c_str()) ); } - // Load shared background + // Find the prepared shared background (if any), and activate it. CString sNewBGA; if( pNewScreen->UsesBackground() ) sNewBGA = THEME->GetPathB(sScreenName,"background"); if( sNewBGA != m_pSharedBGA->GetName() ) { - // Create the new background before deleting the previous so that we keep - // any common textures loaded. - Actor *pNewBGA; + Actor *pNewBGA = NULL; if( sNewBGA.empty() ) pNewBGA = new Actor; else - pNewBGA = ActorUtil::MakeActor( sNewBGA ); - pNewBGA->SetName( sNewBGA ); + { + FOREACH( Actor*, m_vPreparedBackgrounds, a ) + { + if( (*a)->m_sName == sNewBGA ) + { + pNewBGA = *a; + m_vPreparedBackgrounds.erase( a ); + break; + } + } + } + ASSERT( pNewBGA != NULL ); SAFE_DELETE( m_pSharedBGA ); m_pSharedBGA = pNewBGA; diff --git a/stepmania/src/ScreenManager.h b/stepmania/src/ScreenManager.h index fe74ce877b..8f74dcd96e 100644 --- a/stepmania/src/ScreenManager.h +++ b/stepmania/src/ScreenManager.h @@ -81,6 +81,7 @@ private: CString m_sDelayedScreen; CString m_sSystemMessage; vector m_vPreparedScreens; + vector m_vPreparedBackgrounds; vector m_vScreensToDelete; // Set this to true anywhere we create of delete objects. These