diff options
Diffstat (limited to 'src/Bindings/LuaState.h')
-rw-r--r-- | src/Bindings/LuaState.h | 88 |
1 files changed, 82 insertions, 6 deletions
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 094a200e0..c13e36188 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -164,7 +164,7 @@ public: void Detach(void); /** Returns true if the m_LuaState is valid */ - bool IsValid(void) const { return (m_LuaState != NULL); } + bool IsValid(void) const { return (m_LuaState != nullptr); } /** Adds the specified path to package.<a_PathVariable> */ void AddPackagePath(const AString & a_PathVariable, const AString & a_Path); @@ -240,10 +240,28 @@ public: /** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */ void GetStackValue(int a_StackPos, pWorld & a_Value); + /** Call the specified Lua function. + Returns true if call succeeded, false if there was an error. + A special param of cRet & signifies the end of param list and the start of return values. + Example call: Call(Fn, Param1, Param2, Param3, cLuaState::Return, Ret1, Ret2) */ + template <typename FnT, typename... Args> + bool Call(const FnT & a_Function, Args &&... args) + { + if (!PushFunction(a_Function)) + { + // Pushing the function failed + return false; + } + return PushCallPop(args...); + } - // Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script: - #include "LuaState_Call.inc" - + /** Retrieves a list of values from the Lua stack, starting at the specified index. */ + template <typename T, typename... Args> + inline void GetStackValues(int a_StartStackPos, T & a_Ret, Args &&... args) + { + GetStackValue(a_StartStackPos, a_Ret); + GetStackValues(a_StartStackPos + 1, args...); + } /** 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); @@ -304,12 +322,13 @@ public: void ToString(int a_StackPos, AString & a_String); /** Logs all the elements' types on the API stack, with an optional header for the listing. */ - void LogStack(const char * a_Header); + void LogStack(const char * a_Header = nullptr); /** Logs all the elements' types on the API stack, with an optional header for the listing. */ - static void LogStack(lua_State * a_LuaState, const char * a_Header = NULL); + static void LogStack(lua_State * a_LuaState, const char * a_Header = nullptr); protected: + lua_State * m_LuaState; /** If true, the state is owned by this object and will be auto-Closed. False => attached state */ @@ -327,6 +346,63 @@ protected: int m_NumCurrentFunctionArgs; + /** Variadic template terminator: Counting zero args returns zero. */ + int CountArgs(void) + { + return 0; + } + + /** Variadic template: Counting args means add one to the count of the rest. */ + template <typename T, typename... Args> + int CountArgs(T, Args... args) + { + return 1 + CountArgs(args...); + } + + /** Variadic template terminator: If there's nothing more to push / pop, just call the function. + Note that there are no return values either, because those are prefixed by a cRet value, so the arg list is never empty. */ + bool PushCallPop(void) + { + return CallFunction(0); + } + + /** Variadic template recursor: More params to push. Push them and recurse. */ + template <typename T, typename... Args> + inline bool PushCallPop(T a_Param, Args &&... args) + { + Push(a_Param); + return PushCallPop(args...); + } + + /** Variadic template terminator: If there's nothing more to push, but return values to collect, call the function and collect the returns. */ + template <typename... Args> + bool PushCallPop(cLuaState::cRet, Args &&... args) + { + // Calculate the number of return values (number of args left): + int NumReturns = CountArgs(args...); + + // Call the function: + if (!CallFunction(NumReturns)) + { + return false; + } + + // Collect the return values: + GetStackValues(-NumReturns, args...); + lua_pop(m_LuaState, NumReturns); + + // All successful: + return true; + } + + /** Variadic template terminator: If there are no more values to get, bail out. + This function is not available in the public API, because it's an error to request no values directly; only internal functions can do that. + If you get a compile error saying this function is not accessible, check your calling code, you aren't reading any stack values. */ + void GetStackValues(int a_StartingStackPos) + { + // Do nothing + } + /** Pushes the function of the specified name onto the stack. Returns true if successful. Logs a warning on failure (incl. m_SubsystemName) */ |