1
0

Rewritten ForEach using #define-s, new ones can be added as a simple one-liner

git-svn-id: http://mc-server.googlecode.com/svn/trunk@618 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-06-15 21:31:06 +00:00
parent ceeb3d4c54
commit 7d4abe001e
4 changed files with 90 additions and 168 deletions

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 06/14/12 21:17:55.
** Generated automatically by tolua++-1.0.92 on 06/15/12 23:23:53.
*/
#ifndef __cplusplus

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 06/14/12 21:17:55.
** Generated automatically by tolua++-1.0.92 on 06/15/12 23:23:53.
*/
/* Exported function */

View File

@ -43,6 +43,7 @@ public:
{
m_Items[a_Idx] = cItem(a_ItemType, a_ItemCount, a_ItemHealth);
}
protected:
cItems & m_Items;
} ;
@ -50,3 +51,4 @@ protected:

View File

@ -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);