From 977689ac839cadf6a2f14c718df4eba7f1014622 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 27 Feb 2006 05:43:39 +0000 Subject: [PATCH] Annoying: allow OptionRowHandlers to specify what they reloaded, and don't re-create things if we've only changed what's enabled. Use this with the Lua interface, by making EnabledForPlayers a function returning a table instead of a table. --- stepmania/src/OptionRow.cpp | 34 +++-- stepmania/src/OptionRowHandler.cpp | 121 ++++++++---------- stepmania/src/OptionRowHandler.h | 11 +- .../src/ScreenOptionsEditCourseEntry.cpp | 4 +- 4 files changed, 84 insertions(+), 86 deletions(-) diff --git a/stepmania/src/OptionRow.cpp b/stepmania/src/OptionRow.cpp index 966a209639..3df0340e6b 100644 --- a/stepmania/src/OptionRow.cpp +++ b/stepmania/src/OptionRow.cpp @@ -866,17 +866,31 @@ void OptionRow::Reload() // ExportOptions( vpns, bRowHasFocus ); //} - if( !m_pHand->Reload() ) - return; + switch( m_pHand->Reload() ) + { + case OptionRowHandler::RELOAD_CHANGED_NONE: + break; - ChoicesChanged(); + case OptionRowHandler::RELOAD_CHANGED_ALL: + { + ChoicesChanged(); + + vector vpns; + FOREACH_HumanPlayer( p ) + vpns.push_back( p ); + ImportOptions( vpns ); + FOREACH_HumanPlayer( p ) + AfterImportOptions( p ); + // fall through + } + + case OptionRowHandler::RELOAD_CHANGED_ENABLED: + UpdateEnabledDisabled(); + FOREACH_HumanPlayer( pn ) + PositionUnderlines( pn ); + break; + } - vector vpns; - FOREACH_HumanPlayer( p ) - vpns.push_back( p ); - ImportOptions( vpns ); - FOREACH_HumanPlayer( p ) - AfterImportOptions( p ); // TODO: Nothing uses this yet and it causes skips when changing options. //if( m_pHand->m_Def.m_bExportOnChange ) @@ -885,8 +899,6 @@ void OptionRow::Reload() // ZERO( bRowHasFocus ); // ExportOptions( vpns, bRowHasFocus ); //} - - UpdateEnabledDisabled(); } void OptionRow::HandleMessage( const RString& sMessage ) diff --git a/stepmania/src/OptionRowHandler.cpp b/stepmania/src/OptionRowHandler.cpp index e5edcf5f06..934ef3a33a 100644 --- a/stepmania/src/OptionRowHandler.cpp +++ b/stepmania/src/OptionRowHandler.cpp @@ -256,11 +256,11 @@ public: return gc.m_sScreen; } - virtual bool Reload() + virtual ReloadChanged Reload() { // HACK: always reload "speed", to update the BPM text in the name of the speed line if( !m_Def.m_sName.CompareNoCase("speed") ) - return true; + return RELOAD_CHANGED_ALL; return OptionRowHandler::Reload(); } @@ -300,7 +300,7 @@ class OptionRowHandlerListSteps : public OptionRowHandlerList // OptionRowHandlerList::LoadInternal( cmds ); } - virtual bool Reload() + virtual ReloadChanged Reload() { m_Def.m_vsChoices.clear(); m_aListEntries.clear(); @@ -361,7 +361,7 @@ class OptionRowHandlerListSteps : public OptionRowHandlerList m_aListEntries.push_back( GameCommand() ); } - return true; + return RELOAD_CHANGED_ALL; } }; @@ -671,6 +671,7 @@ class OptionRowHandlerLua : public OptionRowHandler { public: LuaExpression *m_pLuaTable; + LuaReference m_EnabledForPlayersFunc; OptionRowHandlerLua() { m_pLuaTable = new LuaExpression; Init(); } virtual ~OptionRowHandlerLua() { delete m_pLuaTable; } @@ -679,6 +680,43 @@ public: OptionRowHandler::Init(); m_pLuaTable->Unset(); } + + void SetEnabledForPlayers() + { + Lua *L = LUA->Get(); + + if( m_EnabledForPlayersFunc.IsNil() ) + { + LUA->Release(L); + return; + } + + m_EnabledForPlayersFunc.PushSelf( L ); + + /* Argument 1 (self): */ + m_pLuaTable->PushSelf( L ); + + lua_call( L, 1, 1 ); // call function with 1 argument and 1 result + if( !lua_istable(L, -1) ) + RageException::Throw( "\"EnabledForPlayers\" did not return a table" ); + + m_Def.m_vEnabledForPlayers.clear(); // and fill in with supplied PlayerNumbers below + + lua_pushnil( L ); + while( lua_next(L, -2) != 0 ) + { + /* `key' is at index -2 and `value' at index -1 */ + PlayerNumber pn = (PlayerNumber)luaL_checkint( L, -1 ); + + m_Def.m_vEnabledForPlayers.insert( pn ); + + lua_pop( L, 1 ); /* removes `value'; keeps `key' for next iteration */ + } + lua_pop( L, 1 ); + + LUA->Release(L); + } + virtual void LoadInternal( const Commands &cmds ) { ASSERT( cmds.v.size() == 1 ); @@ -763,29 +801,13 @@ public: lua_pop( L, 1 ); /* pop choices table */ - /* Iterate over the "EnabledForPlayers" table. */ + /* Set the EnabledForPlayers function. */ lua_pushstring( L, "EnabledForPlayers" ); lua_gettable( L, -2 ); - if( !lua_isnil( L, -1 ) ) - { - if( !lua_istable( L, -1 ) ) - RageException::Throw( "\"%s\" \"EnabledForPlayers\" is not a table", sLuaFunction.c_str() ); - - m_Def.m_vEnabledForPlayers.clear(); // and fill in with supplied PlayerNumbers below - - lua_pushnil( L ); - while( lua_next(L, -2) != 0 ) - { - /* `key' is at index -2 and `value' at index -1 */ - PlayerNumber pn = (PlayerNumber)luaL_checkint( L, -1 ); - - m_Def.m_vEnabledForPlayers.insert( pn ); - - lua_pop( L, 1 ); /* removes `value'; keeps `key' for next iteration */ - } - } - lua_pop( L, 1 ); /* pop EnabledForPlayers table */ - + if( !lua_isfunction( L, -1 ) && !lua_isnil( L, -1 ) ) + RageException::Throw( "\"%s\" \"EnabledForPlayers\" is not a table", sLuaFunction.c_str() ); + m_EnabledForPlayersFunc.SetFromStack( L ); + SetEnabledForPlayers(); /* Iterate over the "ReloadRowMessages" table. */ lua_pushstring( L, "ReloadRowMessages" ); @@ -827,52 +849,13 @@ public: LUA->Release(L); } - virtual bool Reload() + + virtual ReloadChanged Reload() { - Lua *L = LUA->Get(); - - /* Run the Lua expression. It should return a table. */ - const Command &command = m_cmds.v[0]; - RString sLuaFunction = command.m_vsArgs[1]; - m_pLuaTable->SetFromExpression( sLuaFunction ); - - if( m_pLuaTable->GetLuaType() != LUA_TTABLE ) - RageException::Throw( "Result of \"%s\" is not a table", sLuaFunction.c_str() ); - - m_pLuaTable->PushSelf( L ); - - - /* Iterate over the "EnabledForPlayers" table. */ - lua_pushstring( L, "EnabledForPlayers" ); - lua_gettable( L, -2 ); - if( !lua_isnil( L, -1 ) ) - { - if( !lua_istable( L, -1 ) ) - RageException::Throw( "\"%s\" \"EnabledForPlayers\" is not a table", sLuaFunction.c_str() ); - - m_Def.m_vEnabledForPlayers.clear(); // and fill in with supplied PlayerNumbers below - - lua_pushnil( L ); - while( lua_next(L, -2) != 0 ) - { - /* `key' is at index -2 and `value' at index -1 */ - PlayerNumber pn = (PlayerNumber)luaL_checkint( L, -1 ); - - m_Def.m_vEnabledForPlayers.insert( pn ); - - lua_pop( L, 1 ); /* removes `value'; keeps `key' for next iteration */ - } - } - lua_pop( L, 1 ); /* pop EnabledForPlayers table */ - - - lua_pop( L, 1 ); /* pop main table */ - ASSERT( lua_gettop(L) == 0 ); - - LUA->Release(L); - - return true; + SetEnabledForPlayers(); + return RELOAD_CHANGED_ENABLED; } + virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { Lua *L = LUA->Get(); diff --git a/stepmania/src/OptionRowHandler.h b/stepmania/src/OptionRowHandler.h index d4d0ff52e4..3f5b9da0e4 100644 --- a/stepmania/src/OptionRowHandler.h +++ b/stepmania/src/OptionRowHandler.h @@ -40,11 +40,14 @@ public: * and reinitialize them. As an optimization, rows which do not * change can be initialized just once and left alone. * - * If the row has been reinitialized, return true, and the graphic - * elements will also be reinitialized. If the row is static, and - * nothing has changed, return false. + * If the row has been reinitialized, return RELOAD_CHANGED_ALL, and the + * graphic elements will also be reinitialized. If only m_vEnabledForPlayers + * has been changed, return RELOAD_CHANGED_ENABLED. If the row is static, and + * nothing has changed, return RELOAD_CHANGED_NONE. */ - virtual bool Reload() { return false; } + enum ReloadChanged { RELOAD_CHANGED_NONE, RELOAD_CHANGED_ENABLED, RELOAD_CHANGED_ALL }; + virtual ReloadChanged Reload() { return RELOAD_CHANGED_NONE; } + virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const = 0; /* Returns an OPT mask. */ virtual int ExportOption( const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const = 0; diff --git a/stepmania/src/ScreenOptionsEditCourseEntry.cpp b/stepmania/src/ScreenOptionsEditCourseEntry.cpp index 25cf110ec7..f6ae0eeb10 100644 --- a/stepmania/src/ScreenOptionsEditCourseEntry.cpp +++ b/stepmania/src/ScreenOptionsEditCourseEntry.cpp @@ -60,10 +60,10 @@ public: FillSongsAndChoices( m_sSongGroup, m_vpDisplayedSongs, m_Def.m_vsChoices ); } - virtual bool Reload() + virtual ReloadChanged Reload() { FillSongsAndChoices( m_sSongGroup, m_vpDisplayedSongs, m_Def.m_vsChoices ); - return true; + return RELOAD_CHANGED_ALL; } virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const