diff --git a/stepmania/src/ActorUtil.cpp b/stepmania/src/ActorUtil.cpp index 500531e6de..ea7b4e70cb 100644 --- a/stepmania/src/ActorUtil.cpp +++ b/stepmania/src/ActorUtil.cpp @@ -27,7 +27,7 @@ Actor* ActorUtil::LoadFromActorFile( const CString& sAniDir, const XNode* pNode CString expr; if( pNode->GetAttrValue("Condition",expr) ) { - if( !Lua::RunExpressionB(expr) ) + if( !LUA->RunExpressionB(expr) ) return NULL; } } diff --git a/stepmania/src/BGAnimation.cpp b/stepmania/src/BGAnimation.cpp index d20bc8a71f..5bc1e91b3b 100644 --- a/stepmania/src/BGAnimation.cpp +++ b/stepmania/src/BGAnimation.cpp @@ -42,7 +42,7 @@ void BGAnimation::AddLayersFromAniDir( const CString &_sAniDir, const IniFile& i CString expr; if( ini.GetValue( "BGAnimation", "Condition", expr ) || ini.GetValue( "BGAnimation", "Cond", expr ) ) { - if( !Lua::RunExpressionB( expr ) ) + if( !LUA->RunExpressionB( expr ) ) return; } } @@ -70,7 +70,7 @@ void BGAnimation::AddLayersFromAniDir( const CString &_sAniDir, const IniFile& i CString expr; if( pKey->GetAttrValue("Condition",expr) ) { - if( !Lua::RunExpressionB( expr ) ) + if( !LUA->RunExpressionB( expr ) ) continue; } diff --git a/stepmania/src/BGAnimationLayer.cpp b/stepmania/src/BGAnimationLayer.cpp index 2c861d4a28..a06a4b3eef 100644 --- a/stepmania/src/BGAnimationLayer.cpp +++ b/stepmania/src/BGAnimationLayer.cpp @@ -376,7 +376,7 @@ void BGAnimationLayer::LoadFromNode( const CString& sDir, const XNode* pNode ) CString expr; if( pNode->GetAttrValue("Cond",expr) || pNode->GetAttrValue("Condition",expr) ) { - if( !Lua::RunExpressionB( expr ) ) + if( !LUA->RunExpressionB( expr ) ) return; } } @@ -672,7 +672,7 @@ bool BGAnimationLayer::EarlyAbortDraw() if( m_sDrawCond.empty() ) return false; - if( !Lua::RunExpressionB( m_sDrawCond ) ) + if( !LUA->RunExpressionB( m_sDrawCond ) ) return true; return false; diff --git a/stepmania/src/Command.cpp b/stepmania/src/Command.cpp index eced90c352..5ce62c01ed 100644 --- a/stepmania/src/Command.cpp +++ b/stepmania/src/Command.cpp @@ -38,20 +38,20 @@ Command::Arg::operator CString () Command::Arg::operator float () { - Lua::PrepareExpression( s ); // strip invalid chars - return Lua::RunExpressionF( s ); + LUA->PrepareExpression( s ); // strip invalid chars + return LUA->RunExpressionF( s ); } Command::Arg::operator int () { - Lua::PrepareExpression( s ); // strip invalid chars - return (int)Lua::RunExpressionF( s ); + LUA->PrepareExpression( s ); // strip invalid chars + return (int)LUA->RunExpressionF( s ); } Command::Arg::operator bool () { - Lua::PrepareExpression( s ); // strip invalid chars - return Lua::RunExpressionF( s ) != 0.0f; + LUA->PrepareExpression( s ); // strip invalid chars + return LUA->RunExpressionF( s ) != 0.0f; } void Command::Load( const CString &sCommand ) diff --git a/stepmania/src/LuaFunctions.h b/stepmania/src/LuaFunctions.h index ee355d9ef7..0ed116419d 100644 --- a/stepmania/src/LuaFunctions.h +++ b/stepmania/src/LuaFunctions.h @@ -11,7 +11,7 @@ extern "C" } /* Argument helpers: */ -#define LUA_ASSERT( expr, err ) if( !(expr) ) { Lua::Fail( L, err ); } +#define LUA_ASSERT( expr, err ) if( !(expr) ) { LUA->Fail( L, err ); } /* Require exactly "need" arguments. */ #define REQ_ARGS(func, need) { \ @@ -35,7 +35,7 @@ extern "C" const int val = (int) lua_tonumber( L, n ); \ LUA_ASSERT( val >= minimum && val <= maximum, ssprintf("Argument %i to " func " must be an integer between %i and %i (got %i)", n, minimum, maximum, val) ); \ } -#define LUA_RETURN( expr ) { Lua::PushStack( L, expr ); return 1; } +#define LUA_RETURN( expr ) { LUA->PushStack( L, expr ); return 1; } /* Helpers to create common functions: */ /* Functions that take no arguments: */ @@ -71,7 +71,7 @@ int LuaFunc_##func( lua_State *L ) { \ REQ_ARGS( #func, 1 ); \ REQ_ARG( #func, 1, string ); \ CString str; \ - Lua::PopStack( L, str ); \ + LUA->PopStack( L, str ); \ LUA_RETURN( call ); \ } \ LuaFunction( func ); /* register it */ @@ -83,8 +83,8 @@ int LuaFunc_##func( lua_State *L ) { \ REQ_ARG( #func, 2, string ); \ CString str1; \ CString str2; \ - Lua::PopStack( L, str2 ); \ - Lua::PopStack( L, str1 ); \ + LUA->PopStack( L, str2 ); \ + LUA->PopStack( L, str1 ); \ LUA_RETURN( call ); \ } \ LuaFunction( func ); /* register it */ @@ -106,7 +106,7 @@ int LuaFunc_##func( lua_State *L ) { \ REQ_ARG_NUMBER_RANGE( #func, 1, 1, NUM_PLAYERS ); \ const PlayerNumber pn = (PlayerNumber) (int(lua_tonumber( L, 1 ))-1); \ int a1 = def; \ - Lua::GetStack( L, 2, a1 ); \ + LUA->GetStack( L, 2, a1 ); \ } /* Linked list of functions we make available to Lua. */ diff --git a/stepmania/src/LuaHelpers.cpp b/stepmania/src/LuaHelpers.cpp index 8de0a771ff..eaa54ddd13 100644 --- a/stepmania/src/LuaHelpers.cpp +++ b/stepmania/src/LuaHelpers.cpp @@ -8,6 +8,8 @@ #include #include +static LuaManager LUAObj; +LuaManager *LUA = &LUAObj; LuaFunctionList *g_LuaFunctionList = NULL; #if defined(_WINDOWS) @@ -50,20 +52,20 @@ const char *ChunkReaderString( lua_State *L, void *ptr, size_t *size ) return ret; } -void Lua::PushStack( lua_State *L, int out ) +void LuaManager::PushStack( lua_State *L, int out ) { /* XXX: stack bounds */ lua_pushnumber( L, out ); } -void Lua::PushStack( lua_State *L, bool out ) +void LuaManager::PushStack( lua_State *L, bool out ) { /* XXX: stack bounds */ lua_pushboolean( L, out ); } -void Lua::PushStack( lua_State *L, void *out ) +void LuaManager::PushStack( lua_State *L, void *out ) { if( out ) lua_pushlightuserdata( L, out ); @@ -71,12 +73,12 @@ void Lua::PushStack( lua_State *L, void *out ) lua_pushnil( L ); } -void Lua::PushStack( lua_State *L, const CString &out ) +void LuaManager::PushStack( lua_State *L, const CString &out ) { lua_pushstring( L, out ); } -void Lua::PopStack( lua_State *L, CString &out ) +void LuaManager::PopStack( lua_State *L, CString &out ) { /* There must be at least one entry on the stack. */ ASSERT( lua_gettop(L) > 0 ); @@ -86,7 +88,7 @@ void Lua::PopStack( lua_State *L, CString &out ) lua_pop( L, -1 ); } -bool Lua::GetStack( lua_State *L, int pos, int &out ) +bool LuaManager::GetStack( lua_State *L, int pos, int &out ) { if( pos < 0 ) pos = lua_gettop(L) - pos - 1; @@ -97,7 +99,7 @@ bool Lua::GetStack( lua_State *L, int pos, int &out ) return true; } -void Lua::SetGlobal( lua_State *L, const CString &sName ) +void LuaManager::SetGlobal( lua_State *L, const CString &sName ) { lua_setglobal( L, sName ); } @@ -110,7 +112,7 @@ static CString jbuf_error; static int LuaPanic( lua_State *L ) { CString err; - Lua::PopStack( L, err ); + LUA->PopStack( L, err ); /* Grr. We can't throw an exception from here: it'll explode going through the * Lua stack for some reason. Get it off the stack with a longjmp and throw @@ -119,9 +121,13 @@ static int LuaPanic( lua_State *L ) longjmp( jbuf, 1 ); } -lua_State *L = NULL; - void OpenLua() +{ + if( LUA == NULL ) + LUA = new LuaManager; +} + +LuaManager::LuaManager() { ASSERT( L == NULL ); @@ -137,25 +143,15 @@ void OpenLua() luaopen_string( L ); lua_settop(L, 0); // luaopen_* pushes stuff onto the stack that we don't need - Lua::RegisterFunctions( L ); + RegisterFunctions( L ); } -void CloseLua() +LuaManager::~LuaManager() { - ASSERT( L ); - lua_close( L ); - L = NULL; } -lua_State *Lua::GetGlobalState() -{ - if( L == NULL ) - OpenLua(); - return L; -} - -void Lua::PrepareExpression( CString &sInOut ) +void LuaManager::PrepareExpression( CString &sInOut ) { // HACK: Many metrics have "//" comments that Lua fails to parse. // Replace them with Lua-style comments. @@ -169,7 +165,7 @@ void Lua::PrepareExpression( CString &sInOut ) sInOut.erase( 0, 1 ); } -bool RunExpression( const CString &str ) +bool LuaManager::RunExpression( const CString &str ) { // load string { @@ -181,7 +177,7 @@ bool RunExpression( const CString &str ) if( ret ) { CString err; - Lua::PopStack( L, err ); + LuaManager::PopStack( L, err ); CString sError = ssprintf( "Lua runtime error parsing \"%s\": %s", str.c_str(), err.c_str() ); Dialog::OK( sError, "LUA_ERROR" ); return false; @@ -196,7 +192,7 @@ bool RunExpression( const CString &str ) if( ret ) { CString err; - Lua::PopStack( L, err ); + LuaManager::PopStack( L, err ); CString sError = ssprintf( "Lua runtime error evaluating \"%s\": %s", str.c_str(), err.c_str() ); Dialog::OK( sError, "LUA_ERROR" ); return false; @@ -213,7 +209,7 @@ bool RunExpression( const CString &str ) return true; } -bool Lua::RunExpressionB( const CString &str ) +bool LuaManager::RunExpressionB( const CString &str ) { if( L == NULL ) OpenLua(); @@ -227,7 +223,7 @@ bool Lua::RunExpressionB( const CString &str ) return result; } -float Lua::RunExpressionF( const CString &str ) +float LuaManager::RunExpressionF( const CString &str ) { if( L == NULL ) OpenLua(); @@ -241,7 +237,7 @@ float Lua::RunExpressionF( const CString &str ) return result; } -bool Lua::RunExpressionS( const CString &str, CString &sOut ) +bool LuaManager::RunExpressionS( const CString &str, CString &sOut ) { if( L == NULL ) OpenLua(); @@ -257,13 +253,13 @@ bool Lua::RunExpressionS( const CString &str, CString &sOut ) return true; } -void Lua::Fail( lua_State *L, const CString &err ) +void LuaManager::Fail( lua_State *L, const CString &err ) { lua_pushstring( L, err ); lua_error( L ); } -void Lua::RegisterFunctions( lua_State *L ) +void LuaManager::RegisterFunctions( lua_State *L ) { for( const LuaFunctionList *p = g_LuaFunctionList; p; p=p->next ) lua_register( L, p->name, p->func ); diff --git a/stepmania/src/LuaHelpers.h b/stepmania/src/LuaHelpers.h index 142e2a1932..929a8d1146 100644 --- a/stepmania/src/LuaHelpers.h +++ b/stepmania/src/LuaHelpers.h @@ -2,9 +2,15 @@ #define LUA_HELPERS_H struct lua_State; -namespace Lua +class LuaManager { +public: + LuaManager(); + ~LuaManager(); + void PrepareExpression( CString &sInOut ); // strip "//" comments and "+" + + /* Run an expression in the global environment, returning the given type. */ bool RunExpressionB( const CString &str ); float RunExpressionF( const CString &str ); bool RunExpressionS( const CString &str, CString &sOut ); @@ -22,9 +28,16 @@ namespace Lua bool GetStack( lua_State *L, int pos, int &out ); void SetGlobal( lua_State *L, const CString &sName ); - lua_State *GetGlobalState(); + lua_State *Get() { return L; } + +private: + /* Run an expression. The result is left on the Lua stack. */ + bool RunExpression( const CString &str ); + lua_State *L; }; +extern LuaManager *LUA; + #endif /* diff --git a/stepmania/src/ScreenBranch.cpp b/stepmania/src/ScreenBranch.cpp index 4083edb246..0ca7ececa9 100644 --- a/stepmania/src/ScreenBranch.cpp +++ b/stepmania/src/ScreenBranch.cpp @@ -23,7 +23,7 @@ ScreenBranch::ScreenBranch( CString sClassName ) : Screen( sClassName ) CString sChoice = Capitalize( as[i] ); CString sCondition = CONDITION(sChoice); - if( Lua::RunExpressionB(sCondition) ) + if( LUA->RunExpressionB(sCondition) ) { m_sChoice = sChoice; HandleScreenMessage( SM_GoToNextScreen );