implement ConcurrentlyPrepareScreen and IsConcurrentlyLoading
This commit is contained in:
@@ -31,9 +31,11 @@
|
|||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "Foreach.h"
|
#include "Foreach.h"
|
||||||
#include "ActorUtil.h"
|
#include "ActorUtil.h"
|
||||||
|
#include "GameLoop.h"
|
||||||
|
|
||||||
ScreenManager* SCREENMAN = NULL; // global and accessable from anywhere in our program
|
ScreenManager* SCREENMAN = NULL; // global and accessable from anywhere in our program
|
||||||
|
|
||||||
|
static Preference<bool> g_bConcurrentLoading( "ConcurrentLoading", false );
|
||||||
|
|
||||||
// Screen registration
|
// Screen registration
|
||||||
static map<CString,CreateScreenFn> *g_pmapRegistrees = NULL;
|
static map<CString,CreateScreenFn> *g_pmapRegistrees = NULL;
|
||||||
@@ -56,6 +58,7 @@ ScreenManager::ScreenManager()
|
|||||||
|
|
||||||
m_bZeroNextUpdate = false;
|
m_bZeroNextUpdate = false;
|
||||||
m_PopTopScreen = SM_Invalid;
|
m_PopTopScreen = SM_Invalid;
|
||||||
|
m_OnDonePreparingScreen = SM_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,6 +118,8 @@ bool ScreenManager::IsStackedScreen( const Screen *pScreen ) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool g_bIsConcurrentlyLoading = false;
|
||||||
|
|
||||||
void ScreenManager::Update( float fDeltaTime )
|
void ScreenManager::Update( float fDeltaTime )
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -197,12 +202,41 @@ void ScreenManager::Update( float fDeltaTime )
|
|||||||
if( bFirstUpdate )
|
if( bFirstUpdate )
|
||||||
SOUND->Flush();
|
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();
|
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()
|
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()
|
void ScreenManager::DeletePreparedScreens()
|
||||||
{
|
{
|
||||||
FOREACH( Screen*, m_vPreparedScreens, s )
|
FOREACH( Screen*, m_vPreparedScreens, s )
|
||||||
@@ -559,7 +608,11 @@ void ScreenManager::RefreshCreditsMessages()
|
|||||||
|
|
||||||
void ScreenManager::ZeroNextUpdate()
|
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. */
|
/* Always play these sounds, even if we're in a silent attract loop. */
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public:
|
|||||||
void SetNewScreen( const CString &sName );
|
void SetNewScreen( const CString &sName );
|
||||||
void AddNewScreenToTop( 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.
|
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 DeletePreparedScreens();
|
||||||
void SetFromNewScreen( Screen *pNewScreen );
|
void SetFromNewScreen( Screen *pNewScreen );
|
||||||
void PopTopScreen( ScreenMessage SM );
|
void PopTopScreen( ScreenMessage SM );
|
||||||
@@ -82,9 +84,10 @@ private:
|
|||||||
vector<Screen*> m_vPreparedScreens;
|
vector<Screen*> m_vPreparedScreens;
|
||||||
vector<Actor*> m_vPreparedBackgrounds;
|
vector<Actor*> m_vPreparedBackgrounds;
|
||||||
|
|
||||||
// Screen loads and removals are delayed until the next update, so the
|
// Screen loads, removals, and concurrent prepares are delayed until the next update.
|
||||||
// screen being removed isn't on the stack.
|
|
||||||
CString m_sDelayedScreen;
|
CString m_sDelayedScreen;
|
||||||
|
CString m_sDelayedConcurrentPrepare;
|
||||||
|
ScreenMessage m_OnDonePreparingScreen;
|
||||||
ScreenMessage m_PopTopScreen;
|
ScreenMessage m_PopTopScreen;
|
||||||
|
|
||||||
// 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