From 1d6c55afcc31fdd9df6e9330c1e6812dfaf45a1a Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 2 Jun 2012 09:38:51 +0000 Subject: Added Lua function cRoot:ForEachWorld(), removed the obsolete cRoot:GetWorld() method (both C++ and Lua) git-svn-id: http://mc-server.googlecode.com/svn/trunk@534 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/ManualBindings.cpp | 97 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 3 deletions(-) (limited to 'source/ManualBindings.cpp') diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index ba3b99e14..b6e1e9f72 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -102,6 +102,94 @@ static int tolua_LOGERROR(lua_State* tolua_S) +static int tolua_cRoot_ForEachWorld(lua_State * tolua_S) +{ + int NumArgs = lua_gettop( tolua_S ) - 1; // This includes 'self' + if ((NumArgs != 1) && (NumArgs != 2)) + { + LOGWARN("Error in function call 'ForEachWorld': Requires 1 or 2 arguments, got %i", NumArgs); + return 0; + } + + cRoot * self = (cRoot *)tolua_tousertype(tolua_S, 1, 0); + + if (!lua_isfunction(tolua_S, 2)) + { + LOGWARN("Error in function call 'ForEachWorld': Expected a function for parameter #1"); + 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 'ForEachWorld': Could not get value reference of parameter #2"); + return 0; + } + } + + // 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 'ForEachWorld': Could not get function reference of parameter #1"); + return 0; + } + + class cLuaWorldCallback : public cWorldListCallback + { + public: + cLuaWorldCallback( lua_State* a_LuaState, int a_FuncRef, int a_TableRef ) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: + virtual bool Item(cWorld * a_World) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference + tolua_pushusertype( LuaState, a_World, "cWorld" ); + 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 true; // break enumeration + } + + if (lua_isboolean( LuaState, -1)) + { + return (tolua_toboolean( LuaState, -1, 0) > 0); + } + return false; // continue enumeration + } + lua_State* LuaState; + int FuncRef; + int TableRef; + } Callback( tolua_S, FuncRef, TableRef ); + + bool bRetVal = self->ForEachWorld(Callback); + + // 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; +} + + + + + static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) { int NumArgs = lua_gettop( tolua_S )-1; // This includes 'self' @@ -161,16 +249,16 @@ static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) int s = lua_pcall( LuaState, (TableRef==LUA_REFNIL?1:2), 1, 0); if( report_errors( LuaState, s ) ) { - return false; // Maybe we should return true? + return true; // Abort enumeration } if( lua_isboolean( LuaState, -1 ) ) { return (tolua_toboolean( LuaState, -1, 0) > 0); } - return false; + return false; // Continue enumeration } - lua_State* LuaState; + lua_State * LuaState; int FuncRef; int TableRef; } Callback( tolua_S, FuncRef, TableRef ); @@ -481,6 +569,9 @@ void ManualBindings::Bind( lua_State* tolua_S ) tolua_function(tolua_S,"LOGERROR",tolua_LOGERROR); tolua_function(tolua_S,"Log",tolua_LOG); // Deprecated + tolua_beginmodule(tolua_S,"cRoot"); + tolua_function(tolua_S,"ForEachWorld",tolua_cRoot_ForEachWorld); + tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S,"cWorld"); tolua_function(tolua_S,"ForEachPlayer",tolua_cWorld_ForEachPlayer); tolua_endmodule(tolua_S); -- cgit v1.2.3