From 3b993dfa08363c3753f76e4ddc182417246023dc Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Thu, 24 Feb 2005 20:03:07 +0000 Subject: [PATCH] Replace PopStack with FromStack as a basic overloaded function. Move Push and FromStack into a namespace, so other files can add to it; that way, we can say Push(1) or Push(Actor*), instead of Push(1) and pActor->PushSelf(), allowing easier templating. Add presently unused/untested LuaHelpers::ReadArrayFromTable. --- stepmania/src/LuaBinding.h | 4 +- stepmania/src/LuaFunctions.h | 3 +- stepmania/src/LuaManager.cpp | 111 ++++++++--------------------------- stepmania/src/LuaManager.h | 68 +++++++++++++++++---- 4 files changed, 84 insertions(+), 102 deletions(-) diff --git a/stepmania/src/LuaBinding.h b/stepmania/src/LuaBinding.h index 017af4513e..0f415fada2 100644 --- a/stepmania/src/LuaBinding.h +++ b/stepmania/src/LuaBinding.h @@ -140,7 +140,9 @@ private: template<> const char Luna::s_className[] = #T; \ template<> Luna::RegTypeVector* Luna::s_pvMethods = NULL; \ static Luna##T registera; \ -void T::PushSelf( lua_State *L ) { Luna##T::Push( L, this ); } +void T::PushSelf( lua_State *L ) { Luna##T::Push( L, this ); } \ +/* Call PushSelf, so we always call the derived Luna::Push. */ \ +namespace LuaHelpers { template<> void Push( T *pObject, lua_State *L ) { pObject->PushSelf( L ); } } #define ADD_METHOD( method_name ) \ { Luna::CreateMethodsVector(); RegType r = {#method_name,method_name}; Luna::s_pvMethods->push_back(r); } diff --git a/stepmania/src/LuaFunctions.h b/stepmania/src/LuaFunctions.h index f751af5de3..1952f97662 100644 --- a/stepmania/src/LuaFunctions.h +++ b/stepmania/src/LuaFunctions.h @@ -1,7 +1,6 @@ #ifndef LUA_FUNCTIONS_H #define LUA_FUNCTIONS_H -#include "LuaManager.h" #include "RageUtil.h" /* for ssprintf */ extern "C" @@ -36,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, L ) { LUA->PushStack( expr, L ); return 1; } +#define LUA_RETURN( expr, L ) { LuaHelpers::Push( expr, L ); return 1; } /* Helpers to create common functions: */ /* Functions that take no arguments: */ diff --git a/stepmania/src/LuaManager.cpp b/stepmania/src/LuaManager.cpp index 4169fbebb8..9c62c324c8 100644 --- a/stepmania/src/LuaManager.cpp +++ b/stepmania/src/LuaManager.cpp @@ -10,7 +10,14 @@ #include #include - +/* +#include "Actor.h" +void foo() +{ + Actor *p = NULL; + LuaHelpers::Push( p, NULL ); +} +*/ LuaManager *LUA = NULL; static LuaFunctionList *g_LuaFunctions = NULL; @@ -59,101 +66,29 @@ void LuaManager::PushStackNil() lua_pushnil( L ); } -void LuaManager::PushStack( int out, lua_State *L ) + +void LuaHelpers::Push( const bool &Object, lua_State *L ) { lua_pushboolean( L, Object ); } +void LuaHelpers::Push( const float &Object, lua_State *L ) { lua_pushnumber( L, Object ); } +void LuaHelpers::Push( const int &Object, lua_State *L ) { lua_pushnumber( L, Object ); } +void LuaHelpers::Push( void *Object, lua_State *L ) { - if( L == NULL ) - L = LUA->L; - - /* XXX: stack bounds */ - lua_pushnumber( L, out ); -} - -void LuaManager::PushStack( bool out, lua_State *L ) -{ - if( L == NULL ) - L = LUA->L; - - /* XXX: stack bounds */ - lua_pushboolean( L, out ); -} - -void LuaManager::PushStack( float val, lua_State *L ) -{ - if( L == NULL ) - L = LUA->L; - - /* XXX: stack bounds */ - lua_pushnumber( L, val ); -} - -void LuaManager::PushStack( void *out, lua_State *L ) -{ - if( L == NULL ) - L = LUA->L; - - if( out ) - lua_pushlightuserdata( L, out ); + if( Object != NULL ) + lua_pushlightuserdata( L, Object ); else lua_pushnil( L ); } +void LuaHelpers::Push( const CString &Object, lua_State *L ) { lua_pushstring( L, Object ); } -void LuaManager::PushStack( const CString &out, lua_State *L ) +bool LuaHelpers::FromStack( bool &Object, int iOffset, lua_State *L ) { Object = !!lua_toboolean( L, iOffset ); return true; } +bool LuaHelpers::FromStack( float &Object, int iOffset, lua_State *L ) { Object = (float)lua_tonumber( L, iOffset ); return true; } +bool LuaHelpers::FromStack( int &Object, int iOffset, lua_State *L ) { Object = (int) lua_tonumber( L, iOffset ); return true; } +bool LuaHelpers::FromStack( void *&Object, int iOffset, lua_State *L ) { Object = lua_touserdata( L, iOffset ); return true; } +bool LuaHelpers::FromStack( CString &Object, int iOffset, lua_State *L ) { - if( L == NULL ) - L = LUA->L; - lua_pushstring( L, out ); -} - -bool LuaManager::PopStack( int &out, lua_State *L ) -{ - if( L == NULL ) - L = LUA->L; - - out = (int) lua_tonumber( L, -1 ); - lua_pop( L, 1 ); - return true; -} - -bool LuaManager::PopStack( bool &out, lua_State *L ) -{ - if( L == NULL ) - L = LUA->L; - - out = !!lua_toboolean( L, -1 ); - lua_pop( L, 1 ); - return true; -} - -bool LuaManager::PopStack( float &val, lua_State *L ) -{ - if( L == NULL ) - L = LUA->L; - - val = (float)lua_tonumber( L, -1 ); - lua_pop( L, 1 ); - return true; -} - -bool LuaManager::PopStack( void *&out, lua_State *L ) -{ - if( L == NULL ) - L = LUA->L; - - out = lua_touserdata( L, -1 ); - lua_pop( L, 1 ); - return true; -} - -bool LuaManager::PopStack( CString &out, lua_State *L ) -{ - if( L == NULL ) - L = LUA->L; - - const char *pStr = lua_tostring( L, -1 ); + const char *pStr = lua_tostring( L, iOffset ); if( pStr != NULL ) - out = pStr; + Object = pStr; - lua_pop( L, 1 ); return pStr != NULL; } diff --git a/stepmania/src/LuaManager.h b/stepmania/src/LuaManager.h index db37fca193..5e18728944 100644 --- a/stepmania/src/LuaManager.h +++ b/stepmania/src/LuaManager.h @@ -1,9 +1,49 @@ #ifndef LUA_MANAGER_H #define LUA_MANAGER_H +#include "LuaFunctions.h" + struct lua_State; typedef void (*RegisterWithLuaFn)(lua_State*); +namespace LuaHelpers +{ + template + void Push( T *pObject, lua_State *L ); + + void Push( const bool &Object, lua_State *L ); + void Push( const float &Object, lua_State *L ); + void Push( const int &Object, lua_State *L ); + void Push( void *Object, lua_State *L ); + void Push( const CString &Object, lua_State *L ); + + + bool FromStack( bool &Object, int iOffset, lua_State *L ); + bool FromStack( float &Object, int iOffset, lua_State *L ); + bool FromStack( int &Object, int iOffset, lua_State *L ); + bool FromStack( void *&Object, int iOffset, lua_State *L ); + bool FromStack( CString &Object, int iOffset, lua_State *L ); + + template + void ReadArrayFromTable( vector aOut, lua_State *L ) + { + if( L == NULL ) + L = LUA->L; + + luaL_checktype( L, -1, LUA_TTABLE ); + + unsigned iCount = luaL_getn( L, -1 ); + + for( unsigned i = 0; i < iCount; ++i ) + { + lua_rawgeti( L, -1, i+1 ); + T value = T(); + LuaHelpers::FromStack( value, -1, L ); + aOut.push_back( value ); + lua_pop( L, 1 ); + } + } +}; class LuaManager { @@ -48,19 +88,25 @@ public: void SetGlobal( const CString &sName, bool val ) { PushStack(val); SetGlobal( sName ); } void UnsetGlobal( const CString &sName ) { PushStackNil(); SetGlobal( sName ); } - // XXX: yuck void PushStackNil(); void PushNopFunction(); - static void PushStack( bool val, lua_State *L = NULL ); - static void PushStack( float val, lua_State *L = NULL ); - static void PushStack( int val, lua_State *L = NULL ); - static void PushStack( void *val, lua_State *L = NULL ); - static void PushStack( const CString &val, lua_State *L = NULL ); - static bool PopStack( bool &val, lua_State *L = NULL ); - static bool PopStack( float &val, lua_State *L = NULL ); - static bool PopStack( int &val, lua_State *L = NULL ); - static bool PopStack( void *&val, lua_State *L = NULL ); - static bool PopStack( CString &val, lua_State *L = NULL ); + template + static void PushStack( const T &val, lua_State *L = NULL ) + { + if( L == NULL ) + L = LUA->L; + LuaHelpers::Push( val, L ); + } + + template + static bool PopStack( T &val, lua_State *L = NULL ) + { + if( L == NULL ) + L = LUA->L; + bool bRet = LuaHelpers::FromStack( val, -1, L ); + lua_pop( L, 1 ); + return bRet; + } bool GetStack( int pos, int &out ); void SetGlobal( const CString &sName );