[DEV] function call work

This commit is contained in:
Edouard DUPIN 2018-08-14 22:56:11 +02:00
parent 463538aca3
commit fd43a85688
2 changed files with 102 additions and 25 deletions

View File

@ -60,14 +60,19 @@ namespace luaWrapper {
template<typename LUAW_TYPE> LUAW_TYPE to(lua_State* _luaState, int _index); template<typename LUAW_TYPE> LUAW_TYPE to(lua_State* _luaState, int _index);
template<typename LUAW_TYPE> void push(lua_State* _luaState, const LUAW_TYPE& _value); template<typename LUAW_TYPE> void push(lua_State* _luaState, const LUAW_TYPE& _value);
} }
template<class LUAW_ARG, class ... LUAW_ARGS> // end the recursive template...
void setCallParameters(lua_State* _luaState) { inline void setCallParameters(lua_State* _luaState) {
// nothing to do... // nothing to do...
} }
template<class ... LUAW_ARGS>
void setCallParameters(lua_State* _luaState, const char* _value, LUAW_ARGS&&... _args) {
luaWrapper::utils::push<const char*>(_luaState, _value);
setCallParameters(_luaState, etk::forward<LUAW_ARGS>(_args)...);
}
template<class LUAW_ARG, class ... LUAW_ARGS> template<class LUAW_ARG, class ... LUAW_ARGS>
void setCallParameters(lua_State* _luaState, LUAW_ARG&& _value, LUAW_ARGS&&... _args) { void setCallParameters(lua_State* _luaState, LUAW_ARG&& _value, LUAW_ARGS&&... _args) {
luaWrapper::utils::push<LUAW_ARG>(_luaState, _value); luaWrapper::utils::push<LUAW_ARG>(_luaState, _value);
setCallParameters(_luaState, _args...); setCallParameters(_luaState, etk::forward<LUAW_ARGS>(_args)...);
} }
/** /**
* @brief main interface of Lua engine. * @brief main interface of Lua engine.
@ -102,28 +107,44 @@ namespace luaWrapper {
lua_State* getState() { lua_State* getState() {
return m_luaState; return m_luaState;
} }
template<class LUAW_RETURN_TYPE, class ... LUAW_ARGS> private:
LUAW_RETURN_TYPE call(const char* _functionName, LUAW_ARGS&&... _args) { template<class ... LUAW_ARGS>
LUAW_RETURN_TYPE returnValue; void callGeneric(int32_t _numberReturn, const char* _functionName, LUAW_ARGS&&... _args) {
/* push functions and arguments */ /* push functions and arguments */
lua_getglobal(m_luaState, _functionName); /* function to be called */ lua_getglobal(m_luaState, _functionName); /* function to be called */
setCallParameters(m_luaState, _args ...); setCallParameters(m_luaState, etk::forward<LUAW_ARGS>(_args)...);
/* do the call (n arguments, 1 result) */ /* do the call (n arguments, 1 result) */
if (lua_pcall(m_luaState, int32_t(sizeof...(LUAW_ARGS)), 1, 0) != 0) { if (lua_pcall(m_luaState, int32_t(sizeof...(LUAW_ARGS)), _numberReturn, 0) != 0) {
ETK_THROW_EXCEPTION(etk::exception::RuntimeError(etk::String("error running function `") + _functionName +": " + lua_tostring(m_luaState, -1))); ETK_THROW_EXCEPTION(etk::exception::RuntimeError(etk::String("error running function `") + _functionName +": " + lua_tostring(m_luaState, -1)));
} }
/* retrieve result */ }
if (!lua_isnumber(m_luaState, -1)) { public:
ETK_THROW_EXCEPTION(etk::exception::RuntimeError(etk::String("function `") + _functionName +"`: must return a number")); /**
} * Call a lua function with some generic parameters (with return value).
returnValue = lua_tonumber(m_luaState, -1); * @param[in] _functionName Funtion to call.
lua_pop(m_luaState, 1); /* pop returned value */ * @param[in] _args... Multiple argument (what you want).
* @return The specified type.
*/
template<class LUAW_RETURN_TYPE, class ... LUAW_ARGS>
LUAW_RETURN_TYPE call(const char* _functionName, LUAW_ARGS&&... _args) {
callGeneric(1, _functionName, etk::forward<LUAW_ARGS>(_args)...);
// retrieve result
LUAW_RETURN_TYPE returnValue = luaWrapper::utils::check<LUAW_RETURN_TYPE>(m_luaState, -1);
// pop returned value
lua_pop(m_luaState, 1);
return returnValue; return returnValue;
} }
/**
* Call a lua function with some generic parameters (WITHOUT return value).
* @param[in] _functionName Funtion to call.
* @param[in] _args... Multiple argument (what you want).
*/
template<class ... LUAW_ARGS>
void callVoid(const char* _functionName, LUAW_ARGS&&... _args) {
callGeneric(0, _functionName, etk::forward<LUAW_ARGS>(_args)...);
}
}; };
/** /**
* A simple utility function to adjust a given index * A simple utility function to adjust a given index
* Useful for when a parameter index needs to be adjusted * Useful for when a parameter index needs to be adjusted

View File

@ -8,18 +8,74 @@
#include <etest/etest.hpp> #include <etest/etest.hpp>
static etk::String refOutputBoolean1("{\n\t\"tmpElement\": true\n}\n"); TEST(TestCCallLuaFunctionn, basicCallReturnDouble) {
TEST(TestCCallLuaFunctionn, basicCall) {
luaWrapper::Lua lua; luaWrapper::Lua lua;
lua.executeString(R"#( lua.executeString(R"#(
function MyFunctionName(x, y) function MyFunctionName(x, y)
return x + y*2 return x + y*2
end end
)#"); )#");
double ret = lua.call<float>("MyFunctionName", 43.9, 143.6);
float ret = lua.call<float>("MyFunctionName", 43.9f, 43.6f); EXPECT_EQ(ret, float(43.9 + 143.6 * 2.0));
}
EXPECT_EQ(ret, 43.9f + 43.6f * 2.0f);
TEST(TestCCallLuaFunctionn, basicCallReturnFloat) {
} luaWrapper::Lua lua;
lua.executeString(R"#(
function MyFunctionName(x, y)
return x + y*2
end
)#");
float ret = lua.call<float>("MyFunctionName", 43.9f, 143.6f);
EXPECT_EQ(ret, 43.9f + 143.6f * 2.0f);
}
TEST(TestCCallLuaFunctionn, basicCallReturnInt) {
luaWrapper::Lua lua;
lua.executeString(R"#(
function MyFunctionName(x, y)
return x + y*2
end
)#");
int ret = lua.call<int>("MyFunctionName", 43, 76);
EXPECT_EQ(ret, 43 + 76 * 2);
}
TEST(TestCCallLuaFunctionn, basicCallReturnBool) {
luaWrapper::Lua lua;
lua.executeString(R"#(
function MyFunctionName(x, y)
return x or y
end
)#");
bool ret = lua.call<bool>("MyFunctionName", true, false);
EXPECT_EQ(ret, true || false);
ret = lua.call<bool>("MyFunctionName", false, false);
EXPECT_EQ(ret, false || false);
ret = lua.call<bool>("MyFunctionName", true, true);
EXPECT_EQ(ret, true || true);
ret = lua.call<bool>("MyFunctionName", false, true);
EXPECT_EQ(ret, false || true);
}
TEST(TestCCallLuaFunctionn, basicCallReturnVoid) {
luaWrapper::Lua lua;
lua.executeString(R"#(
function MyFunctionName(x, y)
print("x or y")
end
)#");
lua.callVoid("MyFunctionName", true, "TRESDF");
}
TEST(TestCCallLuaFunctionn, basicCallNotExist) {
luaWrapper::Lua lua;
lua.executeString(R"#(
function MyFunctionName(x, y)
print("x or y")
end
)#");
lua.callVoid("MyFunctionNameThatDoesNotExit", true, "TRESDF");
}