[DEV] basic call interface

This commit is contained in:
Edouard DUPIN 2018-08-13 23:50:20 +02:00
parent fb2e791f08
commit 463538aca3
8 changed files with 354 additions and 256 deletions

View File

@ -42,6 +42,7 @@
#include <etk/typeInfo.hpp>
#include <etk/Allocator.hpp>
#include <etk/os/FSNode.hpp>
#include <etk/Exception.hpp>
#include <luaWrapper/debug.hpp>
@ -54,6 +55,20 @@
#define LUAW_WRAPPER_KEY "LuaWrapper"
namespace luaWrapper {
namespace utils {
template<typename LUAW_TYPE> LUAW_TYPE check(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<class LUAW_ARG, class ... LUAW_ARGS>
void setCallParameters(lua_State* _luaState) {
// nothing to do...
}
template<class LUAW_ARG, class ... LUAW_ARGS>
void setCallParameters(lua_State* _luaState, LUAW_ARG&& _value, LUAW_ARGS&&... _args) {
luaWrapper::utils::push<LUAW_ARG>(_luaState, _value);
setCallParameters(_luaState, _args...);
}
/**
* @brief main interface of Lua engine.
*/
@ -87,6 +102,26 @@ namespace luaWrapper {
lua_State* getState() {
return m_luaState;
}
template<class LUAW_RETURN_TYPE, class ... LUAW_ARGS>
LUAW_RETURN_TYPE call(const char* _functionName, LUAW_ARGS&&... _args) {
LUAW_RETURN_TYPE returnValue;
/* push functions and arguments */
lua_getglobal(m_luaState, _functionName); /* function to be called */
setCallParameters(m_luaState, _args ...);
/* do the call (n arguments, 1 result) */
if (lua_pcall(m_luaState, int32_t(sizeof...(LUAW_ARGS)), 1, 0) != 0) {
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)) {
ETK_THROW_EXCEPTION(etk::exception::RuntimeError(etk::String("function `") + _functionName +"`: must return a number"));
}
returnValue = lua_tonumber(m_luaState, -1);
lua_pop(m_luaState, 1); /* pop returned value */
return returnValue;
}
};
/**
@ -514,13 +549,6 @@ namespace luaWrapper {
lua_pop( _luaState, 1 );
return 0;
}
/*
static int gc( lua_State* const L )
{
return 0;
}
*/
/**
* Thakes two tables and registers them with Lua to the table on the top of the
* stack.
@ -529,21 +557,12 @@ namespace luaWrapper {
*/
inline void registerfuncs(lua_State* _luaState, const luaL_Reg _defaulttable[], const luaL_Reg _table[]) {
// ... T
#if LUA_VERSION_NUM == 502
if (_defaulttable) {
luaL_setfuncs(_luaState, _defaulttable, 0); // ... T
}
if (_table) {
luaL_setfuncs(_luaState, _table, 0); // ... T
}
#else
if (_defaulttable) {
luaL_register(_luaState, NULL, _defaulttable); // ... T
}
if (_table) {
luaL_register(_luaState, NULL, _table); // ... T
}
#endif
}
/**
@ -668,36 +687,36 @@ namespace luaWrapper {
}
template <typename LUAW_TYPE>
void registerElement(lua_State* _luaState,
void registerElement(Lua& _lua,
const char* _classname,
const luaL_Reg* _table,
const luaL_Reg* _metatable,
ememory::SharedPtr<LUAW_TYPE> (*_allocator)(lua_State*),
void (*_identifier)(lua_State*, ememory::SharedPtr<LUAW_TYPE>)) {
setfuncs(_luaState, _classname, _table, _metatable, _allocator, _identifier); // ... T
lua_pushvalue(_luaState, -1); // ... LUAW_TYPE LUAW_TYPE
lua_setglobal(_luaState, _classname); // ... LUAW_TYPE
setfuncs(_lua.getState(), _classname, _table, _metatable, _allocator, _identifier); // ... T
lua_pushvalue(_lua.getState(), -1); // ... LUAW_TYPE LUAW_TYPE
lua_setglobal(_lua.getState(), _classname); // ... LUAW_TYPE
}
template <typename LUAW_TYPE>
void registerElement(lua_State* _luaState,
void registerElement(Lua& _lua,
const char* _classname,
const luaL_Reg* _table,
const luaL_Reg* _metatable,
ememory::SharedPtr<LUAW_TYPE> (*_allocator)(lua_State*)) {
setfuncs(_luaState, _classname, _table, _metatable, _allocator, defaultidentifier<LUAW_TYPE>);
lua_pushvalue(_luaState, -1); // ... LUAW_TYPE LUAW_TYPE
lua_setglobal(_luaState, _classname); // ... LUAW_TYPE
setfuncs(_lua.getState(), _classname, _table, _metatable, _allocator, defaultidentifier<LUAW_TYPE>);
lua_pushvalue(_lua.getState(), -1); // ... LUAW_TYPE LUAW_TYPE
lua_setglobal(_lua.getState(), _classname); // ... LUAW_TYPE
}
template <typename LUAW_TYPE>
void registerElement(lua_State* _luaState,
void registerElement(Lua& _lua,
const char* _classname,
const luaL_Reg* _table,
const luaL_Reg* _metatable) {
setfuncs(_luaState, _classname, _table, _metatable, defaultallocator<LUAW_TYPE>, defaultidentifier<LUAW_TYPE>); // ... T
lua_pushvalue(_luaState, -1); // ... T T
lua_setglobal(_luaState, _classname); // ... T
setfuncs(_lua.getState(), _classname, _table, _metatable, defaultallocator<LUAW_TYPE>, defaultidentifier<LUAW_TYPE>); // ... T
lua_pushvalue(_lua.getState(), -1); // ... T T
lua_setglobal(_lua.getState(), _classname); // ... T
}
/**

View File

@ -29,104 +29,104 @@ namespace luaWrapper {
* This example uses etk::String, but if you have other custom string types it
* should be easy to write versions of those functions too
*/
template<> etk::String check<etk::String>(lua_State* _L, int _index) {
return etk::String(luaL_checkstring(_L, _index));
template<> etk::String check<etk::String>(lua_State* _luaState, int _index) {
return etk::String(luaL_checkstring(_luaState, _index));
}
template<> etk::String to<etk::String>(lua_State* _L, int _index) {
return etk::String(lua_tostring(_L, _index));
template<> etk::String to<etk::String>(lua_State* _luaState, int _index) {
return etk::String(lua_tostring(_luaState, _index));
}
template<> void push<etk::String>(lua_State* _L, const etk::String& _val) {
lua_pushstring(_L, _val.c_str());
template<> void push<etk::String>(lua_State* _luaState, const etk::String& _val) {
lua_pushstring(_luaState, _val.c_str());
}
template<> bool check<bool>(lua_State* _L, int _index) {
return lua_toboolean(_L, _index) != 0;
template<> bool check<bool>(lua_State* _luaState, int _index) {
return lua_toboolean(_luaState, _index) != 0;
}
template<> bool to<bool>(lua_State* _L, int _index) {
return lua_toboolean(_L, _index) != 0;
template<> bool to<bool>(lua_State* _luaState, int _index) {
return lua_toboolean(_luaState, _index) != 0;
}
template<> void push<bool>(lua_State* _L, const bool& _value) {
lua_pushboolean(_L, _value);
template<> void push<bool>(lua_State* _luaState, const bool& _value) {
lua_pushboolean(_luaState, _value);
}
template<> const char* check<const char*>(lua_State* _L, int _index) {
return luaL_checkstring(_L, _index);
template<> const char* check<const char*>(lua_State* _luaState, int _index) {
return luaL_checkstring(_luaState, _index);
}
template<> const char* to<const char*>(lua_State* _L, int _index) {
return lua_tostring(_L, _index);
template<> const char* to<const char*>(lua_State* _luaState, int _index) {
return lua_tostring(_luaState, _index);
}
template<> void push<const char*>(lua_State* _L, const char* const& _value) {
lua_pushstring(_L, _value);
template<> void push<const char*>(lua_State* _luaState, const char* const& _value) {
lua_pushstring(_luaState, _value);
}
template<> const char* const check<const char* const>(lua_State* _L, int _index) {
return luaL_checkstring(_L, _index);
template<> const char* const check<const char* const>(lua_State* _luaState, int _index) {
return luaL_checkstring(_luaState, _index);
}
template<> const char* const to<const char* const>(lua_State* _L, int _index) {
return lua_tostring(_L, _index);
template<> const char* const to<const char* const>(lua_State* _luaState, int _index) {
return lua_tostring(_luaState, _index);
}
template<> void push<const char* const>(lua_State* _L, const char* const& _value) {
lua_pushstring(_L, _value);
template<> void push<const char* const>(lua_State* _luaState, const char* const& _value) {
lua_pushstring(_luaState, _value);
}
template<> unsigned int check<unsigned int>(lua_State* _L, int _index) {
return static_cast<unsigned int>(luaL_checkinteger(_L, _index));
template<> unsigned int check<unsigned int>(lua_State* _luaState, int _index) {
return static_cast<unsigned int>(luaL_checkinteger(_luaState, _index));
}
template<> unsigned int to<unsigned int>(lua_State* _L, int _index) {
return static_cast<unsigned int>(lua_tointeger(_L, _index));
template<> unsigned int to<unsigned int>(lua_State* _luaState, int _index) {
return static_cast<unsigned int>(lua_tointeger(_luaState, _index));
}
template<> void push<unsigned int>(lua_State* _L, const unsigned int& _value) {
lua_pushinteger(_L, _value);
template<> void push<unsigned int>(lua_State* _luaState, const unsigned int& _value) {
lua_pushinteger(_luaState, _value);
}
template<> int check<int>(lua_State* _L, int _index) {
return static_cast<int>(luaL_checkinteger(_L, _index));
template<> int check<int>(lua_State* _luaState, int _index) {
return static_cast<int>(luaL_checkinteger(_luaState, _index));
}
template<> int to<int>(lua_State* _L, int _index) {
return static_cast<int>(lua_tointeger(_L, _index));
template<> int to<int>(lua_State* _luaState, int _index) {
return static_cast<int>(lua_tointeger(_luaState, _index));
}
template<> void push<int>(lua_State* _L, const int& _value) {
lua_pushinteger(_L, _value);
template<> void push<int>(lua_State* _luaState, const int& _value) {
lua_pushinteger(_luaState, _value);
}
template<> unsigned char check<unsigned char>(lua_State* _L, int _index) {
return static_cast<unsigned char>(luaL_checkinteger(_L, _index));
template<> unsigned char check<unsigned char>(lua_State* _luaState, int _index) {
return static_cast<unsigned char>(luaL_checkinteger(_luaState, _index));
}
template<> unsigned char to<unsigned char>(lua_State* _L, int _index) {
return static_cast<unsigned char>(lua_tointeger(_L, _index));
template<> unsigned char to<unsigned char>(lua_State* _luaState, int _index) {
return static_cast<unsigned char>(lua_tointeger(_luaState, _index));
}
template<> void push<unsigned char>(lua_State* _L, const unsigned char& _value) {
lua_pushinteger(_L, _value);
template<> void push<unsigned char>(lua_State* _luaState, const unsigned char& _value) {
lua_pushinteger(_luaState, _value);
}
template<> char check<char>(lua_State* _L, int _index) {
return static_cast<char>(luaL_checkinteger(_L, _index));
template<> char check<char>(lua_State* _luaState, int _index) {
return static_cast<char>(luaL_checkinteger(_luaState, _index));
}
template<> char to<char>(lua_State* _L, int _index) {
return static_cast<char>(lua_tointeger(_L, _index));
template<> char to<char>(lua_State* _luaState, int _index) {
return static_cast<char>(lua_tointeger(_luaState, _index));
}
template<> void push<char>(lua_State* _L, const char& _value) {
lua_pushinteger(_L, _value);
template<> void push<char>(lua_State* _luaState, const char& _value) {
lua_pushinteger(_luaState, _value);
}
template<> float check<float>(lua_State* _L, int _index) {
return static_cast<float>(luaL_checknumber(_L, _index));
template<> float check<float>(lua_State* _luaState, int _index) {
return static_cast<float>(luaL_checknumber(_luaState, _index));
}
template<> float to<float>(lua_State* _L, int _index) {
return static_cast<float>(lua_tonumber(_L, _index));
template<> float to<float>(lua_State* _luaState, int _index) {
return static_cast<float>(lua_tonumber(_luaState, _index));
}
template<> void push<float>(lua_State* _L, const float& _value) {
lua_pushnumber(_L, _value);
template<> void push<float>(lua_State* _luaState, const float& _value) {
lua_pushnumber(_luaState, _value);
}
template<> double check<double>(lua_State* _L, int _index) {
return static_cast<double>(luaL_checknumber(_L, _index));
template<> double check<double>(lua_State* _luaState, int _index) {
return static_cast<double>(luaL_checknumber(_luaState, _index));
}
template<> double to<double>(lua_State* _L, int _index) {
return static_cast<double>(lua_tonumber(_L, _index));
template<> double to<double>(lua_State* _luaState, int _index) {
return static_cast<double>(lua_tonumber(_luaState, _index));
}
template<> void push<double>(lua_State* _L, const double& _value) {
lua_pushnumber(_L, _value);
template<> void push<double>(lua_State* _luaState, const double& _value) {
lua_pushnumber(_luaState, _value);
}
}
}

View File

@ -29,69 +29,57 @@ namespace luaWrapper {
/**
* @brief This template removes reference and const qualifier from the type
*/
template <typename T> struct remove_cr {
typedef typename std::remove_const<typename std::remove_reference<T>::type>::type type;
template <typename LUAW_TYPE> struct remove_cr {
typedef typename std::remove_const<typename std::remove_reference<LUAW_TYPE>::type>::type type;
};
/**
* A set of templated luaL_check and lua_push functions for use in the getters
* and setters below
*
* It is often useful to override luaWrapper::utils::check, luaWrapper::utils::to and/or luaWrapper::utils::push to
* operate on your own simple types rather than register your type with
* LuaWrapper, especially with small objects.
*/
template<typename U> U check(lua_State* _L, int _index);
template<typename U> U to(lua_State* _L, int _index);
template<typename U> void push(lua_State* _L, const U& _value);
/**
* This is slightly different than the previous three functions in that you
* shouldn't need to write your own version of it, since it uses check
* automatically.
*/
template<typename U> U opt(lua_State* _L, int _index, const U& _fallback = U()) {
if (lua_isnil(_L, _index)) {
template<typename U> U opt(lua_State* _luaState, int _index, const U& _fallback = U()) {
if (lua_isnil(_luaState, _index)) {
return _fallback;
} else {
return luaWrapper::utils::check<U>(_L, _index);
return luaWrapper::utils::check<U>(_luaState, _index);
}
}
/**
* These are just some functions I've always felt should exist
*/
template <typename U> inline U getfield(lua_State* _L, int _index, const char* _field) {
template <typename U> inline U getfield(lua_State* _luaState, int _index, const char* _field) {
static_assert(!LUAW_STD::is_same<U, const char*>::value,
"luaWrapper::utils::getfield is not safe to use on const char*'s. (The string will be popped from the stack.)");
lua_getfield(_L, _index, _field);
U val = luaWrapper::utils::to<U>(_L, -1);
lua_pop(_L, 1);
lua_getfield(_luaState, _index, _field);
U val = luaWrapper::utils::to<U>(_luaState, -1);
lua_pop(_luaState, 1);
return val;
}
template <typename U> inline U checkfield(lua_State* _L, int _index, const char* _field) {
template <typename U> inline U checkfield(lua_State* _luaState, int _index, const char* _field) {
static_assert(!LUAW_STD::is_same<U, const char*>::value,
"luaWrapper::utils::checkfield is not safe to use on const char*'s. (The string will be popped from the stack.)");
lua_getfield(_L, _index, _field);
U val = luaWrapper::utils::check<U>(_L, -1);
lua_pop(_L, 1);
lua_getfield(_luaState, _index, _field);
U val = luaWrapper::utils::check<U>(_luaState, -1);
lua_pop(_luaState, 1);
return val;
}
template <typename U> inline U optfield(lua_State* _L, int _index, const char* _field, const U& _fallback = U()) {
template <typename U> inline U optfield(lua_State* _luaState, int _index, const char* _field, const U& _fallback = U()) {
static_assert(!LUAW_STD::is_same<U, const char*>::value,
"luaWrapper::utils::getfield is not safe to use on const char*'s. (The string will be popped from the stack.)");
lua_getfield(_L, _index, _field);
U val = luaWrapper::utils::opt<U>(_L, -1, _fallback);
lua_pop(_L, 1);
lua_getfield(_luaState, _index, _field);
U val = luaWrapper::utils::opt<U>(_luaState, -1, _fallback);
lua_pop(_luaState, 1);
return val;
}
template <typename U> inline void setfield(lua_State* _L, int _index, const char* _field, U _val) {
luaWrapper::utils::push<U>(_L, _val);
lua_setfield(_L, luaWrapper::correctindex(_L, _index, 1), _field);
template <typename U> inline void setfield(lua_State* _luaState, int _index, const char* _field, U _val) {
luaWrapper::utils::push<U>(_luaState, _val);
lua_setfield(_luaState, luaWrapper::correctindex(_luaState, _index, 1), _field);
}
/** A set of trivial getter and setter templates. These templates are designed
@ -121,9 +109,9 @@ namespace luaWrapper {
* }
*
* Getters and setters must have one of the following signatures:
* void T::Setter(U _value);
* void T::Setter(U* _value);
* void T::Setter(const U& _value);
* void LUAW_TYPE::Setter(U _value);
* void LUAW_TYPE::Setter(U* _value);
* void LUAW_TYPE::Setter(const U& _value);
* U Getter() const;
* U* Getter() const;
*
@ -141,211 +129,211 @@ namespace luaWrapper {
* In a Lua script, you can now use foo:GetBar(), foo:SetBar() and foo:Bar()
*/
template <typename T, typename U, U T::*Member> int get(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
luaWrapper::utils::push<U>(_L, obj.get()->*Member);
template <typename LUAW_TYPE, typename U, U LUAW_TYPE::*Member> int get(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
luaWrapper::utils::push<U>(_luaState, obj.get()->*Member);
return 1;
}
template <typename T, typename U, U* T::*Member> int get(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
luaWrapper::push<U>(_L, obj.get()->*Member);
template <typename LUAW_TYPE, typename U, U* LUAW_TYPE::*Member> int get(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
luaWrapper::push<U>(_luaState, obj.get()->*Member);
return 1;
}
template <typename T, typename U, U (T::*Getter)() const> int get(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
luaWrapper::utils::push<U>(_L, (obj.get()->*Getter)());
template <typename LUAW_TYPE, typename U, U (LUAW_TYPE::*Getter)() const> int get(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
luaWrapper::utils::push<U>(_luaState, (obj.get()->*Getter)());
return 1;
}
template <typename T, typename U, const U& (T::*Getter)() const> int get(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
luaWrapper::utils::push<U>(_L, (obj.get()->*Getter)());
template <typename LUAW_TYPE, typename U, const U& (LUAW_TYPE::*Getter)() const> int get(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
luaWrapper::utils::push<U>(_luaState, (obj.get()->*Getter)());
return 1;
}
template <typename T, typename U, U* (T::*Getter)() const> int get(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
luaWrapper::push<U>(_L, (obj.get()->*Getter)());
template <typename LUAW_TYPE, typename U, U* (LUAW_TYPE::*Getter)() const> int get(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
luaWrapper::push<U>(_luaState, (obj.get()->*Getter)());
return 1;
}
template <typename T, typename U, U T::*Member> int set(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U LUAW_TYPE::*Member> int set(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if (obj != null) {
obj.get()->*Member = luaWrapper::utils::check<U>(_L, 2);
obj.get()->*Member = luaWrapper::utils::check<U>(_luaState, 2);
}
return 0;
}
template <typename T, typename U, U* T::*Member> int set(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U* LUAW_TYPE::*Member> int set(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if (obj != null) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
obj.get()->*Member = member.get();
}
return 0;
}
template <typename T, typename U, const U* T::*Member> int set(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, const U* LUAW_TYPE::*Member> int set(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if (obj != null) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
obj.get()->*Member = member.get();
}
return 0;
}
template <typename T, typename U, const U* T::*Member> int setAndRelease(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, const U* LUAW_TYPE::*Member> int setAndRelease(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if (obj != null) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
obj.get()->*Member = member.get();
if (member) {
luaWrapper::release<U>(_L, member);
luaWrapper::release<U>(_luaState, member);
}
}
return 0;
}
template <typename T, typename U, void (T::*Setter)(U)> int set(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, void (LUAW_TYPE::*Setter)(U)> int set(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if (obj != null) {
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_L, 2));
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_luaState, 2));
}
return 0;
}
template <typename T, typename U, void (T::*Setter)(const U&)> int set(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, void (LUAW_TYPE::*Setter)(const U&)> int set(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if (obj != null) {
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_L, 2));
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_luaState, 2));
}
return 0;
}
template <typename T, typename U, void (T::*Setter)(U*)> int set(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, void (LUAW_TYPE::*Setter)(U*)> int set(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if (obj != null) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
(obj.get()->*Setter)(member.get());
}
return 0;
}
template <typename T, typename U, void (T::*Setter)(U*)> int setAndRelease(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, void (LUAW_TYPE::*Setter)(U*)> int setAndRelease(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if (obj != null) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
(obj.get()->*Setter)(member);
if (member) {
luaWrapper::release<U>(_L, member);
luaWrapper::release<U>(_luaState, member);
}
}
return 0;
}
template <typename T, typename U, U T::*Member> int getSet(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U LUAW_TYPE::*Member> int getSet(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if ( obj != null
&& lua_gettop(_L) >= 2) {
obj.get()->*Member = luaWrapper::utils::check<U>(_L, 2);
&& lua_gettop(_luaState) >= 2) {
obj.get()->*Member = luaWrapper::utils::check<U>(_luaState, 2);
return 0;
} else {
luaWrapper::utils::push<U>(_L, obj.get()->*Member);
luaWrapper::utils::push<U>(_luaState, obj.get()->*Member);
return 1;
}
}
template <typename T, typename U, U* T::*Member> int getSet(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U* LUAW_TYPE::*Member> int getSet(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if ( obj != null
&& lua_gettop(_L) >= 2) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
&& lua_gettop(_luaState) >= 2) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
obj.get()->*Member = member.get();
return 0;
} else {
luaWrapper::push<U>(_L, obj.get()->*Member);
luaWrapper::push<U>(_luaState, obj.get()->*Member);
return 1;
}
}
template <typename T, typename U, U* T::*Member> int getSetAndRelease(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U* LUAW_TYPE::*Member> int getSetAndRelease(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if ( obj != null
&& lua_gettop(_L) >= 2) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
&& lua_gettop(_luaState) >= 2) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
obj.get()->*Member = member.get();
if (member)
luaWrapper::release<U>(_L, member);
luaWrapper::release<U>(_luaState, member);
return 0;
} else {
luaWrapper::push<U>(_L, obj.get()->*Member);
luaWrapper::push<U>(_luaState, obj.get()->*Member);
return 1;
}
}
template <typename T, typename U, U (T::*Getter)() const, void (T::*Setter)(U)> int getSet(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U (LUAW_TYPE::*Getter)() const, void (LUAW_TYPE::*Setter)(U)> int getSet(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if ( obj != null
&& lua_gettop(_L) >= 2) {
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_L, 2));
&& lua_gettop(_luaState) >= 2) {
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_luaState, 2));
return 0;
} else {
luaWrapper::utils::push<U>(_L, (obj.get()->*Getter)());
luaWrapper::utils::push<U>(_luaState, (obj.get()->*Getter)());
return 1;
}
}
template <typename T, typename U, U (T::*Getter)() const, void (T::*Setter)(const U&)> int getSet(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U (LUAW_TYPE::*Getter)() const, void (LUAW_TYPE::*Setter)(const U&)> int getSet(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if ( obj != null
&& lua_gettop(_L) >= 2) {
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_L, 2));
&& lua_gettop(_luaState) >= 2) {
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_luaState, 2));
return 0;
} else {
luaWrapper::utils::push<U>(_L, (obj.get()->*Getter)());
luaWrapper::utils::push<U>(_luaState, (obj.get()->*Getter)());
return 1;
}
}
template <typename T, typename U, const U& (T::*Getter)() const, void (T::*Setter)(const U&)> int getSet(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, const U& (LUAW_TYPE::*Getter)() const, void (LUAW_TYPE::*Setter)(const U&)> int getSet(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if ( obj != null
&& lua_gettop(_L) >= 2) {
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_L, 2));
&& lua_gettop(_luaState) >= 2) {
(obj.get()->*Setter)(luaWrapper::utils::check<U>(_luaState, 2));
return 0;
} else {
luaWrapper::utils::push<U>(_L, (obj.get()->*Getter)());
luaWrapper::utils::push<U>(_luaState, (obj.get()->*Getter)());
return 1;
}
}
template <typename T, typename U, U* (T::*Getter)() const, void (T::*Setter)(U*)> int getSet(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U* (LUAW_TYPE::*Getter)() const, void (LUAW_TYPE::*Setter)(U*)> int getSet(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if ( obj != null
&& lua_gettop(_L) >= 2) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
&& lua_gettop(_luaState) >= 2) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
(obj.get()->*Setter)(member.get());
return 0;
} else {
luaWrapper::push<U>(_L, (obj.get()->*Getter)());
luaWrapper::push<U>(_luaState, (obj.get()->*Getter)());
return 1;
}
}
template <typename T, typename U, U* (T::*Getter)() const, void (T::*Setter)(U*)> int getSetAndRelease(lua_State* _L) {
ememory::SharedPtr<T> obj = luaWrapper::check<T>(_L, 1);
template <typename LUAW_TYPE, typename U, U* (LUAW_TYPE::*Getter)() const, void (LUAW_TYPE::*Setter)(U*)> int getSetAndRelease(lua_State* _luaState) {
ememory::SharedPtr<LUAW_TYPE> obj = luaWrapper::check<LUAW_TYPE>(_luaState, 1);
if ( obj != null
&& lua_gettop(_L) >= 2) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_L, 2);
&& lua_gettop(_luaState) >= 2) {
ememory::SharedPtr<U> member = luaWrapper::opt<U>(_luaState, 2);
(obj.get()->*Setter)(member);
if (member)
luaWrapper::release<U>(_L, member);
luaWrapper::release<U>(_luaState, member);
return 0;
} else {
luaWrapper::push<U>(_L, (obj.get()->*Getter)());
luaWrapper::push<U>(_luaState, (obj.get()->*Getter)());
return 1;
}
}
@ -461,28 +449,28 @@ namespace luaWrapper {
struct MemberFuncWrapper;
template<class LUAW_TYPE, class ReturnType, class... Args, ReturnType(LUAW_TYPE::*MemberFunc)(Args...)>
struct MemberFuncWrapper<ReturnType (T::*)(Args...), MemberFunc> {
struct MemberFuncWrapper<ReturnType (LUAW_TYPE::*)(Args...), MemberFunc> {
public:
static int call(lua_State* _L) {
return callImpl(_L, makeIntRange<2,sizeof...(Args)>());
static int call(lua_State* _luaState) {
return callImpl(_luaState, makeIntRange<2,sizeof...(Args)>());
}
private:
template<int... indices> static int callImpl(lua_State* _L, IntPack<indices...>) {
luaWrapper::utils::push<ReturnType>(_L, ((*luaWrapper::check<LUAW_TYPE>(_L, 1)).*MemberFunc)(luaWrapper::utils::check<typename luaWrapper::utils::remove_cr<Args>::type>(_L, indices)...));
template<int... indices> static int callImpl(lua_State* _luaState, IntPack<indices...>) {
luaWrapper::utils::push<ReturnType>(_luaState, ((*luaWrapper::check<LUAW_TYPE>(_luaState, 1)).*MemberFunc)(luaWrapper::utils::check<typename luaWrapper::utils::remove_cr<Args>::type>(_luaState, indices)...));
return 1;
}
};
template<class LUAW_TYPE, class... Args, void(LUAW_TYPE::*MemberFunc)(Args...)>
struct MemberFuncWrapper<void(T::*)(Args...), MemberFunc> {
struct MemberFuncWrapper<void(LUAW_TYPE::*)(Args...), MemberFunc> {
public:
static int call(lua_State* _L) {
return callImpl(_L, luaWrapper::utils::makeIntRange<2, sizeof...(Args)>());
static int call(lua_State* _luaState) {
return callImpl(_luaState, luaWrapper::utils::makeIntRange<2, sizeof...(Args)>());
}
private:
template<int... indices>
static int callImpl(lua_State* _L, IntPack<indices...>) {
((*luaWrapper::check<T>(_L, 1)).*MemberFunc)(luaWrapper::utils::check<typename luaWrapper::utils::remove_cr<Args>::type>(_L, indices)...);
static int callImpl(lua_State* _luaState, IntPack<indices...>) {
((*luaWrapper::check<LUAW_TYPE>(_luaState, 1)).*MemberFunc)(luaWrapper::utils::check<typename luaWrapper::utils::remove_cr<Args>::type>(_luaState, indices)...);
return 0;
}
};
@ -498,12 +486,12 @@ namespace luaWrapper {
template<class ReturnType, class... Args, ReturnType(*LUAW_FUNCTION)(Args...)>
struct StaticFuncWrapper<ReturnType(*)(Args...), LUAW_FUNCTION> {
public:
static int call(lua_State* _L) {
return callImpl(_L, luaWrapper::utils::makeIntRange<2,sizeof...(Args)>());
static int call(lua_State* _luaState) {
return callImpl(_luaState, luaWrapper::utils::makeIntRange<2,sizeof...(Args)>());
}
private:
template<int... indices> static int callImpl(lua_State* _L, IntPack<indices...>) {
luaWrapper::utils::push<ReturnType>(_L, (*LUAW_FUNCTION)(luaWrapper::utils::check<typename luaWrapper::utils::remove_cr<Args>::type>(_L, indices)...));
template<int... indices> static int callImpl(lua_State* _luaState, IntPack<indices...>) {
luaWrapper::utils::push<ReturnType>(_luaState, (*LUAW_FUNCTION)(luaWrapper::utils::check<typename luaWrapper::utils::remove_cr<Args>::type>(_luaState, indices)...));
return 1;
}
};
@ -511,13 +499,13 @@ namespace luaWrapper {
template<class... Args, void(*LUAW_FUNCTION)(Args...)>
struct StaticFuncWrapper<void(*)(Args...), LUAW_FUNCTION> {
public:
static int call(lua_State* _L) {
return callImpl(_L, luaWrapper::utils::makeIntRange<2, sizeof...(Args)>());
static int call(lua_State* _luaState) {
return callImpl(_luaState, luaWrapper::utils::makeIntRange<2, sizeof...(Args)>());
}
private:
template<int... indices>
static int callImpl(lua_State* _L, luaWrapper::utils::IntPack<indices...>) {
(*LUAW_FUNCTION)(luaWrapper::utils::check<typename luaWrapper::utils::remove_cr<Args>::type>(_L, indices)...);
static int callImpl(lua_State* _luaState, luaWrapper::utils::IntPack<indices...>) {
(*LUAW_FUNCTION)(luaWrapper::utils::check<typename luaWrapper::utils::remove_cr<Args>::type>(_luaState, indices)...);
return 0;
}
};
@ -539,13 +527,13 @@ namespace luaWrapper {
* foo = Foo.new()
* foo2 = foo:clone()
*/
template <typename LUAW_TYPE> int clone(lua_State* _L) {
T* obj = new T(*luaWrapper::check<LUAW_TYPE>(_L, 1));
lua_remove(_L, 1); // ...
int numargs = lua_gettop(_L);
luaWrapper::push<T>(_L, obj); // ... clone
luaWrapper::hold<T>(_L, obj);
luaWrapper::postconstructor<LUAW_TYPE>(_L, numargs);
template <typename LUAW_TYPE> int clone(lua_State* _luaState) {
LUAW_TYPE* obj = new LUAW_TYPE(*luaWrapper::check<LUAW_TYPE>(_luaState, 1));
lua_remove(_luaState, 1); // ...
int numargs = lua_gettop(_luaState);
luaWrapper::push<LUAW_TYPE>(_luaState, obj); // ... clone
luaWrapper::hold<LUAW_TYPE>(_luaState, obj);
luaWrapper::postconstructor<LUAW_TYPE>(_luaState, numargs);
return 1;
}
@ -567,17 +555,17 @@ namespace luaWrapper {
* After the object is constructed, luaWrapper::utils::build will do the equivalent of
* calling f:X(10) and f:Y(20).
*/
template <typename LUAW_TYPE> int build(lua_State* _L) {
template <typename LUAW_TYPE> int build(lua_State* _luaState) {
// obj {}
lua_insert(_L, -2); // {} obj
if (lua_type(_L, 1) == LUA_TTABLE) {
for (lua_pushnil(_L); lua_next(_L, 1); lua_pop(_L, 1)) {
lua_insert(_luaState, -2); // {} obj
if (lua_type(_luaState, 1) == LUA_TTABLE) {
for (lua_pushnil(_luaState); lua_next(_luaState, 1); lua_pop(_luaState, 1)) {
// {} obj k v
lua_pushvalue(_L, -2); // {} obj k v k
lua_gettable(_L, -4); // {} obj k v ud[k]
lua_pushvalue(_L, -4); // {} obj k v ud[k] ud
lua_pushvalue(_L, -3); // {} obj k v ud[k] ud v
lua_call(_L, 2, 0); // {} obj k v
lua_pushvalue(_luaState, -2); // {} obj k v k
lua_gettable(_luaState, -4); // {} obj k v ud[k]
lua_pushvalue(_luaState, -4); // {} obj k v ud[k] ud
lua_pushvalue(_luaState, -3); // {} obj k v ud[k] ud v
lua_call(_luaState, 2, 0); // {} obj k v
}
// {} ud
}
@ -595,30 +583,30 @@ namespace luaWrapper {
*
* e.g.
*
* Foo* parent = luaWrapper::check<Foo>(_L, 1);
* Bar* child = luaWrapper::check<Bar>(_L, 2);
* Foo* parent = luaWrapper::check<Foo>(_luaState, 1);
* Bar* child = luaWrapper::check<Bar>(_luaState, 2);
* if (parent && child)
* {
* luaWrapper::utils::store<Bar>(_L, 1, "Children");
* luaWrapper::utils::store<Bar>(_luaState, 1, "Children");
* parent->AddChild(child);
* }
*/
template <typename T> void store(lua_State* _L, int _index, const char* _storagetable, const char* _key = NULL) {
template <typename LUAW_TYPE> void store(lua_State* _luaState, int _index, const char* _storagetable, const char* _key = NULL) {
// ... store ... obj store.storagetable
lua_getfield(_L, _index, _storagetable);
lua_getfield(_luaState, _index, _storagetable);
if (_key) {
// ... store ... obj store.storagetable key
lua_pushstring(_L, _key);
lua_pushstring(_luaState, _key);
} else {
// ... store ... obj store.storagetable key
LuaWrapper<T>::identifier(_L, luaWrapper::to<T>(_L, -2));
LuaWrapper<LUAW_TYPE>::identifier(_luaState, luaWrapper::to<LUAW_TYPE>(_luaState, -2));
}
// ... store ... obj store.storagetable key obj
lua_pushvalue(_L, -3);
lua_pushvalue(_luaState, -3);
// ... store ... obj store.storagetable
lua_settable(_L, -3);
lua_settable(_luaState, -3);
// ... store ... obj
lua_pop(_L, 1);
lua_pop(_luaState, 1);
}
}
}

41
lutin_luaWrapper-test.py Normal file
View File

@ -0,0 +1,41 @@
#!/usr/bin/python
import lutin.debug as debug
import lutin.tools as tools
def get_type():
return "BINARY"
def get_sub_type():
return "TEST"
def get_name():
return "lua-wrapper-test"
def get_desc():
return "lua wrapper test application"
def get_licence():
return "MPL-2"
def get_compagny_type():
return "com"
def get_compagny_name():
return "atria-soft"
def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
def configure(target, my_module):
my_module.add_src_file([
'test/test.cpp',
'test/testCCallLuaFunction.cpp',
])
my_module.add_depend([
'luaWrapper',
'etest',
'test-debug'
])
return True

View File

@ -82,11 +82,12 @@ static luaL_Reg BankAccount_metatable[] = {
};
int luaopen_BankAccount(luaWrapper:Lua& _lua) {
_lua.registerElement<BankAccount>("BankAccount",
BankAccount_table,
BankAccount_metatable,
BankAccount_new // If your class has a default constructor you can omit this argument, LuaWrapper will generate a default allocator for you.
);
luaWrapper::registerElement<BankAccount>(_lua,
"BankAccount",
BankAccount_table,
BankAccount_metatable,
BankAccount_new
);
return 1;
}

View File

@ -133,7 +133,7 @@ static luaL_Reg Example_metatable[] = {
};
int luaopen_Example(luaWrapper:Lua& _lua) {
_lua.registerElement<Example>("Example", NULL, Example_metatable);
luaWrapper::registerElement<Example>(_lua, "Example", NULL, Example_metatable);
return 1;
}

24
test/test.cpp Normal file
View File

@ -0,0 +1,24 @@
/**
* @author Edouard DUPIN
* @copyright 2014, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etk/Vector.hpp>
#include <etk/etk.hpp>
#include <etk/types.hpp>
#include <etk/archive/Archive.hpp>
#include <test-debug/debug.hpp>
#include <etest/etest.hpp>
#include <etk/os/FSNode.hpp>
int main(int argc, const char *argv[]) {
// init test engine:
etest::init(argc, argv);
// init etk log system and file interface:
etk::init(argc, argv);
// Run all test with etest
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,25 @@
/**
* @author Edouard DUPIN
* @copyright 2014, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <luaWrapper/luaWrapper.hpp>
#include <etest/etest.hpp>
static etk::String refOutputBoolean1("{\n\t\"tmpElement\": true\n}\n");
TEST(TestCCallLuaFunctionn, basicCall) {
luaWrapper::Lua lua;
lua.executeString(R"#(
function MyFunctionName(x, y)
return x + y*2
end
)#");
float ret = lua.call<float>("MyFunctionName", 43.9f, 43.6f);
EXPECT_EQ(ret, 43.9f + 43.6f * 2.0f);
}