From 1d6c55afcc31fdd9df6e9330c1e6812dfaf45a1a Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 2 Jun 2012 09:38:51 +0000 Subject: [PATCH] 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/Bindings.cpp | 50 +++++--------------- source/Bindings.h | 2 +- source/ManualBindings.cpp | 97 +++++++++++++++++++++++++++++++++++++-- source/cRoot.cpp | 25 ++++++---- source/cRoot.h | 22 +++++---- source/cWorld.h | 5 +- 6 files changed, 137 insertions(+), 64 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index dae86cc26..2b3f6b451 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 05/31/12 22:03:38. +** Generated automatically by tolua++-1.0.92 on 06/02/12 11:29:17. */ #ifndef __cplusplus @@ -12888,38 +12888,6 @@ static int tolua_AllToLua_cRoot_GetServer00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: GetWorld of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWorld00 -static int tolua_AllToLua_cRoot_GetWorld00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWorld'", NULL); -#endif - { - OBSOLETE cWorld* tolua_ret = (OBSOLETE cWorld*) self->GetWorld(); - tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld"); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: GetDefaultWorld of class cRoot */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetDefaultWorld00 static int tolua_AllToLua_cRoot_GetDefaultWorld00(lua_State* tolua_S) @@ -12953,9 +12921,10 @@ static int tolua_AllToLua_cRoot_GetDefaultWorld00(lua_State* tolua_S) #endif //#ifndef TOLUA_DISABLE /* method: GetWorld of class cRoot */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWorld01 -static int tolua_AllToLua_cRoot_GetWorld01(lua_State* tolua_S) +#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetWorld00 +static int tolua_AllToLua_cRoot_GetWorld00(lua_State* tolua_S) { +#ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) || @@ -12964,6 +12933,7 @@ static int tolua_AllToLua_cRoot_GetWorld01(lua_State* tolua_S) ) goto tolua_lerror; else +#endif { cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0); const AString a_WorldName = ((const AString) tolua_tocppstring(tolua_S,2,0)); @@ -12977,8 +12947,11 @@ static int tolua_AllToLua_cRoot_GetWorld01(lua_State* tolua_S) } } return 2; -tolua_lerror: - return tolua_AllToLua_cRoot_GetWorld00(tolua_S); +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetWorld'.",&tolua_err); + return 0; +#endif } #endif //#ifndef TOLUA_DISABLE @@ -18563,9 +18536,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_beginmodule(tolua_S,"cRoot"); tolua_function(tolua_S,"Get",tolua_AllToLua_cRoot_Get00); tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00); - tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00); tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00); - tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld01); + tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00); tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00); tolua_function(tolua_S,"GetRecipeChecker",tolua_AllToLua_cRoot_GetRecipeChecker00); tolua_function(tolua_S,"GetFurnaceRecipe",tolua_AllToLua_cRoot_GetFurnaceRecipe00); diff --git a/source/Bindings.h b/source/Bindings.h index 8595c838a..5ffda8f50 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 05/31/12 22:03:38. +** Generated automatically by tolua++-1.0.92 on 06/02/12 11:29:17. */ /* Exported function */ 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); diff --git a/source/cRoot.cpp b/source/cRoot.cpp index d110c96a3..fd3132f28 100644 --- a/source/cRoot.cpp +++ b/source/cRoot.cpp @@ -247,15 +247,6 @@ void cRoot::UnloadWorlds() -cWorld* cRoot::GetWorld() -{ - return GetDefaultWorld(); -} - - - - - cWorld* cRoot::GetDefaultWorld() { return m_pState->pDefaultWorld; @@ -277,6 +268,22 @@ cWorld* cRoot::GetWorld( const AString & a_WorldName ) +bool cRoot::ForEachWorld(cWorldListCallback & a_Callback) +{ + for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) + { + if (a_Callback.Item(itr->second)) + { + return false; + } + } + return true; +} + + + + + void cRoot::TickWorlds( float a_Dt ) { for( WorldMap::iterator itr = m_pState->WorldsByName.begin(); itr != m_pState->WorldsByName.end(); ++itr ) diff --git a/source/cRoot.h b/source/cRoot.h index 3f65305db..5fc43afe8 100644 --- a/source/cRoot.h +++ b/source/cRoot.h @@ -21,6 +21,7 @@ class cServer; class cWorld; class cPlayer; typedef cItemCallback cPlayerListCallback; +typedef cItemCallback cWorldListCallback; @@ -36,18 +37,21 @@ public: void Start(); - cServer* GetServer() { return m_Server; } //tolua_export - OBSOLETE cWorld* GetWorld(); //tolua_export - cWorld* GetDefaultWorld(); //tolua_export + cServer* GetServer(void) { return m_Server; } //tolua_export + cWorld* GetDefaultWorld(void); //tolua_export cWorld* GetWorld( const AString & a_WorldName ); //tolua_export + + /// Calls the callback for each world; returns true if the callback didn't abort (return true) + bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings << + cMonsterConfig *GetMonsterConfig() { return m_MonsterConfig;} - cGroupManager* GetGroupManager() { return m_GroupManager; } //tolua_export - cRecipeChecker* GetRecipeChecker() { return m_RecipeChecker; } //tolua_export - cFurnaceRecipe* GetFurnaceRecipe() { return m_FurnaceRecipe; } //tolua_export - cWebAdmin* GetWebAdmin() { return m_WebAdmin; } //tolua_export - cPluginManager* GetPluginManager() { return m_PluginManager; } //tolua_export - cAuthenticator & GetAuthenticator() {return m_Authenticator; } + cGroupManager * GetGroupManager (void) { return m_GroupManager; } // tolua_export + cRecipeChecker * GetRecipeChecker(void) { return m_RecipeChecker; } // tolua_export + cFurnaceRecipe * GetFurnaceRecipe(void) { return m_FurnaceRecipe; } // tolua_export + cWebAdmin * GetWebAdmin (void) { return m_WebAdmin; } // tolua_export + cPluginManager * GetPluginManager(void) { return m_PluginManager; } // tolua_export + cAuthenticator & GetAuthenticator(void) { return m_Authenticator; } void ServerCommand(const char* a_Cmd ); //tolua_export diff --git a/source/cWorld.h b/source/cWorld.h index 0664c72cc..3f8080f06 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -123,9 +123,8 @@ public: void AddPlayer( cPlayer* a_Player ); void RemovePlayer( cPlayer* a_Player ); - typedef struct lua_State lua_State; - bool ForEachPlayer(cPlayerListCallback & a_Callback); // Calls the callback for each player in the list - // >> EXPORTED IN MANUALBINDINGS << + bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + unsigned int GetNumPlayers(); //tolua_export // TODO: This interface is dangerous - rewrite to DoWithPlayer(playername, action)