From 5e1033c567064ffc4a81ac5a2f916db98e3a50ee Mon Sep 17 00:00:00 2001 From: faketruth Date: Wed, 15 Feb 2012 13:16:42 +0000 Subject: Can now pass any argument to cWorld:ForEachPlayer in Lua! But I'm not even using it.. lol git-svn-id: http://mc-server.googlecode.com/svn/trunk@262 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/ManualBindings.cpp | 64 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'source') diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 840109a8f..ea6c18e29 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -103,6 +103,13 @@ static int tolua_LOGERROR(lua_State* tolua_S) static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) { + int NumArgs = lua_gettop( tolua_S )-1; // This includes 'self' + if( NumArgs != 1 && NumArgs != 2) + { + LOGWARN("Error in function call 'ForEachPlayer': Requires 1 or 2 arguments, got %i", NumArgs ); + return 0; + } + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); if( !lua_isfunction( tolua_S, 2 ) ) @@ -111,48 +118,69 @@ static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) return 0; } + // luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top + int TableRef = LUA_REFNIL; + if( NumArgs == 2 ) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( TableRef == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachPlayer': Could not get value reference of parameter #2"); + return 0; + } + } - int Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if( Reference == LUA_REFNIL ) + // table value is popped, and now function is on top of the stack + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( FuncRef == LUA_REFNIL ) { - LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference"); + LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference of parameter #1"); return 0; } - + class cLuaPlayerCallback : public cPlayerListCallback { + public: + cLuaPlayerCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: virtual bool Item(cPlayer * a_Player) override { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, Reference); + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference tolua_pushusertype( LuaState, a_Player, "cPlayer" ); - - int s = lua_pcall( LuaState, 1, 1, 0); + if( TableRef != LUA_REFNIL ) + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); // Push table reference + } + + int s = lua_pcall( LuaState, (TableRef==LUA_REFNIL?1:2), 1, 0); if( report_errors( LuaState, s ) ) { - return false; + return false; // Maybe we should return true? } if( lua_isboolean( LuaState, -1 ) ) { return (tolua_toboolean( LuaState, -1, 0) > 0); } - - LOGINFO("Stack size: %i", lua_gettop(LuaState) ); - return false; } - public: lua_State* LuaState; - int Reference; - } Callback; - - Callback.LuaState = tolua_S; - Callback.Reference = Reference; + int FuncRef; + int TableRef; + } Callback( tolua_S, FuncRef, TableRef ); bool bRetVal = self->ForEachPlayer( &Callback ); - luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); + // Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references + luaL_unref( tolua_S, LUA_REGISTRYINDEX, TableRef ); + luaL_unref( tolua_S, LUA_REGISTRYINDEX, FuncRef ); + // Push return value on stack tolua_pushboolean( tolua_S, bRetVal ); return 1; } -- cgit v1.2.3