summaryrefslogtreecommitdiffstats
path: root/source/ManualBindings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/ManualBindings.cpp')
-rw-r--r--source/ManualBindings.cpp252
1 files changed, 86 insertions, 166 deletions
diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp
index 8349f52f0..383f792b2 100644
--- a/source/ManualBindings.cpp
+++ b/source/ManualBindings.cpp
@@ -102,177 +102,97 @@ 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;
+#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 (!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 cLuaPlayerCallback : public cItemCallback<ITEM> \
+ { \
+ 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(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; \
}
-
-static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S)
-{
- int NumArgs = lua_gettop( tolua_S )-1; // This includes 'self'
- if( NumArgs != 1 && NumArgs != 2)
- {
- LOGWARN("Error in function call 'ForEachPlayer': Requires 1 or 2 arguments, got %i", NumArgs );
- return 0;
- }
-
- cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
-
- if( !lua_isfunction( tolua_S, 2 ) )
- {
- LOGWARN("Error in function call 'ForEachPlayer': 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 'ForEachPlayer': 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 'ForEachPlayer': Could not get function reference of parameter #1");
- return 0;
- }
-
- class cLuaPlayerCallback : public cPlayerListCallback
- {
- 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(cPlayer * a_Player) override
- {
- lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference
- tolua_pushusertype( LuaState, a_Player, "cPlayer" );
- 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->ForEachPlayer( 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 the ForEach enumerators:
+DEFINE_LUA_FOREACH(cWorld,cPlayer,ForEachPlayer, tolua_cWorld_ForEachPlayer);
+DEFINE_LUA_FOREACH(cRoot, cWorld, ForEachWorld, tolua_cRoot_ForEachWorld);