diff --git a/stepmania/src/Actor.cpp b/stepmania/src/Actor.cpp index ade468f2fd..d7a258be79 100644 --- a/stepmania/src/Actor.cpp +++ b/stepmania/src/Actor.cpp @@ -196,14 +196,7 @@ void Actor::LoadFromNode( const CString& sDir, const XNode* pNode ) { if( pChild->m_sName == "Input" ) { - /* - * Parameters are set as globals by ActorUtil::LoadFromNode and - * Screen::InitScreen. - * If parameters are specified here, save them to the actor. Accessing - * parameters as globals directly is deprecated. (However, it's still - * the only way to access them when self isn't available, such as from - * RunAtExpressionS.) - */ + /* If parameters are specified here, save their values to the actor. */ CString sName; if( !pChild->GetAttrValue( "Name", sName ) ) RageException::Throw( ssprintf("Input node in '%s' is missing the attribute 'Name'", sDir.c_str()) ); @@ -214,7 +207,7 @@ void Actor::LoadFromNode( const CString& sDir, const XNode* pNode ) Lua *L = LUA->Get(); this->PushSelf( L ); LuaHelpers::Push( sName, L ); - lua_getglobal( L, sName ); + ActorUtil::GetParam( L, sName ); if( lua_isnil(L, -1) && !bOptional ) RageException::Throw( "Actor in \"%s\" requires parameter \"%s\" that is not set", sDir.c_str(), sName.c_str() ); diff --git a/stepmania/src/ActorUtil.cpp b/stepmania/src/ActorUtil.cpp index 29c5dc6e5e..ac797e300c 100644 --- a/stepmania/src/ActorUtil.cpp +++ b/stepmania/src/ActorUtil.cpp @@ -104,6 +104,70 @@ retry: sPath = DerefRedir( sPath ); } +static void PushParamsTable( Lua *L ) +{ + lua_pushstring( L, "Params" ); + lua_rawget( L, LUA_GLOBALSINDEX ); + if( lua_isnil(L, -1) ) + { + lua_pop( L, 1 ); + lua_newtable( L ); + lua_pushstring( L, "Params" ); + lua_pushvalue( L, -2 ); + lua_rawset( L, LUA_GLOBALSINDEX ); + } +} + +/* Set an input parameter to the first value on the stack. If pOld is non-NULL, + * set it to the old value. The value used on the stack will be removed. */ +void ActorUtil::SetParamFromStack( Lua *L, CString sName, LuaReference *pOld ) +{ + int iValue = lua_gettop(L); + + PushParamsTable( L ); + int iParams = lua_gettop(L); + + LuaHelpers::Push( sName, L ); + int iName = lua_gettop(L); + + /* Save the old value. */ + if( pOld != NULL ) + { + lua_pushvalue( L, iName ); + lua_rawget( L, iParams ); + pOld->SetFromStack( L ); + } + + /* Backwards-compatibility: set the value as a global. This is strongly + * deprecated. */ + lua_pushvalue( L, iName ); + lua_pushvalue( L, iValue ); + lua_rawset( L, LUA_GLOBALSINDEX ); + + /* Set the value in the table. */ + lua_pushvalue( L, iName ); + lua_pushvalue( L, iValue ); + lua_rawset( L, iParams ); + + lua_settop( L, iValue-1 ); +} + +/* Look up a param set with SetParamFromStack, and push it on the stack. */ +void ActorUtil::GetParam( Lua *L, const CString &sName ) +{ + /* Search the params table. */ + PushParamsTable( L ); + LuaHelpers::Push( sName, L ); + lua_rawget( L, -2 ); + lua_remove( L, -2 ); + + if( lua_isnil(L, -1) ) + { + /* Deprecated: search globals. */ + lua_pop( L, 1 ); + lua_getglobal( L, sName ); + } +} Actor* ActorUtil::LoadFromNode( const CString& sDir, const XNode* pNode ) { @@ -136,8 +200,15 @@ Actor* ActorUtil::LoadFromNode( const CString& sDir, const XNode* pNode ) CString s; if( pChild->GetAttrValue( "Value", s ) ) { + /* XXX: don't RunAtExpressionS here; probably don't replace ::, either + * (use regular Lua escapes). */ THEME->EvaluateString( s ); - LUA->SetGlobalFromExpression( sName, s ); + + Lua *L = LUA->Get(); + LuaHelpers::RunScript( L, "return " + s, "", 1 ); + + SetParamFromStack( L, sName, NULL ); + LUA->Release(L); } else { diff --git a/stepmania/src/ActorUtil.h b/stepmania/src/ActorUtil.h index 5f4f8d5054..c362910076 100644 --- a/stepmania/src/ActorUtil.h +++ b/stepmania/src/ActorUtil.h @@ -74,6 +74,9 @@ namespace ActorUtil void SortByZPosition( vector &vActors ); FileType GetFileType( const CString &sPath ); + + void SetParamFromStack( Lua *L, CString sName, LuaReference *pOld=NULL ); + void GetParam( Lua *L, const CString &sName ); }; #define SET_XY( actor ) ActorUtil::SetXY( actor, m_sName ) diff --git a/stepmania/src/Screen.cpp b/stepmania/src/Screen.cpp index b3eda02b28..4ecf9f42f7 100644 --- a/stepmania/src/Screen.cpp +++ b/stepmania/src/Screen.cpp @@ -19,16 +19,12 @@ void Screen::InitScreen( Screen *pScreen ) { - /* Set the name of the loading screen, so Actor::LoadFromNode can - * access it. */ + /* Set the name of the loading screen. */ LuaReference Old; { Lua *L = LUA->Get(); - lua_getglobal( L, "LoadingScreen" ); - Old.SetFromStack( L ); - LuaHelpers::Push( pScreen->GetName(), L ); - lua_setglobal( L, "LoadingScreen" ); + ActorUtil::SetParamFromStack( L, "LoadingScreen", &Old ); LUA->Release( L ); } @@ -38,7 +34,7 @@ void Screen::InitScreen( Screen *pScreen ) { Lua *L = LUA->Get(); Old.PushSelf( L ); - lua_setglobal( L, "LoadingScreen" ); + ActorUtil::SetParamFromStack( L, "LoadingScreen" ); LUA->Release( L ); } }