diff options
author | faketruth <faketruth@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2012-02-15 14:16:42 +0100 |
---|---|---|
committer | faketruth <faketruth@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2012-02-15 14:16:42 +0100 |
commit | 5e1033c567064ffc4a81ac5a2f916db98e3a50ee (patch) | |
tree | 8409761d37e1bc62ea21faa4689dd85f6bcc5063 /source/ManualBindings.cpp | |
parent | Slight cleanup - removed old code, some additional comments on dangerous functions (diff) | |
download | cuberite-5e1033c567064ffc4a81ac5a2f916db98e3a50ee.tar cuberite-5e1033c567064ffc4a81ac5a2f916db98e3a50ee.tar.gz cuberite-5e1033c567064ffc4a81ac5a2f916db98e3a50ee.tar.bz2 cuberite-5e1033c567064ffc4a81ac5a2f916db98e3a50ee.tar.lz cuberite-5e1033c567064ffc4a81ac5a2f916db98e3a50ee.tar.xz cuberite-5e1033c567064ffc4a81ac5a2f916db98e3a50ee.tar.zst cuberite-5e1033c567064ffc4a81ac5a2f916db98e3a50ee.zip |
Diffstat (limited to '')
-rw-r--r-- | source/ManualBindings.cpp | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 840109a8f..ea6c18e29 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -103,6 +103,13 @@ static int tolua_LOGERROR(lua_State* tolua_S) 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 ) )
@@ -111,48 +118,69 @@ static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) 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;
+ }
+ }
- int Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
- if( Reference == LUA_REFNIL )
+ // 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");
+ 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, Reference);
+ lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function reference
tolua_pushusertype( LuaState, a_Player, "cPlayer" );
-
- int s = lua_pcall( LuaState, 1, 1, 0);
+ 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 false;
+ return false; // Maybe we should return true?
}
if( lua_isboolean( LuaState, -1 ) )
{
return (tolua_toboolean( LuaState, -1, 0) > 0);
}
-
- LOGINFO("Stack size: %i", lua_gettop(LuaState) );
-
return false;
}
- public:
lua_State* LuaState;
- int Reference;
- } Callback;
-
- Callback.LuaState = tolua_S;
- Callback.Reference = Reference;
+ int FuncRef;
+ int TableRef;
+ } Callback( tolua_S, FuncRef, TableRef );
bool bRetVal = self->ForEachPlayer( &Callback );
- luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference );
+ // 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;
}
|