summaryrefslogtreecommitdiffstats
path: root/source/ManualBindings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/ManualBindings.cpp')
-rw-r--r--source/ManualBindings.cpp93
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");