implement ConcurrentlyPrepareScreen and IsConcurrentlyLoading

This commit is contained in:
Glenn Maynard
2005-07-13 06:44:44 +00:00
parent cf33a47ba4
commit a6cb2db9f2
2 changed files with 60 additions and 4 deletions
+55 -2
View File
@@ -31,9 +31,11 @@
#include "Screen.h"
#include "Foreach.h"
#include "ActorUtil.h"
#include "GameLoop.h"
ScreenManager* SCREENMAN = NULL; // global and accessable from anywhere in our program
static Preference<bool> g_bConcurrentLoading( "ConcurrentLoading", false );
// Screen registration
static map<CString,CreateScreenFn> *g_pmapRegistrees = NULL;
@@ -56,6 +58,7 @@ ScreenManager::ScreenManager()
m_bZeroNextUpdate = false;
m_PopTopScreen = SM_Invalid;
m_OnDonePreparingScreen = SM_Invalid;
}
@@ -115,6 +118,8 @@ bool ScreenManager::IsStackedScreen( const Screen *pScreen ) const
return false;
}
static bool g_bIsConcurrentlyLoading = false;
void ScreenManager::Update( float fDeltaTime )
{
//
@@ -197,12 +202,41 @@ void ScreenManager::Update( float fDeltaTime )
if( bFirstUpdate )
SOUND->Flush();
if( m_sDelayedScreen.size() != 0 )
/* If we're currently inside a background screen load, and m_sDelayedScreen
* is set, then the screen called SetNewScreen before we finished preparing.
* Postpone it until we're finished loading. */
if( !IsConcurrentlyLoading() && m_sDelayedScreen.size() != 0 )
{
LoadDelayedScreen();
}
if( !m_sDelayedConcurrentPrepare.empty() )
{
/* Don't call BackgroundPrepareScreen() from within another background load. */
ASSERT( !IsConcurrentlyLoading() );
/* Push rendering into a thread, and prepare the screen. */
g_bIsConcurrentlyLoading = true;
StartConcurrentRendering();
PrepareScreen( m_sDelayedConcurrentPrepare );
FinishConcurrentRendering();
g_bIsConcurrentlyLoading = false;
LOG->Trace( "Concurrent prepare of %s finished", m_sDelayedConcurrentPrepare.c_str() );
/* We're done. Send the message. The screen is allowed to start
* another concurrent prepare from this message. */
ScreenMessage SM = m_OnDonePreparingScreen;
m_sDelayedConcurrentPrepare = "";
m_OnDonePreparingScreen = SM_None;
SendMessageToTopScreen( SM );
}
}
bool ScreenManager::IsConcurrentlyLoading() const
{
return g_bIsConcurrentlyLoading;
}
void ScreenManager::Draw()
{
@@ -347,6 +381,21 @@ void ScreenManager::PrepareScreen( const CString &sScreenName )
}
}
bool ScreenManager::ConcurrentlyPrepareScreen( const CString &sScreenName, ScreenMessage SM )
{
ASSERT_M( m_sDelayedConcurrentPrepare == "", m_sDelayedConcurrentPrepare );
if( !g_bConcurrentLoading || !DISPLAY->SupportsThreadedRendering() )
return false;
LOG->Trace( "ConcurrentlyPrepareScreen(%s)", sScreenName.c_str() );
ASSERT( !IsConcurrentlyLoading() );
m_sDelayedConcurrentPrepare = sScreenName;
m_OnDonePreparingScreen = SM;
return true;
}
void ScreenManager::DeletePreparedScreens()
{
FOREACH( Screen*, m_vPreparedScreens, s )
@@ -559,7 +608,11 @@ void ScreenManager::RefreshCreditsMessages()
void ScreenManager::ZeroNextUpdate()
{
m_bZeroNextUpdate = true;
if( !IsConcurrentlyLoading() )
{
LOG->Trace("ScreenManager::ZeroNextUpdate");
m_bZeroNextUpdate = true;
}
}
/* Always play these sounds, even if we're in a silent attract loop. */
+5 -2
View File
@@ -39,6 +39,8 @@ public:
void SetNewScreen( const CString &sName );
void AddNewScreenToTop( const CString &sName );
void PrepareScreen( const CString &sScreenName ); // creates and caches screen so that the next call to SetNewScreen for the prep'd screen will be very quick.
bool ConcurrentlyPrepareScreen( const CString &sScreenName, ScreenMessage send_when_done = SM_None );
bool IsConcurrentlyLoading() const;
void DeletePreparedScreens();
void SetFromNewScreen( Screen *pNewScreen );
void PopTopScreen( ScreenMessage SM );
@@ -82,9 +84,10 @@ private:
vector<Screen*> m_vPreparedScreens;
vector<Actor*> m_vPreparedBackgrounds;
// Screen loads and removals are delayed until the next update, so the
// screen being removed isn't on the stack.
// Screen loads, removals, and concurrent prepares are delayed until the next update.
CString m_sDelayedScreen;
CString m_sDelayedConcurrentPrepare;
ScreenMessage m_OnDonePreparingScreen;
ScreenMessage m_PopTopScreen;
// Set this to true anywhere we create of delete objects. These