/* Run the function at the top of the stack, which returns an actor description * table. If the table was returned, return true and leave it on the stack. * If not, display an error, return false, and leave nothing on the stack. */ bool ActorUtil::LoadTableFromStackShowErrors( Lua *L ) { LuaReference func; lua_pushvalue( L, -1 ); func.SetFromStack( L ); RString Error= "Lua runtime error: "; if( !LuaHelpers::RunScriptOnStack(L, Error, 0, 1, true) ) { lua_pop( L, 1 ); return false; } if( lua_type(L, -1) != LUA_TTABLE ) { lua_pop( L, 1 ); func.PushSelf( L ); lua_Debug debug; lua_getinfo( L, ">nS", &debug ); Error = ssprintf( "%s: must return a table", debug.short_src ); LuaHelpers::ReportScriptError(Error, "LUA_ERROR"); return false; } return true; }
void Message::SetParamTable( const LuaReference ¶ms ) { Lua *L = LUA->Get(); params.PushSelf( L ); m_pParams->SetFromStack( L ); LUA->Release( L ); }
Message::Message( const RString &s, const LuaReference ¶ms ) { m_sName = s; m_bBroadcast = false; Lua *L = LUA->Get(); m_pParams = new LuaTable; // XXX: creates an extra table params.PushSelf( L ); m_pParams->SetFromStack( L ); LUA->Release( L ); // m_pParams = new LuaTable( params ); }
static void GetGlobalTable( Lua *L ) { static LuaReference UserDataTable; if( !UserDataTable.IsSet() ) { lua_newtable( L ); UserDataTable.SetFromStack( L ); } UserDataTable.PushSelf( L ); }
/* Set up the enum table on the stack, and pop the table. */ void Enum::SetMetatable( lua_State *L, LuaReference &EnumTable, LuaReference &EnumIndexTable, const char *szName ) { EnumTable.PushSelf( L ); { lua_newtable( L ); EnumIndexTable.PushSelf( L ); lua_setfield( L, -2, "reverse" ); lua_pushstring( L, szName ); lua_setfield( L, -2, "name" ); PushEnumMethodTable( L ); lua_setfield( L, -2, "__index" ); lua_pushliteral( L, "Enum" ); LuaHelpers::PushValueFunc( L, 1 ); lua_setfield( L, -2, "__type" ); // for luaL_pushtype } lua_setmetatable( L, -2 ); lua_pop( L, 2 ); }
int CheckEnum( lua_State *L, LuaReference &table, int iPos, int iInvalid, const char *szType, bool bAllowInvalid ) { luaL_checkany( L, iPos ); if( lua_isnil(L, iPos) ) { if( bAllowInvalid ) return iInvalid; LuaHelpers::Push( L, ssprintf("Expected %s; got nil", szType) ); lua_error( L ); } iPos = LuaHelpers::AbsIndex( L, iPos ); table.PushSelf( L ); lua_pushvalue( L, iPos ); lua_gettable( L, -2 ); // If the result is nil, then a string was passed that is not a member of this enum. Throw // an error. To specify the invalid value, pass nil. That way, typos will throw an error, // and not silently result in nil, or an out-of-bounds value. if( unlikely(lua_isnil(L, -1)) ) { RString sGot; if( lua_isstring(L, iPos) ) { /* We were given a string, but it wasn't a valid value for this enum. Show * the string. */ lua_pushvalue( L, iPos ); LuaHelpers::Pop( L, sGot ); sGot = ssprintf( "\"%s\"", sGot.c_str() ); } else { /* We didn't get a string. Show the type. */ luaL_pushtype( L, iPos ); LuaHelpers::Pop( L, sGot ); } LuaHelpers::Push( L, ssprintf("Expected %s; got %s", szType, sGot.c_str() ) ); lua_error( L ); } int iRet = lua_tointeger( L, -1 ); lua_pop( L, 2 ); return iRet; }
void XNodeLuaValue::PushValue( lua_State *L ) const { m_Value.PushSelf( L ); }
template<> void Push<LuaReference>( lua_State *L, const LuaReference &Object ) { Object.PushSelf( L ); }
int CheckEnum( lua_State *L, LuaReference &table, int iPos, int iInvalid, const char *szType, bool bAllowInvalid, bool bAllowAnything ) { luaL_checkany( L, iPos ); if( lua_isnil(L, iPos) ) { if( bAllowInvalid ) return iInvalid; LuaHelpers::Push( L, ssprintf("Expected %s; got nil", szType) ); lua_error( L ); } iPos = LuaHelpers::AbsIndex( L, iPos ); table.PushSelf( L ); lua_pushvalue( L, iPos ); lua_gettable( L, -2 ); // If not found, check case-insensitively for legacy compatibility if( lua_isnil(L, -1) && lua_isstring(L, iPos) ) { RString sLower; // Get rid of nil value on stack lua_pop( L, 1 ); // Get the string and lowercase it lua_pushvalue( L, iPos ); LuaHelpers::Pop( L, sLower ); sLower.MakeLower(); // Try again to read the value table.PushSelf( L ); LuaHelpers::Push( L, sLower ); lua_gettable( L, -2 ); } // If the result is nil, then a string was passed that is not a member of this enum. Throw // an error. To specify the invalid value, pass nil. That way, typos will throw an error, // and not silently result in nil, or an out-of-bounds value. if( unlikely(lua_isnil(L, -1)) ) { RString sGot; if( lua_isstring(L, iPos) ) { /* We were given a string, but it wasn't a valid value for this enum. Show * the string. */ lua_pushvalue( L, iPos ); LuaHelpers::Pop( L, sGot ); sGot = ssprintf( "\"%s\"", sGot.c_str() ); } else { /* We didn't get a string. Show the type. */ luaL_pushtype( L, iPos ); LuaHelpers::Pop( L, sGot ); } LuaHelpers::Push( L, ssprintf("Expected %s; got %s", szType, sGot.c_str() ) ); // There are a couple places where CheckEnum is used outside of a // function called from lua. If we use lua_error from one of them, // StepMania crashes out completely. bAllowAnything allows those places // to avoid crashing over theme mistakes. if(bAllowAnything) { RString errmsg; LuaHelpers::Pop(L, errmsg); LOG->Warn(errmsg.c_str()); lua_pop(L, 2); return iInvalid; } lua_error( L ); } int iRet = lua_tointeger( L, -1 ); lua_pop( L, 2 ); return iRet; }