From ab1fd34e7692836b7ee3139b8eb70c635cc3edfe Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 20 Sep 2006 23:45:38 +0000 Subject: [PATCH] Previously, changing themes attempted to preserve Lua data by serializing data and tables while reinstantiating Lua. That's ugly, and can't serialize some things (eg. functions). Instead, when changing themes, shut down the high-level objects and unregister as much as we can from Lua, change the theme, then reregister things. This doesn't clean the slate as much; globals won't be erased, etc. A better way would be to clear everything that uses Lua (delete singletons), then reload it all. Singleton creation is a bit of a mess currently so that would break a lot, and we don't want to reload songs. --- stepmania/src/GameLoop.cpp | 41 +++++++++++++++++++++++++++ stepmania/src/GameLoop.h | 1 + stepmania/src/ScreenOptionsMaster.cpp | 3 ++ stepmania/src/ScreenTitleMenu.cpp | 9 ++---- stepmania/src/ThemeManager.cpp | 5 +--- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/stepmania/src/GameLoop.cpp b/stepmania/src/GameLoop.cpp index 594fc3d47a..675e0514f8 100644 --- a/stepmania/src/GameLoop.cpp +++ b/stepmania/src/GameLoop.cpp @@ -115,6 +115,44 @@ static void CheckFocus() } } +/* On the next update, change themes, and load sNewScreen. */ +static RString g_sNewTheme; +static RString g_sNewScreen; +void GameLoop::ChangeTheme( const RString &sNewTheme, const RString &sNewScreen ) +{ + g_sNewTheme = sNewTheme; + g_sNewScreen = sNewScreen; +} + +#include "StepMania.h" // XXX +namespace +{ + void DoChangeTheme() + { + SAFE_DELETE( SCREENMAN ); + TEXTUREMAN->DoDelayedDelete(); + + /* Clear theme metrics, so ThemeMetrics are cleared. */ + THEME->ClearSubscribers(); + + THEME->SwitchThemeAndLanguage( g_sNewTheme, THEME->GetCurLanguage(), PREFSMAN->m_bPseudoLocalize ); + PREFSMAN->m_sTheme.Set( g_sNewTheme ); + + /* Apply the new window title, icon and aspect ratio. */ + StepMania::ApplyGraphicOptions(); + + SCREENMAN = new ScreenManager(); + + StepMania::ResetGame(); + SCREENMAN->ThemeChanged(); + SCREENMAN->SetNewScreen( g_sNewScreen ); + + g_sNewTheme = RString(); + g_sNewScreen = RString(); + } + +} + void GameLoop::RunGameLoop() { /* People may want to do something else while songs are loading, so do @@ -124,6 +162,9 @@ void GameLoop::RunGameLoop() while( !ArchHooks::UserQuit() ) { + if( !g_sNewTheme.empty() ) + DoChangeTheme(); + /* * Update */ diff --git a/stepmania/src/GameLoop.h b/stepmania/src/GameLoop.h index 42434ebbc0..71a70b9497 100644 --- a/stepmania/src/GameLoop.h +++ b/stepmania/src/GameLoop.h @@ -7,6 +7,7 @@ namespace GameLoop { void RunGameLoop(); void SetUpdateRate( float fUpdateRate ); + void ChangeTheme( const RString &sNewTheme, const RString &sNewScreen ); void StartConcurrentRendering(); void FinishConcurrentRendering(); }; diff --git a/stepmania/src/ScreenOptionsMaster.cpp b/stepmania/src/ScreenOptionsMaster.cpp index f66de6d629..055c3840f0 100644 --- a/stepmania/src/ScreenOptionsMaster.cpp +++ b/stepmania/src/ScreenOptionsMaster.cpp @@ -15,6 +15,7 @@ #include "OptionRowHandler.h" #include "ScreenOptionsMasterPrefs.h" #include "CommonMetrics.h" +#include "GameLoop.h" #define LINE_NAMES THEME->GetMetric (m_sName,"LineNames") #define LINE(sLineName) THEME->GetMetric (m_sName,ssprintf("Line%s",sLineName.c_str())) @@ -123,6 +124,8 @@ void ScreenOptionsMaster::HandleScreenMessage( const ScreenMessage SM ) (m_iChangeMask & OPT_APPLY_GRAPHICS) || (m_iChangeMask & OPT_APPLY_ASPECT_RATIO) ) { + RString sNewTheme = PREFSMAN->m_sTheme.Get(); + GameLoop::ChangeTheme( sNewTheme, this->GetNextScreen() ); StepMania::ApplyGraphicOptions(); } diff --git a/stepmania/src/ScreenTitleMenu.cpp b/stepmania/src/ScreenTitleMenu.cpp index bcfbc92fcf..7c6440ae70 100644 --- a/stepmania/src/ScreenTitleMenu.cpp +++ b/stepmania/src/ScreenTitleMenu.cpp @@ -2,7 +2,6 @@ #include "ScreenTitleMenu.h" #include "ScreenManager.h" #include "RageUtil.h" -#include "StepMania.h" #include "PrefsManager.h" #include "RageLog.h" #include "AnnouncerManager.h" @@ -11,7 +10,6 @@ #include "ThemeManager.h" #include "GameSoundManager.h" #include "CodeDetector.h" -#include "RageTextureManager.h" #include "LightsManager.h" #include "Game.h" #include "InputMapper.h" @@ -19,6 +17,7 @@ #include "CharacterManager.h" #include "InputEventPlus.h" #include "LocalizedString.h" +#include "GameLoop.h" #define COIN_MODE_CHANGE_SCREEN THEME->GetMetric (m_sName,"CoinModeChangeScreen") @@ -74,11 +73,7 @@ void ScreenTitleMenu::Input( const InputEventPlus &input ) if( CodeDetector::EnteredCode(input.GameI.controller,CODE_NEXT_THEME) || CodeDetector::EnteredCode(input.GameI.controller,CODE_NEXT_THEME2) ) { - THEME->SwitchThemeAndLanguage( THEME->GetNextTheme(), THEME->GetCurLanguage(), PREFSMAN->m_bPseudoLocalize ); - StepMania::ApplyGraphicOptions(); // update window title and icon - SCREENMAN->SystemMessage( THEME_.GetValue()+": "+THEME->GetCurThemeName() ); - SCREENMAN->SetNewScreen( m_sName ); - TEXTUREMAN->DoDelayedDelete(); + GameLoop::ChangeTheme( THEME->GetNextTheme(), m_sName ); } if( CodeDetector::EnteredCode(input.GameI.controller,CODE_NEXT_ANNOUNCER) || CodeDetector::EnteredCode(input.GameI.controller,CODE_NEXT_ANNOUNCER2) ) diff --git a/stepmania/src/ThemeManager.cpp b/stepmania/src/ThemeManager.cpp index d99ea71e3c..cf8480338d 100644 --- a/stepmania/src/ThemeManager.cpp +++ b/stepmania/src/ThemeManager.cpp @@ -460,10 +460,7 @@ void ThemeManager::RunLuaScripts( const RString &sMask ) void ThemeManager::UpdateLuaGlobals() { - /* Ugly: we need Serialize.lua to be loaded in order to be able to ResetState, - * but everything else should be able to depend on globals being set. */ - RunLuaScripts( "Serialize.lua" ); - LUA->ResetState(); + LUA->RegisterTypes(); #if !defined(SMPACKAGE) /* explicitly refresh cached metrics that we use. */