summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/ChestEntity.h2
-rw-r--r--source/Entity.cpp14
-rw-r--r--source/Entity.h32
-rw-r--r--source/FurnaceEntity.h2
-rw-r--r--source/ManualBindings.cpp769
-rw-r--r--source/World.h5
6 files changed, 421 insertions, 403 deletions
diff --git a/source/ChestEntity.h b/source/ChestEntity.h
index 78746cfdf..cef53f037 100644
--- a/source/ChestEntity.h
+++ b/source/ChestEntity.h
@@ -31,6 +31,8 @@ public:
virtual ~cChestEntity();
virtual void Destroy();
+ static const char * GetClassStatic() { return "cChestEntity"; }
+
const cItem * GetSlot(int a_Slot) const; // tolua_export
void SetSlot(int a_Slot, const cItem & a_Item ); // tolua_export
diff --git a/source/Entity.cpp b/source/Entity.cpp
index e3af6d4d3..43f9e9431 100644
--- a/source/Entity.cpp
+++ b/source/Entity.cpp
@@ -70,7 +70,19 @@ cEntity::~cEntity()
-CLASS_DEF_GETCLASS(cEntity);
+const char * cEntity::GetClass(void) const
+{
+ return "cEntity";
+}
+
+
+
+
+
+const char * cEntity::GetClassStatic(void)
+{
+ return "cEntity";
+}
diff --git a/source/Entity.h b/source/Entity.h
index 94f565385..8d8d2690b 100644
--- a/source/Entity.h
+++ b/source/Entity.h
@@ -11,31 +11,6 @@
-#define CLASS_PROT_ISA() virtual bool IsA(const char * a_EntityType) const override;
-#define CLASS_PROT_GETCLASS() virtual const char * GetClass (void) const override;
-#define CLASS_PROT_GETPARENT() virtual const char * GetParentClass(void) const override;
-
-#define CLASS_PROTOTYPE() \
- CLASS_PROT_ISA(); \
- CLASS_PROT_GETCLASS(); \
- CLASS_PROT_GETPARENT();
-
-#define CLASS_DEF_ISA(classname) \
- bool classname::IsA(const char * a_ClassName) const \
- { \
- return ((strcmp(a_ClassName, #classname) == 0) || super::IsA(a_ClassName)); \
- }
-
-#define CLASS_DEF_GETCLASS(classname) \
- const char * classname::GetClass(void) const \
- { \
- return #classname; \
- }
-
-#define CLASS_DEFINITION(classname) \
- CLASS_DEF_ISA(classname) \
- CLASS_DEF_GETCLASS(classname)
-
// Place this macro in the header of each cEntity descendant class and you're done :)
#define CLASS_PROTODEF(classname) \
virtual bool IsA(const char * a_ClassName) const override\
@@ -46,6 +21,10 @@
{ \
return #classname; \
} \
+ static const char * GetClassStatic(void) \
+ { \
+ return #classname; \
+ } \
virtual const char * GetParentClass(void) const override \
{ \
return super::GetClass(); \
@@ -109,6 +88,9 @@ public:
/// Returns the topmost class name for the object
virtual const char * GetClass(void) const;
+
+ // Returns the class name of this class
+ static const char * GetClassStatic(void);
/// Returns the topmost class's parent class name for the object. cEntity returns an empty string (no parent).
virtual const char * GetParentClass(void) const;
diff --git a/source/FurnaceEntity.h b/source/FurnaceEntity.h
index 1c417c739..bcdc8d837 100644
--- a/source/FurnaceEntity.h
+++ b/source/FurnaceEntity.h
@@ -30,6 +30,8 @@ public:
virtual ~cFurnaceEntity();
virtual void Destroy();
+ static const char * GetClassStatic() { return "cFurnaceEntity"; }
+
bool LoadFromFile(cFile & a_File); // deprecated format
bool LoadFromJson(const Json::Value& a_Value );
diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp
index 5b2b6ff9e..b7d31a79d 100644
--- a/source/ManualBindings.cpp
+++ b/source/ManualBindings.cpp
@@ -13,6 +13,8 @@
#include "WebAdmin.h"
#include "StringMap.h"
#include "ClientHandle.h"
+#include "ChestEntity.h"
+#include "FurnaceEntity.h"
#include "md5/md5.h"
@@ -27,6 +29,54 @@ bool report_errors(lua_State* lua, int status);
/****************************
+ * Better error reporting for Lua
+ **/
+int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaError)
+{
+ // Retrieve current function name
+ lua_Debug entry;
+ ASSERT( lua_getstack(L, 0, &entry) );
+ ASSERT( lua_getinfo(L, "n", &entry) );
+
+ // Insert function name into error msg
+ AString msg(a_pMsg);
+ ReplaceString(msg, "#funcname#", entry.name?entry.name:"?");
+
+ // Send the error to Lua
+ tolua_error(L, msg.c_str(), a_pToLuaError);
+ return 0;
+}
+
+
+
+
+
+int lua_do_error(lua_State* L, const char * a_pFormat, ...)
+{
+ // Retrieve current function name
+ lua_Debug entry;
+ ASSERT( lua_getstack(L, 0, &entry) );
+ ASSERT( lua_getinfo(L, "n", &entry) );
+
+ // Insert function name into error msg
+ AString msg(a_pFormat);
+ ReplaceString(msg, "#funcname#", entry.name?entry.name:"?");
+
+ // Copied from luaL_error and modified
+ va_list argp;
+ va_start(argp, a_pFormat);
+ luaL_where(L, 1);
+ lua_pushvfstring(L, msg.c_str(), argp);
+ va_end(argp);
+ lua_concat(L, 2);
+ return lua_error(L);
+}
+
+
+
+
+
+/****************************
* Lua bound functions with special return types
**/
@@ -98,390 +148,360 @@ static int tolua_LOGERROR(lua_State* tolua_S)
-#define DEFINE_LUA_DOWITH(CONTAINER,ITEM,FOREACH,FNNAME) \
-static int FNNAME(lua_State * tolua_S) \
-{ \
- int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ \
- if ((NumArgs != 2) && (NumArgs != 3)) \
- { \
- LOGWARN("Error in function call '" #FOREACH "': Requires 2 or 3 arguments, got %i", NumArgs ); \
- return 0; \
- } \
- \
- CONTAINER * self = (CONTAINER *) tolua_tousertype(tolua_S, 1, 0); \
- \
- const char * ItemName = tolua_tocppstring(tolua_S, 2, ""); \
- if ((ItemName == NULL) || (ItemName[0] == 0)) \
- { \
- LOGWARN("Error in function call '" #FOREACH "': Expected a non-empty string for parameter #1"); \
- return 0; \
- } \
- if (!lua_isfunction( tolua_S, 3)) \
- { \
- 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 == 3) \
- { \
- 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(ItemName, 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; \
+template<
+ class Ty1,
+ class Ty2,
+ bool (Ty1::*Func1)(const AString &, cItemCallback<Ty2> &)
+ >
+static int tolua_DoWith(lua_State* tolua_S)
+{
+ int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */
+ if ((NumArgs != 2) && (NumArgs != 3))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 2 or 3 arguments, got %i", NumArgs);
+ }
+
+ Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0);
+
+ const char * ItemName = tolua_tocppstring(tolua_S, 2, "");
+ if ((ItemName == NULL) || (ItemName[0] == 0))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a non-empty string for parameter #1", NumArgs);
+ }
+ if (!lua_isfunction( tolua_S, 3))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #2", NumArgs);
+ }
+
+ /* 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 == 3)
+ {
+ TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
+ if (TableRef == LUA_REFNIL)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get value reference of parameter #3", NumArgs);
+ }
+ }
+
+ /* 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)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #2", NumArgs);
+ }
+
+ class cLuaCallback : public cItemCallback<Ty2>
+ {
+ 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(Ty2 * a_Item) override
+ {
+ lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */
+ tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic());
+ 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->*Func1)(ItemName, 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_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; \
- }
+
+template< class Ty1,
+ class Ty2,
+ bool (Ty1::*Func1)(int, int, int, cItemCallback<Ty2> &) >
+static int tolua_DoWithXYZ(lua_State* tolua_S)
+{
+ int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */
+ if ((NumArgs != 4) && (NumArgs != 5))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 4 or 5 arguments, got %i", NumArgs);
+ }
+
+ Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0);
+ if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3) || !lua_isnumber(tolua_S, 4))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3");
+ }
+
+ 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))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #4");
+ }
+
+ /* 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)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get value reference of parameter #5");
+ }
+ }
+
+ /* 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)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #4");
+ }
+
+ class cLuaCallback : public cItemCallback<Ty2>
+ {
+ 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(Ty2 * a_Item) override
+ {
+ lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */
+ tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic());
+ 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->*Func1)(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) \
-{ \
- 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<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); \
- 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; \
+template< class Ty1,
+ class Ty2,
+ bool (Ty1::*Func1)(int, int, cItemCallback<Ty2> &) >
+static int tolua_ForEachInChunk(lua_State* tolua_S)
+{
+ int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */
+ if ((NumArgs != 3) && (NumArgs != 4))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 3 or 4 arguments, got %i", NumArgs);
+ }
+
+ Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0);
+ if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a number for parameters #1 and #2");
+ }
+
+ int ChunkX = ((int)tolua_tonumber(tolua_S, 2, 0));
+ int ChunkZ = ((int)tolua_tonumber(tolua_S, 3, 0));
+
+ if (!lua_isfunction( tolua_S, 4))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #3");
+ }
+
+ /* 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)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get value reference of parameter #4");
+ }
+ }
+
+ /* 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)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #3");
+ }
+
+ class cLuaCallback : public cItemCallback<Ty2>
+ {
+ 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(Ty2 * a_Item) override
+ {
+ lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */
+ tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic());
+ 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->*Func1)(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_FOREACH(CONTAINER,ITEM,FOREACH,FNNAME) \
-static int FNNAME(lua_State * tolua_S) \
-{ \
- int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ \
- if( NumArgs != 1 && NumArgs != 2) \
- { \
- LOGWARN("Error in function call '" #FOREACH "': Requires 1 or 2 arguments, got %i", NumArgs ); \
- return 0; \
- } \
- \
- CONTAINER * self = (CONTAINER *) tolua_tousertype(tolua_S, 1, 0); \
- if (self == NULL) \
- { \
- LOGWARN("Error in function call '" #FOREACH "': Not called on an object instance"); \
- return 0; \
- } \
- \
- if (!lua_isfunction( tolua_S, 2)) \
- { \
- LOGWARN("Error in function call '" #FOREACH "': 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 '" #FOREACH "': 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 '" #FOREACH "': Could not get function reference of parameter #1"); \
- 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); \
- 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(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; \
-}
+template< class Ty1,
+ class Ty2,
+ bool (Ty1::*Func1)(cItemCallback<Ty2> &) >
+static int tolua_ForEach(lua_State * tolua_S)
+{
+ int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */
+ if( NumArgs != 1 && NumArgs != 2)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 1 or 2 arguments, got %i", NumArgs);
+ }
+
+ Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0);
+ if (self == NULL)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
+ }
+
+ if (!lua_isfunction( tolua_S, 2))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #1");
+ }
+ /* 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)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get value reference of parameter #2");
+ }
+ }
+ /* 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)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
+ }
+ class cLuaCallback : public cItemCallback<Ty2>
+ {
+ 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(Ty2 * a_Item) override
+ {
+ lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */
+ tolua_pushusertype( LuaState, a_Item, Ty2::GetClassStatic() );
+ 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 */
+ }
-// Define the DoWith enumerators: (they take a string and a callback class)
-DEFINE_LUA_DOWITH(cWorld, cPlayer, DoWithPlayer, tolua_cWorld_DoWithPlayer);
-DEFINE_LUA_DOWITH(cWorld, cPlayer, FindAndDoWithPlayer, tolua_cWorld_FindAndDoWithPlayer);
-DEFINE_LUA_DOWITH(cRoot, cPlayer, FindAndDoWithPlayer, tolua_cRoot_FindAndDoWithPlayer);
+ 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);
-// Define the DoWith...At enumerators: (takes one 3D coordinate and a callback class)
-DEFINE_LUA_DOWITH_XYZ(cWorld, cChestEntity, DoWithChestAt, tolua_cWorld_DoWithChestAt );
+ bool bRetVal = (self->*Func1)(Callback);
-// Define the ForEach enumerators:
-DEFINE_LUA_FOREACH(cWorld, cPlayer, ForEachPlayer, tolua_cWorld_ForEachPlayer);
-DEFINE_LUA_FOREACH(cWorld, cEntity, ForEachEntity, tolua_cWorld_ForEachEntity);
-DEFINE_LUA_FOREACH(cRoot, cWorld, ForEachWorld, tolua_cRoot_ForEachWorld);
-DEFINE_LUA_FOREACH(cRoot, cPlayer, ForEachPlayer, tolua_cRoot_ForEachPlayer);
+ /* 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);
-DEFINE_LUA_FOREACHINCHUNK(cWorld, cEntity, ForEachEntityInChunk, tolua_cWorld_ForEachEntityInChunk);
-DEFINE_LUA_FOREACHINCHUNK(cWorld, cChestEntity, ForEachChestInChunk, tolua_cWorld_ForEachChestInChunk);
-DEFINE_LUA_FOREACHINCHUNK(cWorld, cFurnaceEntity, ForEachFurnaceInChunk, tolua_cWorld_ForEachFurnaceInChunk);
+ /* Push return value on stack */
+ tolua_pushboolean(tolua_S, bRetVal );
+ return 1;
+}
@@ -786,12 +806,7 @@ static int tolua_cPlugin_NewLua_AddWebTab(lua_State * tolua_S)
}
else
{
- if( tolua_err.type == 0 )
- {
- tolua_err.type = "function";
- }
- tolua_error(tolua_S,"#ferror in function 'AddWebTab'.",&tolua_err);
- return 0;
+ return tolua_do_error(tolua_S, "#ferror calling function '#funcname#'", &tolua_err);
}
if( Reference != LUA_REFNIL )
@@ -1020,20 +1035,20 @@ void ManualBindings::Bind( lua_State* tolua_S )
tolua_function(tolua_S, "Log", tolua_LOG); // Deprecated
tolua_beginmodule(tolua_S, "cRoot");
- tolua_function(tolua_S, "ForEachWorld", tolua_cRoot_ForEachWorld);
- tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_cRoot_FindAndDoWithPlayer);
- tolua_function(tolua_S, "ForEachPlayer", tolua_cRoot_ForEachPlayer);
+ tolua_function(tolua_S, "ForEachWorld", tolua_ForEach<cRoot, cWorld, &cRoot::ForEachWorld>);
+ tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith <cRoot, cPlayer, &cRoot::FindAndDoWithPlayer>);
+ tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach<cRoot, cPlayer, &cRoot::ForEachPlayer>);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cWorld");
- tolua_function(tolua_S, "ForEachPlayer", tolua_cWorld_ForEachPlayer);
- tolua_function(tolua_S, "ForEachEntity", tolua_cWorld_ForEachEntity);
- tolua_function(tolua_S, "ForEachEntityInChunk", tolua_cWorld_ForEachEntityInChunk);
- tolua_function(tolua_S, "ForEachChestInChunk", tolua_cWorld_ForEachChestInChunk);
- 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_function(tolua_S, "ForEachPlayer", tolua_ForEach<cWorld, cPlayer, &cWorld::ForEachPlayer>);
+ tolua_function(tolua_S, "ForEachEntity", tolua_ForEach<cWorld, cEntity, &cWorld::ForEachEntity>);
+ tolua_function(tolua_S, "ForEachEntityInChunk", tolua_ForEachInChunk<cWorld, cEntity, &cWorld::ForEachEntityInChunk>);
+ tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk<cWorld, cChestEntity, &cWorld::ForEachChestInChunk>);
+ tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_ForEachInChunk<cWorld, cFurnaceEntity, &cWorld::ForEachFurnaceInChunk>);
+ tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith<cWorld, cPlayer, &cWorld::DoWithPlayer>);
+ tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith<cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>);
+ tolua_function(tolua_S, "DoWithChestAt", tolua_DoWithXYZ<cWorld, cChestEntity, &cWorld::DoWithChestAt>);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPlugin");
diff --git a/source/World.h b/source/World.h
index e30fa7981..61817d18a 100644
--- a/source/World.h
+++ b/source/World.h
@@ -60,6 +60,11 @@ class cWorld // tolua_export
public:
// tolua_begin
+
+ static const char * GetClassStatic(void)
+ {
+ return "cWorld";
+ }
/// Return time in seconds
inline static float GetTime(void)