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.
This commit is contained in:
+23
-11
@@ -866,17 +866,31 @@ void OptionRow::Reload()
|
|||||||
// ExportOptions( vpns, bRowHasFocus );
|
// ExportOptions( vpns, bRowHasFocus );
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if( !m_pHand->Reload() )
|
switch( m_pHand->Reload() )
|
||||||
return;
|
{
|
||||||
|
case OptionRowHandler::RELOAD_CHANGED_NONE:
|
||||||
|
break;
|
||||||
|
|
||||||
ChoicesChanged();
|
case OptionRowHandler::RELOAD_CHANGED_ALL:
|
||||||
|
{
|
||||||
|
ChoicesChanged();
|
||||||
|
|
||||||
|
vector<PlayerNumber> 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<PlayerNumber> 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.
|
// TODO: Nothing uses this yet and it causes skips when changing options.
|
||||||
//if( m_pHand->m_Def.m_bExportOnChange )
|
//if( m_pHand->m_Def.m_bExportOnChange )
|
||||||
@@ -885,8 +899,6 @@ void OptionRow::Reload()
|
|||||||
// ZERO( bRowHasFocus );
|
// ZERO( bRowHasFocus );
|
||||||
// ExportOptions( vpns, bRowHasFocus );
|
// ExportOptions( vpns, bRowHasFocus );
|
||||||
//}
|
//}
|
||||||
|
|
||||||
UpdateEnabledDisabled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionRow::HandleMessage( const RString& sMessage )
|
void OptionRow::HandleMessage( const RString& sMessage )
|
||||||
|
|||||||
@@ -256,11 +256,11 @@ public:
|
|||||||
return gc.m_sScreen;
|
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
|
// HACK: always reload "speed", to update the BPM text in the name of the speed line
|
||||||
if( !m_Def.m_sName.CompareNoCase("speed") )
|
if( !m_Def.m_sName.CompareNoCase("speed") )
|
||||||
return true;
|
return RELOAD_CHANGED_ALL;
|
||||||
|
|
||||||
return OptionRowHandler::Reload();
|
return OptionRowHandler::Reload();
|
||||||
}
|
}
|
||||||
@@ -300,7 +300,7 @@ class OptionRowHandlerListSteps : public OptionRowHandlerList
|
|||||||
// OptionRowHandlerList::LoadInternal( cmds );
|
// OptionRowHandlerList::LoadInternal( cmds );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Reload()
|
virtual ReloadChanged Reload()
|
||||||
{
|
{
|
||||||
m_Def.m_vsChoices.clear();
|
m_Def.m_vsChoices.clear();
|
||||||
m_aListEntries.clear();
|
m_aListEntries.clear();
|
||||||
@@ -361,7 +361,7 @@ class OptionRowHandlerListSteps : public OptionRowHandlerList
|
|||||||
m_aListEntries.push_back( GameCommand() );
|
m_aListEntries.push_back( GameCommand() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return RELOAD_CHANGED_ALL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -671,6 +671,7 @@ class OptionRowHandlerLua : public OptionRowHandler
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LuaExpression *m_pLuaTable;
|
LuaExpression *m_pLuaTable;
|
||||||
|
LuaReference m_EnabledForPlayersFunc;
|
||||||
|
|
||||||
OptionRowHandlerLua() { m_pLuaTable = new LuaExpression; Init(); }
|
OptionRowHandlerLua() { m_pLuaTable = new LuaExpression; Init(); }
|
||||||
virtual ~OptionRowHandlerLua() { delete m_pLuaTable; }
|
virtual ~OptionRowHandlerLua() { delete m_pLuaTable; }
|
||||||
@@ -679,6 +680,43 @@ public:
|
|||||||
OptionRowHandler::Init();
|
OptionRowHandler::Init();
|
||||||
m_pLuaTable->Unset();
|
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 )
|
virtual void LoadInternal( const Commands &cmds )
|
||||||
{
|
{
|
||||||
ASSERT( cmds.v.size() == 1 );
|
ASSERT( cmds.v.size() == 1 );
|
||||||
@@ -763,29 +801,13 @@ public:
|
|||||||
lua_pop( L, 1 ); /* pop choices table */
|
lua_pop( L, 1 ); /* pop choices table */
|
||||||
|
|
||||||
|
|
||||||
/* Iterate over the "EnabledForPlayers" table. */
|
/* Set the EnabledForPlayers function. */
|
||||||
lua_pushstring( L, "EnabledForPlayers" );
|
lua_pushstring( L, "EnabledForPlayers" );
|
||||||
lua_gettable( L, -2 );
|
lua_gettable( L, -2 );
|
||||||
if( !lua_isnil( L, -1 ) )
|
if( !lua_isfunction( L, -1 ) && !lua_isnil( L, -1 ) )
|
||||||
{
|
RageException::Throw( "\"%s\" \"EnabledForPlayers\" is not a table", sLuaFunction.c_str() );
|
||||||
if( !lua_istable( L, -1 ) )
|
m_EnabledForPlayersFunc.SetFromStack( L );
|
||||||
RageException::Throw( "\"%s\" \"EnabledForPlayers\" is not a table", sLuaFunction.c_str() );
|
SetEnabledForPlayers();
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
|
|
||||||
/* Iterate over the "ReloadRowMessages" table. */
|
/* Iterate over the "ReloadRowMessages" table. */
|
||||||
lua_pushstring( L, "ReloadRowMessages" );
|
lua_pushstring( L, "ReloadRowMessages" );
|
||||||
@@ -827,52 +849,13 @@ public:
|
|||||||
|
|
||||||
LUA->Release(L);
|
LUA->Release(L);
|
||||||
}
|
}
|
||||||
virtual bool Reload()
|
|
||||||
|
virtual ReloadChanged Reload()
|
||||||
{
|
{
|
||||||
Lua *L = LUA->Get();
|
SetEnabledForPlayers();
|
||||||
|
return RELOAD_CHANGED_ENABLED;
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void ImportOption( const vector<PlayerNumber> &vpns, vector<bool> vbSelectedOut[NUM_PLAYERS] ) const
|
virtual void ImportOption( const vector<PlayerNumber> &vpns, vector<bool> vbSelectedOut[NUM_PLAYERS] ) const
|
||||||
{
|
{
|
||||||
Lua *L = LUA->Get();
|
Lua *L = LUA->Get();
|
||||||
|
|||||||
@@ -40,11 +40,14 @@ public:
|
|||||||
* and reinitialize them. As an optimization, rows which do not
|
* and reinitialize them. As an optimization, rows which do not
|
||||||
* change can be initialized just once and left alone.
|
* change can be initialized just once and left alone.
|
||||||
*
|
*
|
||||||
* If the row has been reinitialized, return true, and the graphic
|
* If the row has been reinitialized, return RELOAD_CHANGED_ALL, and the
|
||||||
* elements will also be reinitialized. If the row is static, and
|
* graphic elements will also be reinitialized. If only m_vEnabledForPlayers
|
||||||
* nothing has changed, return false.
|
* 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<PlayerNumber> &vpns, vector<bool> vbSelectedOut[NUM_PLAYERS] ) const = 0;
|
virtual void ImportOption( const vector<PlayerNumber> &vpns, vector<bool> vbSelectedOut[NUM_PLAYERS] ) const = 0;
|
||||||
/* Returns an OPT mask. */
|
/* Returns an OPT mask. */
|
||||||
virtual int ExportOption( const vector<PlayerNumber> &vpns, const vector<bool> vbSelected[NUM_PLAYERS] ) const = 0;
|
virtual int ExportOption( const vector<PlayerNumber> &vpns, const vector<bool> vbSelected[NUM_PLAYERS] ) const = 0;
|
||||||
|
|||||||
@@ -60,10 +60,10 @@ public:
|
|||||||
FillSongsAndChoices( m_sSongGroup, m_vpDisplayedSongs, m_Def.m_vsChoices );
|
FillSongsAndChoices( m_sSongGroup, m_vpDisplayedSongs, m_Def.m_vsChoices );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Reload()
|
virtual ReloadChanged Reload()
|
||||||
{
|
{
|
||||||
FillSongsAndChoices( m_sSongGroup, m_vpDisplayedSongs, m_Def.m_vsChoices );
|
FillSongsAndChoices( m_sSongGroup, m_vpDisplayedSongs, m_Def.m_vsChoices );
|
||||||
return true;
|
return RELOAD_CHANGED_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void ImportOption( const vector<PlayerNumber> &vpns, vector<bool> vbSelectedOut[NUM_PLAYERS] ) const
|
virtual void ImportOption( const vector<PlayerNumber> &vpns, vector<bool> vbSelectedOut[NUM_PLAYERS] ) const
|
||||||
|
|||||||
Reference in New Issue
Block a user