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.
This commit is contained in:
@@ -296,19 +296,45 @@ void ScreenManager::PrepareScreen( const CString &sScreenName )
|
|||||||
{
|
{
|
||||||
m_bZeroNextUpdate = true;
|
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-- )
|
for( int i = (int)m_vPreparedScreens.size()-1; i>=0; i-- )
|
||||||
{
|
{
|
||||||
Screen *&pScreen = m_vPreparedScreens[i];
|
Screen *&pScreen = m_vPreparedScreens[i];
|
||||||
if( pScreen->m_sName == sScreenName )
|
if( pScreen->m_sName == sScreenName )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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() )
|
||||||
{
|
{
|
||||||
SAFE_DELETE( pScreen );
|
Actor *pNewBGA = NULL;
|
||||||
m_vPreparedScreens.erase( m_vPreparedScreens.begin()+i );
|
FOREACH( Actor*, m_vPreparedBackgrounds, a )
|
||||||
|
{
|
||||||
|
if( (*a)->m_sName == sNewBGA )
|
||||||
|
{
|
||||||
|
pNewBGA = *a;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vPreparedScreens.push_back( MakeNewScreen(sScreenName) );
|
// 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()
|
void ScreenManager::DeletePreparedScreens()
|
||||||
@@ -318,6 +344,9 @@ void ScreenManager::DeletePreparedScreens()
|
|||||||
FOREACH( Screen*, m_vPreparedScreens, s )
|
FOREACH( Screen*, m_vPreparedScreens, s )
|
||||||
SAFE_DELETE( *s );
|
SAFE_DELETE( *s );
|
||||||
m_vPreparedScreens.clear();
|
m_vPreparedScreens.clear();
|
||||||
|
FOREACH( Actor*, m_vPreparedBackgrounds, a )
|
||||||
|
SAFE_DELETE( *a );
|
||||||
|
m_vPreparedBackgrounds.clear();
|
||||||
|
|
||||||
TEXTUREMAN->DeleteCachedTextures();
|
TEXTUREMAN->DeleteCachedTextures();
|
||||||
}
|
}
|
||||||
@@ -370,14 +399,15 @@ void ScreenManager::LoadDelayedScreen()
|
|||||||
EmptyDeleteQueue();
|
EmptyDeleteQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
|
||||||
CString sScreenName = m_sDelayedScreen;
|
CString sScreenName = m_sDelayedScreen;
|
||||||
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.
|
// Find the prepped screen.
|
||||||
// If not prepped, then make it.
|
|
||||||
//
|
//
|
||||||
Screen* pNewScreen = NULL;
|
Screen* pNewScreen = NULL;
|
||||||
FOREACH( Screen*, m_vPreparedScreens, s )
|
FOREACH( Screen*, m_vPreparedScreens, s )
|
||||||
@@ -389,32 +419,43 @@ retry:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pNewScreen == NULL )
|
ASSERT( pNewScreen != NULL );
|
||||||
pNewScreen = MakeNewScreen(sScreenName);
|
|
||||||
|
|
||||||
if( m_sDelayedScreen != "" )
|
if( m_sDelayedScreen != "" )
|
||||||
{
|
{
|
||||||
// While constructing this Screen, it's constructor called
|
// While constructing this Screen, its constructor called
|
||||||
// SetNewScreen again! That SetNewScreen Command should
|
// SetNewScreen again! That SetNewScreen Command should
|
||||||
// override this older one.
|
// 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;
|
CString sNewBGA;
|
||||||
if( pNewScreen->UsesBackground() )
|
if( pNewScreen->UsesBackground() )
|
||||||
sNewBGA = THEME->GetPathB(sScreenName,"background");
|
sNewBGA = THEME->GetPathB(sScreenName,"background");
|
||||||
if( sNewBGA != m_pSharedBGA->GetName() )
|
if( sNewBGA != m_pSharedBGA->GetName() )
|
||||||
{
|
{
|
||||||
// Create the new background before deleting the previous so that we keep
|
Actor *pNewBGA = NULL;
|
||||||
// any common textures loaded.
|
|
||||||
Actor *pNewBGA;
|
|
||||||
if( sNewBGA.empty() )
|
if( sNewBGA.empty() )
|
||||||
pNewBGA = new Actor;
|
pNewBGA = new Actor;
|
||||||
else
|
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 );
|
SAFE_DELETE( m_pSharedBGA );
|
||||||
m_pSharedBGA = pNewBGA;
|
m_pSharedBGA = pNewBGA;
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ private:
|
|||||||
CString m_sDelayedScreen;
|
CString m_sDelayedScreen;
|
||||||
CString m_sSystemMessage;
|
CString m_sSystemMessage;
|
||||||
vector<Screen*> m_vPreparedScreens;
|
vector<Screen*> m_vPreparedScreens;
|
||||||
|
vector<Actor*> m_vPreparedBackgrounds;
|
||||||
vector<Screen*> m_vScreensToDelete;
|
vector<Screen*> m_vScreensToDelete;
|
||||||
|
|
||||||
// Set this to true anywhere we create of delete objects. These
|
// Set this to true anywhere we create of delete objects. These
|
||||||
|
|||||||
Reference in New Issue
Block a user