change Lua to a singleton object

hide Lua state
This commit is contained in:
Glenn Maynard
2005-01-19 23:01:53 +00:00
parent 91a6486f9e
commit 0f4aec8584
4 changed files with 53 additions and 72 deletions
+5 -5
View File
@@ -11,7 +11,7 @@ extern "C"
} }
/* Argument helpers: */ /* Argument helpers: */
#define LUA_ASSERT( expr, err ) if( !(expr) ) { LUA->Fail( L, err ); } #define LUA_ASSERT( expr, err ) if( !(expr) ) { LUA->Fail( err ); }
/* Require exactly "need" arguments. */ /* Require exactly "need" arguments. */
#define REQ_ARGS(func, need) { \ #define REQ_ARGS(func, need) { \
@@ -35,7 +35,7 @@ extern "C"
const int val = (int) lua_tonumber( L, n ); \ 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) ); \ 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( expr ); return 1; }
/* Helpers to create common functions: */ /* Helpers to create common functions: */
/* Functions that take no arguments: */ /* Functions that take no arguments: */
@@ -71,7 +71,7 @@ int LuaFunc_##func( lua_State *L ) { \
REQ_ARGS( #func, 1 ); \ REQ_ARGS( #func, 1 ); \
REQ_ARG( #func, 1, string ); \ REQ_ARG( #func, 1, string ); \
CString str; \ CString str; \
LUA->PopStack( L, str ); \ LUA->PopStack( str ); \
LUA_RETURN( call ); \ LUA_RETURN( call ); \
} \ } \
LuaFunction( func ); /* register it */ LuaFunction( func ); /* register it */
@@ -83,8 +83,8 @@ int LuaFunc_##func( lua_State *L ) { \
REQ_ARG( #func, 2, string ); \ REQ_ARG( #func, 2, string ); \
CString str1; \ CString str1; \
CString str2; \ CString str2; \
LUA->PopStack( L, str2 ); \ LUA->PopStack( str2 ); \
LUA->PopStack( L, str1 ); \ LUA->PopStack( str1 ); \
LUA_RETURN( call ); \ LUA_RETURN( call ); \
} \ } \
LuaFunction( func ); /* register it */ LuaFunction( func ); /* register it */
+23 -32
View File
@@ -10,7 +10,7 @@
static LuaManager LUAObj; static LuaManager LUAObj;
LuaManager *LUA = &LUAObj; LuaManager *LUA = &LUAObj;
LuaFunctionList *g_LuaFunctionList = NULL; static LuaFunctionList *g_NewLuaFunctions = NULL;
#if defined(_WINDOWS) #if defined(_WINDOWS)
#pragma comment(lib, "lua-5.0/lib/LibLua.lib") #pragma comment(lib, "lua-5.0/lib/LibLua.lib")
@@ -52,20 +52,20 @@ const char *ChunkReaderString( lua_State *L, void *ptr, size_t *size )
return ret; return ret;
} }
void LuaManager::PushStack( lua_State *L, int out ) void LuaManager::PushStack( int out )
{ {
/* XXX: stack bounds */ /* XXX: stack bounds */
lua_pushnumber( L, out ); lua_pushnumber( L, out );
} }
void LuaManager::PushStack( lua_State *L, bool out ) void LuaManager::PushStack( bool out )
{ {
/* XXX: stack bounds */ /* XXX: stack bounds */
lua_pushboolean( L, out ); lua_pushboolean( L, out );
} }
void LuaManager::PushStack( lua_State *L, void *out ) void LuaManager::PushStack( void *out )
{ {
if( out ) if( out )
lua_pushlightuserdata( L, out ); lua_pushlightuserdata( L, out );
@@ -73,12 +73,12 @@ void LuaManager::PushStack( lua_State *L, void *out )
lua_pushnil( L ); lua_pushnil( L );
} }
void LuaManager::PushStack( lua_State *L, const CString &out ) void LuaManager::PushStack( const CString &out )
{ {
lua_pushstring( L, out ); lua_pushstring( L, out );
} }
void LuaManager::PopStack( lua_State *L, CString &out ) void LuaManager::PopStack( CString &out )
{ {
/* There must be at least one entry on the stack. */ /* There must be at least one entry on the stack. */
ASSERT( lua_gettop(L) > 0 ); ASSERT( lua_gettop(L) > 0 );
@@ -88,7 +88,7 @@ void LuaManager::PopStack( lua_State *L, CString &out )
lua_pop( L, -1 ); lua_pop( L, -1 );
} }
bool LuaManager::GetStack( lua_State *L, int pos, int &out ) bool LuaManager::GetStack( int pos, int &out )
{ {
if( pos < 0 ) if( pos < 0 )
pos = lua_gettop(L) - pos - 1; pos = lua_gettop(L) - pos - 1;
@@ -99,7 +99,7 @@ bool LuaManager::GetStack( lua_State *L, int pos, int &out )
return true; return true;
} }
void LuaManager::SetGlobal( lua_State *L, const CString &sName ) void LuaManager::SetGlobal( const CString &sName )
{ {
lua_setglobal( L, sName ); lua_setglobal( L, sName );
} }
@@ -112,7 +112,7 @@ static CString jbuf_error;
static int LuaPanic( lua_State *L ) static int LuaPanic( lua_State *L )
{ {
CString err; CString err;
LUA->PopStack( L, err ); LUA->PopStack( err );
/* Grr. We can't throw an exception from here: it'll explode going through the /* 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 * Lua stack for some reason. Get it off the stack with a longjmp and throw
@@ -121,12 +121,6 @@ static int LuaPanic( lua_State *L )
longjmp( jbuf, 1 ); longjmp( jbuf, 1 );
} }
void OpenLua()
{
if( LUA == NULL )
LUA = new LuaManager;
}
LuaManager::LuaManager() LuaManager::LuaManager()
{ {
ASSERT( L == NULL ); ASSERT( L == NULL );
@@ -143,7 +137,7 @@ LuaManager::LuaManager()
luaopen_string( L ); luaopen_string( L );
lua_settop(L, 0); // luaopen_* pushes stuff onto the stack that we don't need lua_settop(L, 0); // luaopen_* pushes stuff onto the stack that we don't need
RegisterFunctions( L ); RegisterFunctions();
} }
LuaManager::~LuaManager() LuaManager::~LuaManager()
@@ -167,6 +161,8 @@ void LuaManager::PrepareExpression( CString &sInOut )
bool LuaManager::RunExpression( const CString &str ) bool LuaManager::RunExpression( const CString &str )
{ {
RegisterFunctions();
// load string // load string
{ {
ChunkReaderData data; ChunkReaderData data;
@@ -177,7 +173,7 @@ bool LuaManager::RunExpression( const CString &str )
if( ret ) if( ret )
{ {
CString err; CString err;
LuaManager::PopStack( L, err ); LuaManager::PopStack( err );
CString sError = ssprintf( "Lua runtime error parsing \"%s\": %s", str.c_str(), err.c_str() ); CString sError = ssprintf( "Lua runtime error parsing \"%s\": %s", str.c_str(), err.c_str() );
Dialog::OK( sError, "LUA_ERROR" ); Dialog::OK( sError, "LUA_ERROR" );
return false; return false;
@@ -192,7 +188,7 @@ bool LuaManager::RunExpression( const CString &str )
if( ret ) if( ret )
{ {
CString err; CString err;
LuaManager::PopStack( L, err ); LuaManager::PopStack( err );
CString sError = ssprintf( "Lua runtime error evaluating \"%s\": %s", str.c_str(), err.c_str() ); CString sError = ssprintf( "Lua runtime error evaluating \"%s\": %s", str.c_str(), err.c_str() );
Dialog::OK( sError, "LUA_ERROR" ); Dialog::OK( sError, "LUA_ERROR" );
return false; return false;
@@ -211,9 +207,6 @@ bool LuaManager::RunExpression( const CString &str )
bool LuaManager::RunExpressionB( const CString &str ) bool LuaManager::RunExpressionB( const CString &str )
{ {
if( L == NULL )
OpenLua();
if( !RunExpression( str ) ) if( !RunExpression( str ) )
return false; return false;
@@ -225,9 +218,6 @@ bool LuaManager::RunExpressionB( const CString &str )
float LuaManager::RunExpressionF( const CString &str ) float LuaManager::RunExpressionF( const CString &str )
{ {
if( L == NULL )
OpenLua();
if( !RunExpression( str ) ) if( !RunExpression( str ) )
return 0; return 0;
@@ -239,9 +229,6 @@ float LuaManager::RunExpressionF( const CString &str )
bool LuaManager::RunExpressionS( const CString &str, CString &sOut ) bool LuaManager::RunExpressionS( const CString &str, CString &sOut )
{ {
if( L == NULL )
OpenLua();
if( !RunExpression( str ) ) if( !RunExpression( str ) )
return false; return false;
@@ -253,24 +240,28 @@ bool LuaManager::RunExpressionS( const CString &str, CString &sOut )
return true; return true;
} }
void LuaManager::Fail( lua_State *L, const CString &err ) void LuaManager::Fail( const CString &err )
{ {
lua_pushstring( L, err ); lua_pushstring( L, err );
lua_error( L ); lua_error( L );
} }
void LuaManager::RegisterFunctions( lua_State *L ) /* Add any newly-added functions to the Lua state. This should be called at
* least once after global initialization, to handle global initialization
* order. */
void LuaManager::RegisterFunctions()
{ {
for( const LuaFunctionList *p = g_LuaFunctionList; p; p=p->next ) for( const LuaFunctionList *p = g_NewLuaFunctions; p; p=p->next )
lua_register( L, p->name, p->func ); lua_register( L, p->name, p->func );
g_NewLuaFunctions = NULL;
} }
LuaFunctionList::LuaFunctionList( CString name_, lua_CFunction func_ ) LuaFunctionList::LuaFunctionList( CString name_, lua_CFunction func_ )
{ {
name = name_; name = name_;
func = func_; func = func_;
next = g_LuaFunctionList; next = g_NewLuaFunctions;
g_LuaFunctionList = this; g_NewLuaFunctions = this;
} }
+12 -12
View File
@@ -15,22 +15,22 @@ public:
float RunExpressionF( const CString &str ); float RunExpressionF( const CString &str );
bool RunExpressionS( const CString &str, CString &sOut ); bool RunExpressionS( const CString &str, CString &sOut );
void Fail( lua_State *L, const CString &err ); void Fail( const CString &err );
/* Add all registered functions into L. */ void SetGlobal( const CString &sName, int val ) { PushStack(val); SetGlobal( sName ); }
void RegisterFunctions( lua_State *L );
void PushStack( lua_State *L, bool out ); void PushStack( bool val );
void PushStack( lua_State *L, int out ); void PushStack( int val );
void PushStack( lua_State *L, void *out ); void PushStack( void *val );
void PushStack( lua_State *L, const CString &out ); void PushStack( const CString &val );
void PopStack( lua_State *L, CString &out ); void PopStack( CString &out );
bool GetStack( lua_State *L, int pos, int &out ); bool GetStack( int pos, int &out );
void SetGlobal( lua_State *L, const CString &sName ); void SetGlobal( const CString &sName );
lua_State *Get() { return L; }
private: private:
/* Register all functions in g_LuaFunctionList. */
void RegisterFunctions();
/* Run an expression. The result is left on the Lua stack. */ /* Run an expression. The result is left on the Lua stack. */
bool RunExpression( const CString &str ); bool RunExpression( const CString &str );
lua_State *L; lua_State *L;
+13 -23
View File
@@ -280,24 +280,14 @@ void ThemeManager::UpdateLuaGlobals()
THEME_SCREEN_WIDTH.Read(); THEME_SCREEN_WIDTH.Read();
THEME_SCREEN_HEIGHT.Read(); THEME_SCREEN_HEIGHT.Read();
lua_State *L = Lua::GetGlobalState(); LUA->SetGlobal( "SCREEN_WIDTH", (int) SCREEN_WIDTH );
LUA->SetGlobal( "SCREEN_HEIGHT", (int) SCREEN_HEIGHT );
Lua::PushStack( L, (int) SCREEN_WIDTH ); LUA->SetGlobal( "SCREEN_LEFT", (int) SCREEN_LEFT );
Lua::SetGlobal( L, "SCREEN_WIDTH" ); LUA->SetGlobal( "SCREEN_RIGHT", (int) SCREEN_RIGHT );
Lua::PushStack( L, (int) SCREEN_HEIGHT ); LUA->SetGlobal( "SCREEN_TOP", (int) SCREEN_TOP );
Lua::SetGlobal( L, "SCREEN_HEIGHT" ); LUA->SetGlobal( "SCREEN_BOTTOM", (int) SCREEN_BOTTOM );
Lua::PushStack( L, (int) SCREEN_LEFT ); LUA->SetGlobal( "SCREEN_CENTER_X", (int) SCREEN_CENTER_X );
Lua::SetGlobal( L, "SCREEN_LEFT" ); LUA->SetGlobal( "SCREEN_CENTER_Y", (int) SCREEN_CENTER_Y );
Lua::PushStack( L, (int) SCREEN_RIGHT );
Lua::SetGlobal( L, "SCREEN_RIGHT" );
Lua::PushStack( L, (int) SCREEN_TOP );
Lua::SetGlobal( L, "SCREEN_TOP" );
Lua::PushStack( L, (int) SCREEN_BOTTOM );
Lua::SetGlobal( L, "SCREEN_BOTTOM" );
Lua::PushStack( L, (int) SCREEN_CENTER_X );
Lua::SetGlobal( L, "SCREEN_CENTER_X" );
Lua::PushStack( L, (int) SCREEN_CENTER_Y );
Lua::SetGlobal( L, "SCREEN_CENTER_Y" );
} }
CString ThemeManager::GetThemeDirFromName( const CString &sThemeName ) CString ThemeManager::GetThemeDirFromName( const CString &sThemeName )
@@ -665,7 +655,7 @@ void ThemeManager::EvaluateString( CString &sText )
sText.erase( 0, 1 ); sText.erase( 0, 1 );
CString sOut; CString sOut;
Lua::RunExpressionS( sText, sOut ); LUA->RunExpressionS( sText, sOut );
sText = sOut; sText = sOut;
return; return;
} }
@@ -696,9 +686,9 @@ float ThemeManager::GetMetricF( const CString &sClassName, const CString &sValue
} }
#endif #endif
Lua::PrepareExpression( sValue ); LUA->PrepareExpression( sValue );
return Lua::RunExpressionF( sValue ); return LUA->RunExpressionF( sValue );
} }
// #include "LuaHelpers.h" // #include "LuaHelpers.h"
@@ -716,9 +706,9 @@ bool ThemeManager::GetMetricB( const CString &sClassName, const CString &sValueN
if( sValue.Left(1) == "1" ) if( sValue.Left(1) == "1" )
return true; /* optimization */ return true; /* optimization */
Lua::PrepareExpression( sValue ); LUA->PrepareExpression( sValue );
return Lua::RunExpressionB( sValue ); return LUA->RunExpressionB( sValue );
} }
RageColor ThemeManager::GetMetricC( const CString &sClassName, const CString &sValueName ) RageColor ThemeManager::GetMetricC( const CString &sClassName, const CString &sValueName )