diff options
Diffstat (limited to '')
-rw-r--r-- | src/LuaState.h | 817 |
1 files changed, 817 insertions, 0 deletions
diff --git a/src/LuaState.h b/src/LuaState.h new file mode 100644 index 000000000..5e7f3d180 --- /dev/null +++ b/src/LuaState.h @@ -0,0 +1,817 @@ + +// LuaState.h + +// Declares the cLuaState class representing the wrapper over lua_State *, provides associated helper functions + +/* +The contained lua_State can be either owned or attached. +Owned lua_State is created by calling Create() and the cLuaState automatically closes the state +Or, lua_State can be attached by calling Attach(), the cLuaState doesn't close such a state +Attaching a state will automatically close an owned state. + +Calling a Lua function is done by pushing the function, either by PushFunction() or PushFunctionFromRegistry(), +then pushing the arguments (PushString(), PushNumber(), PushUserData() etc.) and finally +executing CallFunction(). cLuaState automatically keeps track of the number of arguments and the name of the +function (for logging purposes), which makes the call less error-prone. + +Reference management is provided by the cLuaState::cRef class. This is used when you need to hold a reference to +any Lua object across several function calls; usually this is used for callbacks. The class is RAII-like, with +automatic resource management. +*/ + + + + +#pragma once + +extern "C" +{ + #include "lua/src/lauxlib.h" +} + + + + + +class cWorld; +class cPlayer; +class cEntity; +class cMonster; +class cItem; +class cItems; +class cClientHandle; +class cPickup; +class cChunkDesc; +class cCraftingGrid; +class cCraftingRecipe; +struct TakeDamageInfo; +class cWindow; +class cPluginLua; +struct HTTPRequest; +class cWebAdmin; +struct HTTPTemplateRequest; +class cTNTEntity; +class cCreeper; +class Vector3i; +class cHopperEntity; +class cBlockEntity; + + + + + +/// Encapsulates a Lua state and provides some syntactic sugar for common operations +class cLuaState +{ +public: + + /// Used for storing references to object in the global registry + class cRef + { + public: + /// Creates a reference in the specified LuaState for object at the specified StackPos + cRef(cLuaState & a_LuaState, int a_StackPos); + ~cRef(); + + /// Returns true if the reference is valid + bool IsValid(void) const {return (m_Ref != LUA_REFNIL); } + + /// Allows to use this class wherever an int (i. e. ref) is to be used + operator int(void) const { return m_Ref; } + + protected: + cLuaState & m_LuaState; + int m_Ref; + } ; + + + /// A dummy class that's used only to delimit function args from return values for cLuaState::Call() + class cRet + { + } ; + + static const cRet Return; // Use this constant to delimit function args from return values for cLuaState::Call() + + + /** Creates a new instance. The LuaState is not initialized. + a_SubsystemName is used for reporting problems in the console, it is "plugin %s" for plugins, + or "LuaScript" for the cLuaScript template + */ + cLuaState(const AString & a_SubsystemName); + + /** Creates a new instance. The a_AttachState is attached. + Subsystem name is set to "<attached>". + */ + explicit cLuaState(lua_State * a_AttachState); + + ~cLuaState(); + + /// Allows this object to be used in the same way as a lua_State *, for example in the LuaLib functions + operator lua_State * (void) { return m_LuaState; } + + /// Creates the m_LuaState, if not closed already. This state will be automatically closed in the destructor + void Create(void); + + /// Closes the m_LuaState, if not closed already + void Close(void); + + /// Attaches the specified state. Operations will be carried out on this state, but it will not be closed in the destructor + void Attach(lua_State * a_State); + + /// Detaches a previously attached state. + void Detach(void); + + /// Returns true if the m_LuaState is valid + bool IsValid(void) const { return (m_LuaState != NULL); } + + /** Loads the specified file + Returns false and logs a warning to the console if not successful (but the LuaState is kept open). + m_SubsystemName is displayed in the warning log message. + */ + bool LoadFile(const AString & a_FileName); + + /// Returns true if a_FunctionName is a valid Lua function that can be called + bool HasFunction(const char * a_FunctionName); + + /** Pushes the function of the specified name onto the stack. + Returns true if successful. Logs a warning on failure (incl. m_SubsystemName) + */ + bool PushFunction(const char * a_FunctionName); + + /** Pushes a function that has been saved into the global registry, identified by a_FnRef. + Returns true if successful. Logs a warning on failure + */ + bool PushFunction(int a_FnRef); + + /** Pushes a function that is stored in a table ref. + Returns true if successful, false on failure. Doesn't log failure. + */ + bool PushFunctionFromRefTable(cRef & a_TableRef, const char * a_FnName); + + /// Pushes a usertype of the specified class type onto the stack + void PushUserType(void * a_Object, const char * a_Type); + + // Push a value onto the stack + void Push(const AString & a_String); + void Push(const AStringVector & a_Vector); + void Push(int a_Value); + void Push(double a_Value); + void Push(const char * a_Value); + void Push(bool a_Value); + void Push(cWorld * a_World); + void Push(cPlayer * a_Player); + void Push(const cPlayer * a_Player); + void Push(cEntity * a_Entity); + void Push(cMonster * a_Monster); + void Push(cItem * a_Item); + void Push(cItems * a_Items); + void Push(cClientHandle * a_ClientHandle); + void Push(cPickup * a_Pickup); + void Push(cChunkDesc * a_ChunkDesc); + void Push(const cCraftingGrid * a_Grid); + void Push(const cCraftingRecipe * a_Recipe); + void Push(TakeDamageInfo * a_TDI); + void Push(cWindow * a_Window); + void Push(cPluginLua * a_Plugin); + void Push(const HTTPRequest * a_Request); + void Push(cWebAdmin * a_WebAdmin); + void Push(const HTTPTemplateRequest * a_Request); + void Push(cTNTEntity * a_TNTEntity); + void Push(cCreeper * a_Creeper); + void Push(Vector3i * a_Vector); + void Push(void * a_Ptr); + void Push(cHopperEntity * a_Hopper); + void Push(cBlockEntity * a_BlockEntity); + + /// Call any 0-param 0-return Lua function in a single line: + template <typename FnT> + bool Call(FnT a_FnName) + { + if (!PushFunction(a_FnName)) + { + return false; + } + return CallFunction(0); + } + + /// Call any 1-param 0-return Lua function in a single line: + template< + typename FnT, + typename ArgT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + return CallFunction(0); + } + + /// Call any 2-param 0-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + return CallFunction(0); + } + + /// Call any 1-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 2-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 3-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 4-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 5-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 6-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, + typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 7-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, + typename ArgT7, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + Push(a_Arg7); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 8-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, + typename ArgT7, typename ArgT8, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + Push(a_Arg7); + Push(a_Arg8); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 9-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, + typename ArgT7, typename ArgT8, typename ArgT9, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + Push(a_Arg7); + Push(a_Arg8); + Push(a_Arg9); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 10-param 1-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, + typename ArgT7, typename ArgT8, typename ArgT9, typename ArgT10, typename RetT1 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, ArgT10 a_Arg10, const cRet & a_Mark, RetT1 & a_Ret1) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + Push(a_Arg7); + Push(a_Arg8); + Push(a_Arg9); + Push(a_Arg10); + if (!CallFunction(1)) + { + return false; + } + GetReturn(-1, a_Ret1); + lua_pop(m_LuaState, 1); + return true; + } + + /// Call any 1-param 2-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename RetT1, typename RetT2 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + if (!CallFunction(2)) + { + return false; + } + GetReturn(-2, a_Ret1); + GetReturn(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; + } + + /// Call any 2-param 2-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename RetT1, typename RetT2 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + if (!CallFunction(2)) + { + return false; + } + GetReturn(-2, a_Ret1); + GetReturn(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; + } + + /// Call any 3-param 2-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, + typename RetT1, typename RetT2 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + if (!CallFunction(2)) + { + return false; + } + GetReturn(-2, a_Ret1); + GetReturn(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; + } + + /// Call any 4-param 2-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, + typename RetT1, typename RetT2 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + if (!CallFunction(2)) + { + return false; + } + GetReturn(-2, a_Ret1); + GetReturn(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; + } + + /// Call any 5-param 2-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, + typename RetT1, typename RetT2 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + if (!CallFunction(2)) + { + return false; + } + GetReturn(-2, a_Ret1); + GetReturn(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; + } + + /// Call any 6-param 2-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, + typename ArgT6, + typename RetT1, typename RetT2 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + if (!CallFunction(2)) + { + return false; + } + GetReturn(-2, a_Ret1); + GetReturn(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; + } + + /// Call any 7-param 2-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, + typename ArgT6, typename ArgT7, + typename RetT1, typename RetT2 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + Push(a_Arg7); + if (!CallFunction(2)) + { + return false; + } + GetReturn(-2, a_Ret1); + GetReturn(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; + } + + /// Call any 7-param 3-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, + typename ArgT6, typename ArgT7, + typename RetT1, typename RetT2, typename RetT3 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + Push(a_Arg7); + if (!CallFunction(3)) + { + return false; + } + GetReturn(-3, a_Ret1); + GetReturn(-2, a_Ret2); + GetReturn(-1, a_Ret3); + lua_pop(m_LuaState, 3); + return true; + } + + /// Call any 8-param 3-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, + typename ArgT6, typename ArgT7, typename ArgT8, + typename RetT1, typename RetT2, typename RetT3 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + Push(a_Arg7); + Push(a_Arg8); + if (!CallFunction(3)) + { + return false; + } + GetReturn(-3, a_Ret1); + GetReturn(-2, a_Ret2); + GetReturn(-1, a_Ret3); + lua_pop(m_LuaState, 3); + return true; + } + + /// Call any 9-param 5-return Lua function in a single line: + template< + typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, + typename ArgT6, typename ArgT7, typename ArgT8, typename ArgT9, + typename RetT1, typename RetT2, typename RetT3, typename RetT4, typename RetT5 + > + bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3, RetT4 & a_Ret4, RetT5 & a_Ret5) + { + if (!PushFunction(a_FnName)) + { + return false; + } + Push(a_Arg1); + Push(a_Arg2); + Push(a_Arg3); + Push(a_Arg4); + Push(a_Arg5); + Push(a_Arg6); + Push(a_Arg7); + Push(a_Arg8); + Push(a_Arg9); + if (!CallFunction(5)) + { + return false; + } + GetReturn(-5, a_Ret1); + GetReturn(-4, a_Ret2); + GetReturn(-3, a_Ret3); + GetReturn(-2, a_Ret4); + GetReturn(-1, a_Ret5); + lua_pop(m_LuaState, 5); + return true; + } + + + /// Retrieve value returned at a_StackPos, if it is a valid bool. If not, a_ReturnedVal is unchanged + void GetReturn(int a_StackPos, bool & a_ReturnedVal); + + /// Retrieve value returned at a_StackPos, if it is a valid string. If not, a_ReturnedVal is unchanged + void GetReturn(int a_StackPos, AString & a_ReturnedVal); + + /// Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged + void GetReturn(int a_StackPos, int & a_ReturnedVal); + + /// Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged + void GetReturn(int a_StackPos, double & a_ReturnedVal); + + /** + Calls the function that has been pushed onto the stack by PushFunction(), + with arguments pushed by PushXXX(). + Returns true if successful, logs a warning on failure. + */ + bool CallFunction(int a_NumReturnValues); + + /// Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions + bool CheckParamUserTable(int a_StartParam, const char * a_UserTable, int a_EndParam = -1); + + /// Returns true if the specified parameters on the stack are of the specified usertype; also logs warning if not. Used for regular functions + bool CheckParamUserType(int a_StartParam, const char * a_UserType, int a_EndParam = -1); + + /// Returns true if the specified parameters on the stack are tables; also logs warning if not + bool CheckParamTable(int a_StartParam, int a_EndParam = -1); + + /// Returns true if the specified parameters on the stack are numbers; also logs warning if not + bool CheckParamNumber(int a_StartParam, int a_EndParam = -1); + + /// Returns true if the specified parameters on the stack are strings; also logs warning if not + bool CheckParamString(int a_StartParam, int a_EndParam = -1); + + /// Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) + bool CheckParamEnd(int a_Param); + + /// If the status is nonzero, prints the text on the top of Lua stack and returns true + bool ReportErrors(int status); + + /// If the status is nonzero, prints the text on the top of Lua stack and returns true + static bool ReportErrors(lua_State * a_LuaState, int status); + + /// Logs all items in the current stack trace to the server console + void LogStackTrace(void); + + /// Returns the type of the item on the specified position in the stack + AString GetTypeText(int a_StackPos); + +protected: + lua_State * m_LuaState; + + /// If true, the state is owned by this object and will be auto-Closed. False => attached state + bool m_IsOwned; + + /** The subsystem name is used for reporting errors to the console, it is either "plugin %s" or "LuaScript" + whatever is given to the constructor + */ + AString m_SubsystemName; + + /// Name of the currently pushed function (for the Push / Call chain) + AString m_CurrentFunctionName; + + /// Number of arguments currently pushed (for the Push / Call chain) + int m_NumCurrentFunctionArgs; +} ; + + + + |