From 517ab45d8c73ce26d5bc6df8d4084bbf465decea Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 17 Jun 2012 06:57:13 +0000 Subject: Macro-ized the ForEachSomethingInChunk Lua glue code (will soon be used for block entities, too) git-svn-id: http://mc-server.googlecode.com/svn/trunk@627 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/ManualBindings.cpp | 187 +++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 92 deletions(-) (limited to 'source') diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index c1db27be4..f01fea278 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -102,96 +102,97 @@ static int tolua_LOGERROR(lua_State* tolua_S) -static int tolua_cWorld_ForEachEntityInChunk(lua_State * tolua_S) -{ - int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ - if ((NumArgs != 3) && (NumArgs != 4)) - { - LOGWARN("Error in function call 'ForEachEntityInChunk': Requires 3 or 4 arguments, got %i", NumArgs); - return 0; - } - - cWorld * self = (cWorld *) tolua_tousertype(tolua_S, 1, 0); - if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3)) - { - LOGWARN("Errorin function call 'ForEachEntityInChunk': Expected a number for parameters #1 and #2"); - return 0; - } - - int ChunkX = ((int)tolua_tonumber(tolua_S, 2, 0)); - int ChunkZ = ((int)tolua_tonumber(tolua_S, 3, 0)); - - if (!lua_isfunction( tolua_S, 4)) - { - LOGWARN("Error in function call 'ForEachEntityInChunk': Expected a function for parameter #3"); - 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 == 4) - { - TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (TableRef == LUA_REFNIL) - { - LOGWARN("Error in function call 'ForEachEntityInChunk': Could not get value reference of parameter #4"); - 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 'ForEachEntityInChunk': Could not get function reference of parameter #3"); - return 0; - } - - class cLuaPlayerCallback : public cItemCallback - { - 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(cEntity * a_Item) override - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ - tolua_pushusertype(LuaState, a_Item, "cEntity"); - 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; /* Abort 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->ForEachEntityInChunk(ChunkX, ChunkZ, 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; +#define DEFINE_LUA_FOREACHINCHUNK(CONTAINER,ITEM,FOREACH,FNNAME) \ +static int FNNAME(lua_State * tolua_S) \ +{ \ + int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ \ + if ((NumArgs != 3) && (NumArgs != 4)) \ + { \ + LOGWARN("Error in function call '" #FOREACH "': Requires 3 or 4 arguments, got %i", NumArgs); \ + return 0; \ + } \ + \ + CONTAINER * self = (CONTAINER *) tolua_tousertype(tolua_S, 1, 0); \ + if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3)) \ + { \ + LOGWARN("Errorin function call '" #FOREACH "': Expected a number for parameters #1 and #2"); \ + return 0; \ + } \ + \ + int ChunkX = ((int)tolua_tonumber(tolua_S, 2, 0)); \ + int ChunkZ = ((int)tolua_tonumber(tolua_S, 3, 0)); \ + \ + if (!lua_isfunction( tolua_S, 4)) \ + { \ + LOGWARN("Error in function call '" #FOREACH "': Expected a function for parameter #3"); \ + 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 == 4) \ + { \ + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); \ + if (TableRef == LUA_REFNIL) \ + { \ + LOGWARN("Error in function call '" #FOREACH "': Could not get value reference of parameter #4"); \ + 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 '" #FOREACH "': Could not get function reference of parameter #3"); \ + return 0; \ + } \ + \ + class cLuaCallback : public cItemCallback \ + { \ + public: \ + cLuaCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) \ + : LuaState( a_LuaState ) \ + , FuncRef( a_FuncRef ) \ + , TableRef( a_TableRef ) \ + {} \ + \ + private: \ + virtual bool Item(cEntity * a_Item) override \ + { \ + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ \ + tolua_pushusertype(LuaState, a_Item, "cEntity"); \ + 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; /* Abort 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->FOREACH(ChunkX, ChunkZ, 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; \ } @@ -236,10 +237,10 @@ static int FNNAME(lua_State * tolua_S) \ return 0; \ } \ \ - class cLuaPlayerCallback : public cItemCallback \ + class cLuaCallback : public cItemCallback \ { \ public: \ - cLuaPlayerCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) \ + cLuaCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) \ : LuaState( a_LuaState ) \ , FuncRef( a_FuncRef ) \ , TableRef( a_TableRef ) \ @@ -291,6 +292,8 @@ DEFINE_LUA_FOREACH(cWorld, cPlayer, ForEachPlayer, tolua_cWorld_ForEachPlayer); DEFINE_LUA_FOREACH(cRoot, cWorld, ForEachWorld, tolua_cRoot_ForEachWorld); DEFINE_LUA_FOREACH(cWorld, cEntity, ForEachEntity, tolua_cWorld_ForEachEntity); +DEFINE_LUA_FOREACHINCHUNK(cWorld, cEntity, ForEachEntityInChunk, tolua_cWorld_ForEachEntityInChunk); + -- cgit v1.2.3