diff options
Diffstat (limited to '')
-rw-r--r-- | source/ManualBindings.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 5133d03c7..6e07b0aff 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -194,6 +194,95 @@ static int FNNAME(lua_State * tolua_S) \ +#define DEFINE_LUA_DOWITH_XYZ(CONTAINER,ITEM,FOREACH,FNNAME) \ + static int FNNAME(lua_State * tolua_S) \ + { \ + int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ \ + if ((NumArgs != 4) && (NumArgs != 5)) \ + { \ + LOGWARN("Error in function call '" #FOREACH "': Requires 4 or 5 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) || !lua_isnumber(tolua_S, 4)) \ + { \ + LOGWARN("Error in function call '" #FOREACH "': Expected a number for parameters #1, #2 and #3"); \ + return 0; \ + } \ + \ + int ItemX = ((int)tolua_tonumber(tolua_S, 2, 0)); \ + int ItemY = ((int)tolua_tonumber(tolua_S, 3, 0)); \ + int ItemZ = ((int)tolua_tonumber(tolua_S, 4, 0)); \ + LOG("x %i y %i z %i", ItemX, ItemY, ItemZ ); \ + if (!lua_isfunction( tolua_S, 5)) \ + { \ + LOGWARN("Error in function call '" #FOREACH "': Expected a function for parameter #2"); \ + 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 == 5) \ + { \ + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); \ + if (TableRef == LUA_REFNIL) \ + { \ + LOGWARN("Error in function call '" #FOREACH "': Could not get value reference of parameter #3"); \ + 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 #2"); \ + return 0; \ + } \ + \ + class cLuaCallback : public cItemCallback<ITEM> \ + { \ + 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(ITEM * a_Item) override \ + { \ + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ \ + tolua_pushusertype(LuaState, a_Item, #ITEM); \ + 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); \ + report_errors(LuaState, s); \ + return true; \ + } \ + lua_State * LuaState; \ + int FuncRef; \ + int TableRef; \ + } Callback(tolua_S, FuncRef, TableRef); \ + \ + bool bRetVal = self->FOREACH(ItemX, ItemY, ItemZ, 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) \ @@ -386,6 +475,9 @@ DEFINE_LUA_DOWITH(cWorld, cPlayer, DoWithPlayer, tolua_cWorld_DoWithPlaye DEFINE_LUA_DOWITH(cWorld, cPlayer, FindAndDoWithPlayer, tolua_cWorld_FindAndDoWithPlayer); DEFINE_LUA_DOWITH(cRoot, cPlayer, FindAndDoWithPlayer, tolua_cRoot_FindAndDoWithPlayer); +// Define the DoWith...At enumerators: (takes one 3D coordinate and a callback class) +DEFINE_LUA_DOWITH_XYZ(cWorld, cChestEntity, DoWithChestAt, tolua_cWorld_DoWithChestAt ); + // Define the ForEach enumerators: DEFINE_LUA_FOREACH(cWorld, cPlayer, ForEachPlayer, tolua_cWorld_ForEachPlayer); DEFINE_LUA_FOREACH(cWorld, cEntity, ForEachEntity, tolua_cWorld_ForEachEntity); @@ -718,6 +810,7 @@ void ManualBindings::Bind( lua_State* tolua_S ) tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_cWorld_ForEachFurnaceInChunk); tolua_function(tolua_S, "DoWithPlayer", tolua_cWorld_DoWithPlayer); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_cWorld_FindAndDoWithPlayer); + tolua_function(tolua_S, "DoWithChestAt", tolua_cWorld_DoWithChestAt); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlugin"); |