summaryrefslogtreecommitdiffstats
path: root/src/Bindings/LuaState.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Bindings/LuaState.h')
-rw-r--r--src/Bindings/LuaState.h88
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)
*/