customize LuaBridge
* introduce boost::shared_ptr support * support enum & const * allow to add non-class member functions * STL iterators (vector, list, set, bitset & map) * support reference arguments (framecnt_t&) * add support for arrays of basic types (e.g. float*, int*) * fix compiler warnings
This commit is contained in:
parent
5b40e073e9
commit
12a58015a3
@ -1,7 +1,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
https://github.com/vinniefalco/LuaBridge
|
||||
|
||||
|
||||
Copyright 2016, Robin Gareus <robin@gareus.org>
|
||||
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
Copyright 2007, Nathan Reed
|
||||
|
||||
@ -39,6 +40,17 @@
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <bitset>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#define LUABRIDGE_MAJOR_VERSION 2
|
||||
#define LUABRIDGE_MINOR_VERSION 0
|
||||
#define LUABRIDGE_VERSION 200
|
||||
@ -137,6 +149,6 @@ inline void setHideMetatables (bool shouldHide)
|
||||
Security::setHideMetatables (shouldHide);
|
||||
}
|
||||
|
||||
}
|
||||
} // end Namespace
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
https://github.com/vinniefalco/LuaBridge
|
||||
|
||||
|
||||
Copyright 2016, Robin Gareus <robin@gareus.org>
|
||||
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
@ -290,6 +291,95 @@ struct CFunc
|
||||
}
|
||||
};
|
||||
|
||||
template <class MemFnPtr, class T,
|
||||
class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
|
||||
struct CallMemberPtr
|
||||
{
|
||||
typedef typename FuncTraits <MemFnPtr>::Params Params;
|
||||
|
||||
static int f (lua_State* L)
|
||||
{
|
||||
assert (isfulluserdata (L, lua_upvalueindex (1)));
|
||||
boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
|
||||
T* const tt = t->get();
|
||||
if (!tt) {
|
||||
return luaL_error (L, "shared_ptr is nil");
|
||||
}
|
||||
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
|
||||
assert (fnptr != 0);
|
||||
ArgList <Params, 2> args (L);
|
||||
Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class R>
|
||||
struct CastMemberPtr
|
||||
{
|
||||
static int f (lua_State* L)
|
||||
{
|
||||
boost::shared_ptr<T> t = luabridge::Stack<boost::shared_ptr<T> >::get (L, 1);
|
||||
Stack <boost::shared_ptr<R> >::push (L, boost::dynamic_pointer_cast<R> (t));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct PtrNullCheck
|
||||
{
|
||||
static int f (lua_State* L)
|
||||
{
|
||||
boost::shared_ptr<T> t = luabridge::Stack<boost::shared_ptr<T> >::get (L, 1);
|
||||
Stack <bool>::push (L, t == 0);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct WPtrNullCheck
|
||||
{
|
||||
static int f (lua_State* L)
|
||||
{
|
||||
bool rv = true;
|
||||
boost::weak_ptr<T> tw = luabridge::Stack<boost::weak_ptr<T> >::get (L, 1);
|
||||
boost::shared_ptr<T> const t = tw.lock();
|
||||
if (t) {
|
||||
T* const tt = t.get();
|
||||
rv = (tt == 0);
|
||||
}
|
||||
Stack <bool>::push (L, rv);
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <class MemFnPtr, class T,
|
||||
class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
|
||||
struct CallMemberWPtr
|
||||
{
|
||||
typedef typename FuncTraits <MemFnPtr>::Params Params;
|
||||
|
||||
static int f (lua_State* L)
|
||||
{
|
||||
assert (isfulluserdata (L, lua_upvalueindex (1)));
|
||||
boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
|
||||
boost::shared_ptr<T> const t = tw->lock();
|
||||
if (!t) {
|
||||
return luaL_error (L, "cannot lock weak_ptr");
|
||||
}
|
||||
T* const tt = t.get();
|
||||
if (!tt) {
|
||||
return luaL_error (L, "weak_ptr is nil");
|
||||
}
|
||||
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
|
||||
assert (fnptr != 0);
|
||||
ArgList <Params, 2> args (L);
|
||||
Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
lua_CFunction to call a class member function with no return value.
|
||||
@ -333,6 +423,51 @@ struct CFunc
|
||||
}
|
||||
};
|
||||
|
||||
template <class MemFnPtr, class T>
|
||||
struct CallMemberPtr <MemFnPtr, T, void>
|
||||
{
|
||||
typedef typename FuncTraits <MemFnPtr>::Params Params;
|
||||
|
||||
static int f (lua_State* L)
|
||||
{
|
||||
assert (isfulluserdata (L, lua_upvalueindex (1)));
|
||||
boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
|
||||
T* const tt = t->get();
|
||||
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
|
||||
assert (fnptr != 0);
|
||||
ArgList <Params, 2> args (L);
|
||||
FuncTraits <MemFnPtr>::call (tt, fnptr, args);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <class MemFnPtr, class T>
|
||||
struct CallMemberWPtr <MemFnPtr, T, void>
|
||||
{
|
||||
typedef typename FuncTraits <MemFnPtr>::Params Params;
|
||||
|
||||
static int f (lua_State* L)
|
||||
{
|
||||
assert (isfulluserdata (L, lua_upvalueindex (1)));
|
||||
boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
|
||||
boost::shared_ptr<T> const t = tw->lock();
|
||||
if (!t) {
|
||||
return luaL_error (L, "cannot lock weak_ptr");
|
||||
}
|
||||
T* const tt = t.get();
|
||||
if (!tt) {
|
||||
return luaL_error (L, "weak_ptr is nil");
|
||||
}
|
||||
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
|
||||
assert (fnptr != 0);
|
||||
ArgList <Params, 2> args (L);
|
||||
FuncTraits <MemFnPtr>::call (tt, fnptr, args);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
lua_CFunction to call a class member lua_CFunction.
|
||||
@ -396,6 +531,30 @@ struct CFunc
|
||||
}
|
||||
};
|
||||
|
||||
template <class MemFnPtr>
|
||||
struct CallMemberPtrFunctionHelper
|
||||
{
|
||||
typedef typename FuncTraits <MemFnPtr>::ClassType T;
|
||||
static void add (lua_State* L, char const* name, MemFnPtr mf)
|
||||
{
|
||||
new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
|
||||
lua_pushcclosure (L, &CallMemberPtr <MemFnPtr, T>::f, 1);
|
||||
rawsetfield (L, -3, name); // class table
|
||||
}
|
||||
};
|
||||
|
||||
template <class MemFnPtr>
|
||||
struct CallMemberWPtrFunctionHelper
|
||||
{
|
||||
typedef typename FuncTraits <MemFnPtr>::ClassType T;
|
||||
static void add (lua_State* L, char const* name, MemFnPtr mf)
|
||||
{
|
||||
new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
|
||||
lua_pushcclosure (L, &CallMemberWPtr <MemFnPtr, T>::f, 1);
|
||||
rawsetfield (L, -3, name); // class table
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
__gc metamethod for a class.
|
||||
@ -408,6 +567,11 @@ struct CFunc
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gcNOOPMethod (lua_State* L)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
lua_CFunction to get a class data member.
|
||||
@ -424,6 +588,20 @@ struct CFunc
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
lua_CFunction to get a constant (enum)
|
||||
*/
|
||||
template <typename U>
|
||||
static int getConst (lua_State* L)
|
||||
{
|
||||
U *v = static_cast <U *> (lua_touserdata (L, lua_upvalueindex (1)));
|
||||
assert (v);
|
||||
Stack <U>::push (L, *v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
lua_CFunction to set a class data member.
|
||||
@ -439,4 +617,393 @@ struct CFunc
|
||||
c->**mp = Stack <T>::get (L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// metatable callback for "array[index]"
|
||||
template <typename T>
|
||||
static int array_index (lua_State* L) {
|
||||
T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
|
||||
int const index = luabridge::Stack<int>::get (L, 2);
|
||||
luabridge::Stack<T>::push (L, (*parray)[index-1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// metatable callback for "array[index] = value"
|
||||
template <typename T>
|
||||
static int array_newindex (lua_State* L) {
|
||||
T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
|
||||
int const index = luabridge::Stack<int>::get (L, 2);
|
||||
T const value = luabridge::Stack<T>::get (L, 3);
|
||||
(*parray)[index-1] = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static int getArray (lua_State* L) {
|
||||
T *v = luabridge::Stack<T*>::get (L, 1);
|
||||
T** parray = (T**) lua_newuserdata(L, sizeof(T**));
|
||||
*parray = v;
|
||||
luaL_getmetatable(L, typeid(T).name());
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// copy complete c array to lua table
|
||||
template <typename T>
|
||||
static int getTable (lua_State* L) {
|
||||
T *v = luabridge::Stack<T*>::get (L, 1);
|
||||
const int cnt = luabridge::Stack<int>::get (L, 2);
|
||||
LuaRef t (L);
|
||||
t = newTable (L);
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
t[i + 1] = v[i];
|
||||
}
|
||||
t.push(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// copy lua table to c array
|
||||
template <typename T>
|
||||
static int setTable (lua_State* L) {
|
||||
T *v = luabridge::Stack<T*>::get (L, 1);
|
||||
LuaRef t (LuaRef::fromStack(L, 2));
|
||||
const int cnt = luabridge::Stack<int>::get (L, 3);
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
v[i] = t[i + 1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
C++ STL iterators
|
||||
*/
|
||||
|
||||
// read lua table into C++ std::list
|
||||
template <class T, class C>
|
||||
static int tableToListHelper (lua_State *L, C * const t)
|
||||
{
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
|
||||
if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
|
||||
lua_pushvalue (L, -1);
|
||||
lua_pushnil (L);
|
||||
while (lua_next (L, -2)) {
|
||||
lua_pushvalue (L, -2);
|
||||
T const value = Stack<T>::get (L, -2);
|
||||
t->push_back (value);
|
||||
lua_pop (L, 2);
|
||||
}
|
||||
lua_pop (L, 1);
|
||||
lua_pop (L, 2);
|
||||
Stack<C>::push (L, *t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class T, class C>
|
||||
static int tableToList (lua_State *L)
|
||||
{
|
||||
C * const t = Userdata::get<C> (L, 1, false);
|
||||
return tableToListHelper<T, C> (L, t);
|
||||
}
|
||||
|
||||
template <class T, class C>
|
||||
static int ptrTableToList (lua_State *L)
|
||||
{
|
||||
boost::shared_ptr<C> const* const t = Userdata::get<boost::shared_ptr<C> > (L, 1, true);
|
||||
if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
|
||||
return tableToListHelper<T, C> (L, t->get());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
template <class T, class C>
|
||||
static int listIterIter (lua_State *L) {
|
||||
typedef typename C::const_iterator IterType;
|
||||
IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
|
||||
IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
|
||||
assert (end);
|
||||
assert (iter);
|
||||
if ((*iter) == (*end)) {
|
||||
return 0;
|
||||
}
|
||||
Stack <T>::push (L, **iter);
|
||||
++(*iter);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// generate an iterator
|
||||
template <class T, class C>
|
||||
static int listIterHelper (lua_State *L, C * const t)
|
||||
{
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
|
||||
typedef typename C::const_iterator IterType;
|
||||
new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
|
||||
new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
|
||||
lua_pushcclosure (L, listIterIter<T, C>, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class T, class C>
|
||||
static int listIter (lua_State *L)
|
||||
{
|
||||
C * const t = Userdata::get <C> (L, 1, false);
|
||||
return listIterHelper<T, C> (L, t);
|
||||
}
|
||||
|
||||
template <class T, class C>
|
||||
static int ptrListIter (lua_State *L)
|
||||
{
|
||||
boost::shared_ptr<C> const* const t = Userdata::get <boost::shared_ptr<C> >(L, 1, true);
|
||||
if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
|
||||
return listIterHelper<T, C> (L, t->get());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// generate table from std::list
|
||||
template <class T, class C>
|
||||
static int listToTableHelper (lua_State *L, C const* const t)
|
||||
{
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
|
||||
#if 0 // direct lua api
|
||||
lua_createtable(L, t->size(), 0);
|
||||
int newTable = lua_gettop(L);
|
||||
int index = 1;
|
||||
for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
|
||||
Stack<T>::push(L, (*iter));
|
||||
lua_rawseti (L, newTable, index);
|
||||
}
|
||||
#else // luabridge way
|
||||
LuaRef v (L);
|
||||
v = newTable (L);
|
||||
int index = 1;
|
||||
for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
|
||||
v[index] = (*iter);
|
||||
}
|
||||
v.push(L);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class T, class C>
|
||||
static int listToTable (lua_State *L)
|
||||
{
|
||||
C const* const t = Userdata::get <C> (L, 1, true);
|
||||
return listToTableHelper<T, C> (L, t);
|
||||
}
|
||||
|
||||
template <class T, class C>
|
||||
static int ptrListToTable (lua_State *L)
|
||||
{
|
||||
boost::shared_ptr<C> const* const t = Userdata::get <boost::shared_ptr<C> > (L, 1, true);
|
||||
if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
|
||||
return listToTableHelper<T, C> (L, t->get());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// generate std::map from table
|
||||
|
||||
template <class K, class V>
|
||||
static int tableToMap (lua_State *L)
|
||||
{
|
||||
typedef std::map<K, V> C;
|
||||
C * const t = Userdata::get <C> (L, 1, true);
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
|
||||
if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
|
||||
|
||||
lua_pushvalue (L, -1);
|
||||
lua_pushnil (L);
|
||||
while (lua_next (L, -2)) {
|
||||
lua_pushvalue (L, -2);
|
||||
K const key = Stack<K>::get (L, -1);
|
||||
V const value = Stack<V>::get (L, -2);
|
||||
t->insert (std::pair<K,V> (key, value));
|
||||
//(*t)[key] = value;
|
||||
lua_pop (L, 2);
|
||||
}
|
||||
lua_pop (L, 1);
|
||||
lua_pop (L, 2);
|
||||
Stack<C>::push (L, *t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// iterate over a std::map
|
||||
template <class K, class V>
|
||||
static int mapIterIter (lua_State *L)
|
||||
{
|
||||
typedef std::map<K, V> C;
|
||||
typedef typename C::const_iterator IterType;
|
||||
IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
|
||||
IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
|
||||
assert (end);
|
||||
assert (iter);
|
||||
if ((*iter) == (*end)) {
|
||||
return 0;
|
||||
}
|
||||
Stack <K>::push (L, (*iter)->first);
|
||||
Stack <V>::push (L, (*iter)->second);
|
||||
++(*iter);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// generate iterator
|
||||
template <class K, class V>
|
||||
static int mapIter (lua_State *L)
|
||||
{
|
||||
typedef std::map<K, V> C;
|
||||
C * const t = Userdata::get <C> (L, 1, false);
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
|
||||
typedef typename C::const_iterator IterType;
|
||||
new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
|
||||
new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
|
||||
lua_pushcclosure (L, mapIterIter<K, V>, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// generate table from std::map
|
||||
template <class K, class V>
|
||||
static int mapToTable (lua_State *L)
|
||||
{
|
||||
typedef std::map<K, V> C;
|
||||
C const* const t = Userdata::get <C> (L, 1, true);
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
|
||||
|
||||
LuaRef v (L);
|
||||
v = newTable (L);
|
||||
for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
|
||||
v[(*iter).first] = (*iter).second;
|
||||
}
|
||||
v.push(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// generate std::set from table keys ( table[member] = true )
|
||||
// http://www.lua.org/pil/11.5.html
|
||||
|
||||
template <class T>
|
||||
static int tableToSet (lua_State *L)
|
||||
{
|
||||
typedef std::set<T> C;
|
||||
C * const t = Userdata::get <C> (L, 1, true);
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
|
||||
if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
|
||||
|
||||
lua_pushvalue (L, -1);
|
||||
lua_pushnil (L);
|
||||
while (lua_next (L, -2)) {
|
||||
lua_pushvalue (L, -2);
|
||||
T const member = Stack<T>::get (L, -1);
|
||||
bool const v = Stack<bool>::get (L, -2);
|
||||
if (v) {
|
||||
t->insert (member);
|
||||
}
|
||||
lua_pop (L, 2);
|
||||
}
|
||||
lua_pop (L, 1);
|
||||
lua_pop (L, 2);
|
||||
Stack<C>::push (L, *t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// iterate over a std::set, explicit "true" value.
|
||||
// compare to http://www.lua.org/pil/11.5.html
|
||||
template <class T>
|
||||
static int setIterIter (lua_State *L)
|
||||
{
|
||||
typedef std::set<T> C;
|
||||
typedef typename C::const_iterator IterType;
|
||||
IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
|
||||
IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
|
||||
assert (end);
|
||||
assert (iter);
|
||||
if ((*iter) == (*end)) {
|
||||
return 0;
|
||||
}
|
||||
Stack <T>::push (L, **iter);
|
||||
Stack <bool>::push (L, true);
|
||||
++(*iter);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// generate iterator
|
||||
template <class T>
|
||||
static int setIter (lua_State *L)
|
||||
{
|
||||
typedef std::set<T> C;
|
||||
C * const t = Userdata::get <C> (L, 1, false);
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
|
||||
typedef typename C::const_iterator IterType;
|
||||
new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
|
||||
new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
|
||||
lua_pushcclosure (L, setIterIter<T>, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// generate table from std::set
|
||||
template <class T>
|
||||
static int setToTable (lua_State *L)
|
||||
{
|
||||
typedef std::set<T> C;
|
||||
C const* const t = Userdata::get <C> (L, 1, true);
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
|
||||
|
||||
LuaRef v (L);
|
||||
v = newTable (L);
|
||||
for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
|
||||
v[(*iter)] = true;
|
||||
}
|
||||
v.push(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// bitset { num = true }
|
||||
// compare to http://www.lua.org/pil/11.5.html
|
||||
template <unsigned int T>
|
||||
static int tableToBitSet (lua_State *L)
|
||||
{
|
||||
typedef std::bitset<T> C;
|
||||
C * const t = Userdata::get <C> (L, 1, true);
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
|
||||
if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
|
||||
|
||||
lua_pushvalue (L, -1);
|
||||
lua_pushnil (L);
|
||||
while (lua_next (L, -2)) {
|
||||
lua_pushvalue (L, -2);
|
||||
unsigned int const member = Stack<unsigned int>::get (L, -1);
|
||||
bool const v = Stack<bool>::get (L, -2);
|
||||
if (member < T && v) {
|
||||
t->set (member);
|
||||
}
|
||||
lua_pop (L, 2);
|
||||
}
|
||||
lua_pop (L, 1);
|
||||
lua_pop (L, 2);
|
||||
Stack<C>::push (L, *t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// generate table from std::bitset
|
||||
template <unsigned int T>
|
||||
static int bitSetToTable (lua_State *L)
|
||||
{
|
||||
typedef std::bitset<T> C;
|
||||
C const* const t = Userdata::get <C> (L, 1, true);
|
||||
if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
|
||||
|
||||
LuaRef v (L);
|
||||
v = newTable (L);
|
||||
for (unsigned int i = 0; i < T; ++i) {
|
||||
if (t->test (i)) {
|
||||
v[i] = true;
|
||||
}
|
||||
}
|
||||
v.push(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* vim: set et sw=2: */
|
||||
|
@ -237,6 +237,7 @@ private:
|
||||
}
|
||||
|
||||
inline bool isNil () const { return type () == LUA_TNIL; }
|
||||
inline bool isBoolean () const { return type () == LUA_TBOOLEAN; }
|
||||
inline bool isNumber () const { return type () == LUA_TNUMBER; }
|
||||
inline bool isString () const { return type () == LUA_TSTRING; }
|
||||
inline bool isTable () const { return type () == LUA_TTABLE; }
|
||||
|
@ -2,6 +2,7 @@
|
||||
/*
|
||||
https://github.com/vinniefalco/LuaBridge
|
||||
|
||||
Copyright 2016, Robin Gareus <robin@gareus.org>
|
||||
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
Copyright 2007, Nathan Reed
|
||||
|
||||
@ -482,6 +483,8 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop (L, 1);
|
||||
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
|
||||
rawgetfield (L, -1, "__class");
|
||||
rawgetfield (L, -1, "__const");
|
||||
|
||||
@ -674,6 +677,7 @@ private:
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
Add or replace a property member.
|
||||
@ -797,6 +801,21 @@ private:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class MemFn>
|
||||
Class <T>& addPtrFunction (char const* name, MemFn mf)
|
||||
{
|
||||
CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class MemFn>
|
||||
Class <T>& addWPtrFunction (char const* name, MemFn mf)
|
||||
{
|
||||
CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
Add or replace a member lua_CFunction.
|
||||
@ -812,6 +831,16 @@ private:
|
||||
return *this;
|
||||
}
|
||||
|
||||
// custom callback - extend existing classes
|
||||
// with non-class member functions (e.g STL iterator)
|
||||
Class <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
|
||||
{
|
||||
assert (lua_istable (L, -1));
|
||||
lua_pushcclosure (L, fp, 0);
|
||||
rawsetfield (L, -3, name); // class table
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
Add or replace a const member lua_CFunction.
|
||||
@ -829,6 +858,28 @@ private:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
Add or replace a static const data
|
||||
*/
|
||||
template <typename U>
|
||||
Class <T>& addConst (char const* name, const U val)
|
||||
{
|
||||
assert (lua_istable (L, -1));
|
||||
|
||||
rawgetfield (L, -1, "__propget"); // static
|
||||
new (lua_newuserdata (L, sizeof (val))) U (val);
|
||||
lua_pushcclosure (L, &CFunc::getConst <U>, 1);
|
||||
rawsetfield (L, -2, name);
|
||||
lua_pop (L, 1);
|
||||
|
||||
rawgetfield (L, -1, "__propset"); // static
|
||||
lua_pushstring (L, name);
|
||||
lua_pushcclosure (L, &CFunc::readOnlyError, 1);
|
||||
rawsetfield (L, -2, name);
|
||||
lua_pop (L, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
Add or replace a primary Constructor.
|
||||
@ -859,8 +910,216 @@ private:
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Class <T>& addVoidConstructor ()
|
||||
{
|
||||
return addConstructor <void (*) ()> ();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** C Array to/from table */
|
||||
template <typename T>
|
||||
class Array : public ClassBase
|
||||
{
|
||||
public:
|
||||
Array (char const* name, Namespace const* parent) : ClassBase (parent->L)
|
||||
{
|
||||
m_stackSize = parent->m_stackSize + 3;
|
||||
parent->m_stackSize = 0;
|
||||
|
||||
#if 0 // don't allow to duplicates handlers for same array-type
|
||||
assert (lua_istable (L, -1));
|
||||
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
|
||||
if (lua_istable (L, -1)) {
|
||||
lua_pushnil (L);
|
||||
lua_pushnil (L);
|
||||
return;
|
||||
}
|
||||
lua_pop (L, 1);
|
||||
#endif
|
||||
|
||||
assert (lua_istable (L, -1));
|
||||
rawgetfield (L, -1, name);
|
||||
|
||||
if (lua_isnil (L, -1))
|
||||
{
|
||||
lua_pop (L, 1);
|
||||
|
||||
// register array access in global namespace
|
||||
luaL_newmetatable (L, typeid(T).name());
|
||||
lua_pushcclosure (L, CFunc::array_index<T>, 0);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pushcclosure (L, CFunc::array_newindex<T>, 0);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop (L, 1);
|
||||
|
||||
createConstTable (name);
|
||||
lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
|
||||
rawsetfield (L, -2, "__gc");
|
||||
|
||||
createClassTable (name);
|
||||
lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
|
||||
rawsetfield (L, -2, "__gc");
|
||||
|
||||
createStaticTable (name);
|
||||
|
||||
// Map T back to its tables.
|
||||
lua_pushvalue (L, -1);
|
||||
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
|
||||
lua_pushvalue (L, -2);
|
||||
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
|
||||
lua_pushvalue (L, -3);
|
||||
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
|
||||
|
||||
assert (lua_istable (L, -1));
|
||||
lua_pushcclosure (L, &CFunc::getArray <T>, 0);
|
||||
rawsetfield (L, -3, "array"); // class table
|
||||
|
||||
lua_pushcclosure (L, &CFunc::getTable <T>, 0);
|
||||
rawsetfield (L, -3, "get_table"); // class table
|
||||
|
||||
lua_pushcclosure (L, &CFunc::setTable <T>, 0);
|
||||
rawsetfield (L, -3, "set_table"); // class table
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnil (L);
|
||||
lua_pushnil (L);
|
||||
}
|
||||
}
|
||||
|
||||
Namespace endArray ()
|
||||
{
|
||||
return Namespace (this);
|
||||
}
|
||||
};
|
||||
|
||||
/** Boost Weak & Shared Pointer Class Wrapper */
|
||||
template <class T>
|
||||
class WSPtrClass : public ClassBase
|
||||
{
|
||||
public:
|
||||
WSPtrClass (char const* name, Namespace const* parent)
|
||||
: ClassBase (parent->L)
|
||||
, weak (name, parent)
|
||||
, shared (name, parent)
|
||||
{
|
||||
m_stackSize = weak.m_stackSize;
|
||||
parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
|
||||
lua_pop (L, 3);
|
||||
}
|
||||
|
||||
WSPtrClass (char const* name, Namespace const* parent, void const* const sharedkey, void const* const weakkey)
|
||||
: ClassBase (parent->L)
|
||||
, weak (name, parent, weakkey)
|
||||
, shared (name, parent, sharedkey)
|
||||
{
|
||||
m_stackSize = weak.m_stackSize;
|
||||
parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
|
||||
lua_pop (L, 3);
|
||||
}
|
||||
|
||||
template <class MemFn>
|
||||
WSPtrClass <T>& addFunction (char const* name, MemFn mf)
|
||||
{
|
||||
set_weak_class ();
|
||||
CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
|
||||
|
||||
set_shared_class ();
|
||||
CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class MemFn>
|
||||
WSPtrClass <T>& addConstructor ()
|
||||
{
|
||||
set_weak_class ();
|
||||
lua_pushcclosure (L,
|
||||
&weak.ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::weak_ptr<T> >, 0);
|
||||
rawsetfield(L, -2, "__call");
|
||||
|
||||
set_shared_class ();
|
||||
lua_pushcclosure (L,
|
||||
&shared.ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::shared_ptr<T> >, 0);
|
||||
rawsetfield(L, -2, "__call");
|
||||
return *this;
|
||||
}
|
||||
|
||||
WSPtrClass <T>& addVoidConstructor ()
|
||||
{
|
||||
return addConstructor <void (*) ()> ();
|
||||
}
|
||||
|
||||
WSPtrClass <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
|
||||
{
|
||||
set_weak_class ();
|
||||
assert (lua_istable (L, -1));
|
||||
lua_pushcclosure (L, fp, 0);
|
||||
rawsetfield (L, -3, name); // class table
|
||||
|
||||
set_shared_class ();
|
||||
assert (lua_istable (L, -1));
|
||||
lua_pushcclosure (L, fp, 0);
|
||||
rawsetfield (L, -3, name); // class table
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
WSPtrClass <T>& addCast (char const* name)
|
||||
{
|
||||
// TODO weak ptr
|
||||
set_shared_class ();
|
||||
assert (lua_istable (L, -1));
|
||||
lua_pushcclosure (L, &CFunc::CastMemberPtr <T, U>::f, 0);
|
||||
rawsetfield (L, -3, name); // class table
|
||||
return *this;
|
||||
}
|
||||
|
||||
WSPtrClass <T>& addNullCheck ()
|
||||
{
|
||||
set_weak_class ();
|
||||
assert (lua_istable (L, -1));
|
||||
lua_pushcclosure (L, &CFunc::WPtrNullCheck <T>::f, 0);
|
||||
rawsetfield (L, -3, "isnil"); // class table
|
||||
|
||||
set_shared_class ();
|
||||
assert (lua_istable (L, -1));
|
||||
lua_pushcclosure (L, &CFunc::PtrNullCheck <T>::f, 0);
|
||||
rawsetfield (L, -3, "isnil"); // class table
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Namespace endClass ()
|
||||
{
|
||||
return Namespace (this);
|
||||
}
|
||||
|
||||
private:
|
||||
void set_weak_class () {
|
||||
lua_pop (L, 3);
|
||||
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::weak_ptr<T> >::getStaticKey ());
|
||||
rawgetfield (L, -1, "__class");
|
||||
rawgetfield (L, -1, "__const");
|
||||
lua_insert (L, -3);
|
||||
lua_insert (L, -2);
|
||||
}
|
||||
void set_shared_class () {
|
||||
lua_pop (L, 3);
|
||||
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::shared_ptr<T> >::getStaticKey ());
|
||||
rawgetfield (L, -1, "__class");
|
||||
rawgetfield (L, -1, "__const");
|
||||
lua_insert (L, -3);
|
||||
lua_insert (L, -2);
|
||||
}
|
||||
Class<boost::weak_ptr<T> > weak;
|
||||
Class<boost::shared_ptr<T> > shared;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
@ -1032,6 +1291,25 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
Namespace& addConst (char const* name, const U val)
|
||||
{
|
||||
assert (lua_istable (L, -1));
|
||||
rawgetfield (L, -1, "__propget");
|
||||
new (lua_newuserdata (L, sizeof (val))) U (val);
|
||||
lua_pushcclosure (L, &CFunc::getConst <U>, 1);
|
||||
rawsetfield (L, -2, name);
|
||||
lua_pop (L, 1);
|
||||
|
||||
rawgetfield (L, -1, "__propset");
|
||||
assert (lua_istable (L, -1));
|
||||
lua_pushstring (L, name);
|
||||
lua_pushcclosure (L, &CFunc::readOnlyError, 1);
|
||||
rawsetfield (L, -2, name);
|
||||
lua_pop (L, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
Add or replace a property.
|
||||
@ -1086,6 +1364,19 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
Add or replace a array type
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
Namespace registerArray (char const* name)
|
||||
{
|
||||
return Array <T> (name, this).endArray();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
Add or replace a lua_CFunction.
|
||||
@ -1108,6 +1399,143 @@ public:
|
||||
return Class <T> (name, this);
|
||||
}
|
||||
|
||||
/** weak & shared pointer class */
|
||||
template <class T>
|
||||
WSPtrClass <T> beginWSPtrClass (char const* name)
|
||||
{
|
||||
return WSPtrClass <T> (name, this)
|
||||
.addNullCheck();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <class K, class V>
|
||||
Class<std::map<K, V> > beginStdMap (char const* name)
|
||||
{
|
||||
typedef std::map<K, V> LT;
|
||||
typedef std::pair<const K, V> T;
|
||||
|
||||
return beginClass<LT> (name)
|
||||
.addVoidConstructor ()
|
||||
.addFunction ("empty", <::empty)
|
||||
.addFunction ("size", <::size)
|
||||
.addFunction ("clear", (void (LT::*)())<::clear)
|
||||
.addFunction ("count", (void (LT::*)())<::count)
|
||||
.addExtCFunction ("add", &CFunc::tableToMap<K, V>)
|
||||
.addExtCFunction ("iter", &CFunc::mapIter<K, V>)
|
||||
.addExtCFunction ("table", &CFunc::mapToTable<K, V>);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Class<std::set<T> > beginStdSet (char const* name)
|
||||
{
|
||||
typedef std::set<T> LT;
|
||||
return beginClass<LT> (name)
|
||||
.addVoidConstructor ()
|
||||
.addFunction ("clear", (void (LT::*)())<::clear)
|
||||
.addFunction ("empty", <::empty)
|
||||
.addFunction ("size", <::size)
|
||||
.addExtCFunction ("add", &CFunc::tableToSet<T>)
|
||||
.addExtCFunction ("iter", &CFunc::setIter<T>)
|
||||
.addExtCFunction ("table", &CFunc::setToTable<T>);
|
||||
}
|
||||
|
||||
template <unsigned int T>
|
||||
Class<std::bitset<T> > beginStdBitSet (char const* name)
|
||||
{
|
||||
typedef std::bitset<T> BS;
|
||||
return beginClass<BS> (name)
|
||||
.addVoidConstructor ()
|
||||
.addFunction ("reset", (BS& (BS::*)())&BS::reset)
|
||||
.addFunction ("set", (BS& (BS::*)(size_t, bool))&BS::set)
|
||||
.addFunction ("count", &BS::count)
|
||||
.addFunction ("any", &BS::any)
|
||||
.addFunction ("none", &BS::none)
|
||||
.addFunction ("test", &BS::test)
|
||||
.addFunction ("size", &BS::size)
|
||||
.addExtCFunction ("add", &CFunc::tableToBitSet<T>)
|
||||
.addExtCFunction ("table", &CFunc::bitSetToTable<T>);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Class<std::list<T> > beginConstStdList (char const* name)
|
||||
{
|
||||
typedef std::list<T> LT;
|
||||
return beginClass<LT> (name)
|
||||
.addVoidConstructor ()
|
||||
.addFunction ("empty", <::empty)
|
||||
.addFunction ("size", <::size)
|
||||
.addFunction ("reverse", <::reverse)
|
||||
.addExtCFunction ("iter", &CFunc::listIter<T, LT>)
|
||||
.addExtCFunction ("table", &CFunc::listToTable<T, LT>);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Class<std::list<T> > beginStdList (char const* name)
|
||||
{
|
||||
typedef std::list<T> LT;
|
||||
return beginConstStdList<T> (name)
|
||||
.addFunction ("unique", (void (LT::*)())<::unique)
|
||||
.addFunction ("push_back", (void (LT::*)(const T&))<::push_back)
|
||||
.addExtCFunction ("add", &CFunc::tableToList<T, LT>);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Class<std::vector<T> > beginStdVector (char const* name)
|
||||
{
|
||||
typedef std::vector<T> LT;
|
||||
typedef typename std::vector<T>::reference T_REF;
|
||||
typedef typename std::vector<T>::size_type T_SIZE;
|
||||
|
||||
return beginClass<LT> (name)
|
||||
.addVoidConstructor ()
|
||||
.addFunction ("empty", <::empty)
|
||||
.addFunction ("size", <::size)
|
||||
.addFunction ("push_back", (void (LT::*)(const T&))<::push_back)
|
||||
.addFunction ("at", (T_REF (LT::*)(T_SIZE))<::at)
|
||||
.addExtCFunction ("add", &CFunc::tableToList<T, LT>)
|
||||
.addExtCFunction ("iter", &CFunc::listIter<T, LT>)
|
||||
.addExtCFunction ("table", &CFunc::listToTable<T, LT>);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
Class<boost::shared_ptr<std::list<T> > > beginPtrStdList (char const* name)
|
||||
{
|
||||
typedef std::list<T> LT;
|
||||
|
||||
return beginClass<boost::shared_ptr<LT> > (name)
|
||||
.addVoidConstructor ()
|
||||
.addPtrFunction ("empty", <::empty)
|
||||
.addPtrFunction ("size", <::size)
|
||||
.addPtrFunction ("reverse", <::reverse)
|
||||
.addPtrFunction ("unique", (void (LT::*)())<::unique)
|
||||
.addPtrFunction ("push_back", (void (LT::*)(const T&))<::push_back)
|
||||
.addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
|
||||
.addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
|
||||
.addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Class<boost::shared_ptr<std::vector<T> > > beginPtrStdVector (char const* name)
|
||||
{
|
||||
typedef std::vector<T> LT;
|
||||
typedef typename std::vector<T>::reference T_REF;
|
||||
typedef typename std::vector<T>::size_type T_SIZE;
|
||||
|
||||
return beginClass<boost::shared_ptr<LT> > (name)
|
||||
.addVoidConstructor ()
|
||||
.addPtrFunction ("empty", <::empty)
|
||||
.addPtrFunction ("empty", <::empty)
|
||||
.addPtrFunction ("size", <::size)
|
||||
.addPtrFunction ("push_back", (void (LT::*)(const T&))<::push_back)
|
||||
.addPtrFunction ("at", (T_REF (LT::*)(T_SIZE))<::at)
|
||||
.addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
|
||||
.addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
|
||||
.addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
Derive a new class for registrations.
|
||||
@ -1120,6 +1548,16 @@ public:
|
||||
{
|
||||
return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
WSPtrClass <T> deriveWSPtrClass (char const* name)
|
||||
{
|
||||
return WSPtrClass <T> (name, this,
|
||||
ClassInfo <boost::shared_ptr<U> >::getStaticKey (),
|
||||
ClassInfo <boost::weak_ptr<U> >::getStaticKey ())
|
||||
.addNullCheck();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1134,3 +1572,5 @@ inline Namespace getGlobalNamespace (lua_State* L)
|
||||
{
|
||||
return Namespace::getGlobalNamespace (L);
|
||||
}
|
||||
|
||||
/* vim: set et sw=2: */
|
||||
|
@ -2,6 +2,7 @@
|
||||
/*
|
||||
https://github.com/vinniefalco/LuaBridge
|
||||
|
||||
Copyright 2016, Robin Gareus <robin@gareus.org>
|
||||
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
Copyright 2007, Nathan Reed
|
||||
|
||||
@ -281,6 +282,70 @@ struct Stack <unsigned long const&>
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `long long`.
|
||||
*/
|
||||
template <>
|
||||
struct Stack <long long>
|
||||
{
|
||||
static inline void push (lua_State* L, long long value)
|
||||
{
|
||||
lua_pushinteger (L, static_cast <lua_Integer> (value));
|
||||
}
|
||||
|
||||
static inline long long get (lua_State* L, int index)
|
||||
{
|
||||
return static_cast <long long> (luaL_checkinteger (L, index));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Stack <long long const&>
|
||||
{
|
||||
static inline void push (lua_State* L, long long value)
|
||||
{
|
||||
lua_pushnumber (L, static_cast <lua_Number> (value));
|
||||
}
|
||||
|
||||
static inline long long get (lua_State* L, int index)
|
||||
{
|
||||
return static_cast <long long> (luaL_checknumber (L, index));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `unsigned long long`.
|
||||
*/
|
||||
template <>
|
||||
struct Stack <unsigned long long>
|
||||
{
|
||||
static inline void push (lua_State* L, unsigned long long value)
|
||||
{
|
||||
lua_pushinteger (L, static_cast <lua_Integer> (value));
|
||||
}
|
||||
|
||||
static inline unsigned long long get (lua_State* L, int index)
|
||||
{
|
||||
return static_cast <unsigned long long> (luaL_checkinteger (L, index));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Stack <unsigned long long const&>
|
||||
{
|
||||
static inline void push (lua_State* L, unsigned long long value)
|
||||
{
|
||||
lua_pushnumber (L, static_cast <lua_Number> (value));
|
||||
}
|
||||
|
||||
static inline unsigned long long get (lua_State* L, int index)
|
||||
{
|
||||
return static_cast <unsigned long long> (luaL_checknumber (L, index));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
Stack specialization for `float`.
|
||||
|
@ -89,6 +89,16 @@ struct TypeTraits
|
||||
static const bool value = sizeof (test <ContainerTraits <T> >(0)) == sizeof (yes);
|
||||
};
|
||||
|
||||
/** Determine if T is an enum */
|
||||
template <typename T>
|
||||
class isEnum
|
||||
{
|
||||
public:
|
||||
//static const bool value = std::is_enum<T>::value; // C++11
|
||||
static const bool value = boost::is_enum<T>::value;
|
||||
};
|
||||
|
||||
|
||||
/** Determine if T is const qualified.
|
||||
*/
|
||||
/** @{ */
|
||||
|
@ -1,7 +1,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
https://github.com/vinniefalco/LuaBridge
|
||||
|
||||
|
||||
Copyright 2016, Robin Gareus <robin@gareus.org>
|
||||
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
@ -68,7 +69,7 @@ protected:
|
||||
/**
|
||||
Get an untyped pointer to the contained class.
|
||||
*/
|
||||
inline void* const getPointer ()
|
||||
inline void* getPointer () const
|
||||
{
|
||||
return m_p;
|
||||
}
|
||||
@ -610,7 +611,7 @@ struct UserdataSharedHelper <C, true>
|
||||
either be of the intrusive variety, or in the style of the RefCountedPtr
|
||||
type provided by LuaBridge (that uses a global hash table).
|
||||
*/
|
||||
template <class C, bool byContainer>
|
||||
template <class C, bool byContainer, bool isEnum>
|
||||
struct StackHelper
|
||||
{
|
||||
static inline void push (lua_State* L, C const& c)
|
||||
@ -636,7 +637,7 @@ struct StackHelper
|
||||
retrieved may result in undefined behavior if Lua garbage collected it.
|
||||
*/
|
||||
template <class T>
|
||||
struct StackHelper <T, false>
|
||||
struct StackHelper <T, false, false>
|
||||
{
|
||||
static inline void push (lua_State* L, T const& t)
|
||||
{
|
||||
@ -649,6 +650,22 @@ struct StackHelper <T, false>
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct StackHelper <T, false, true>
|
||||
{
|
||||
static inline void push (lua_State* L, T const& t)
|
||||
{
|
||||
int v = static_cast <int> (t);
|
||||
lua_pushinteger (L, static_cast <lua_Integer> (v));
|
||||
}
|
||||
|
||||
static inline T get (lua_State* L, int index)
|
||||
{
|
||||
int v = static_cast <int> (luaL_checkinteger (L, index));
|
||||
return T (v);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
||||
/**
|
||||
@ -661,13 +678,15 @@ public:
|
||||
static inline void push (lua_State* L, T const& t)
|
||||
{
|
||||
StackHelper <T,
|
||||
TypeTraits::isContainer <T>::value>::push (L, t);
|
||||
TypeTraits::isContainer <T>::value,
|
||||
TypeTraits::isEnum<T>::value>::push (L, t);
|
||||
}
|
||||
|
||||
static inline T get (lua_State* L, int index)
|
||||
{
|
||||
return StackHelper <T,
|
||||
TypeTraits::isContainer <T>::value>::get (L, index);
|
||||
TypeTraits::isContainer <T>::value,
|
||||
TypeTraits::isEnum<T>::value>::get (L, index);
|
||||
}
|
||||
};
|
||||
|
||||
@ -689,7 +708,7 @@ struct Stack <T*>
|
||||
UserdataPtr::push (L, p);
|
||||
}
|
||||
|
||||
static inline T* const get (lua_State* L, int index)
|
||||
static inline T* get (lua_State* L, int index)
|
||||
{
|
||||
return Userdata::get <T> (L, index, false);
|
||||
}
|
||||
@ -704,7 +723,7 @@ struct Stack <T* const>
|
||||
UserdataPtr::push (L, p);
|
||||
}
|
||||
|
||||
static inline T* const get (lua_State* L, int index)
|
||||
static inline T* get (lua_State* L, int index)
|
||||
{
|
||||
return Userdata::get <T> (L, index, false);
|
||||
}
|
||||
@ -719,7 +738,7 @@ struct Stack <T const*>
|
||||
UserdataPtr::push (L, p);
|
||||
}
|
||||
|
||||
static inline T const* const get (lua_State* L, int index)
|
||||
static inline T const* get (lua_State* L, int index)
|
||||
{
|
||||
return Userdata::get <T> (L, index, true);
|
||||
}
|
||||
@ -734,7 +753,7 @@ struct Stack <T const* const>
|
||||
UserdataPtr::push (L, p);
|
||||
}
|
||||
|
||||
static inline T const* const get (lua_State* L, int index)
|
||||
static inline T const* get (lua_State* L, int index)
|
||||
{
|
||||
return Userdata::get <T> (L, index, true);
|
||||
}
|
||||
@ -761,8 +780,8 @@ struct Stack <T&>
|
||||
template <class C, bool byContainer>
|
||||
struct RefStackHelper
|
||||
{
|
||||
typedef C return_type;
|
||||
|
||||
typedef C return_type;
|
||||
|
||||
static inline void push (lua_State* L, C const& t)
|
||||
{
|
||||
UserdataSharedHelper <C,
|
||||
@ -781,12 +800,12 @@ struct RefStackHelper
|
||||
template <class T>
|
||||
struct RefStackHelper <T, false>
|
||||
{
|
||||
typedef T const& return_type;
|
||||
|
||||
static inline void push (lua_State* L, T const& t)
|
||||
{
|
||||
UserdataPtr::push (L, &t);
|
||||
}
|
||||
typedef T const& return_type;
|
||||
|
||||
static inline void push (lua_State* L, T const& t)
|
||||
{
|
||||
UserdataPtr::push (L, &t);
|
||||
}
|
||||
|
||||
static return_type get (lua_State* L, int index)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
std::string dumpLuaState(lua_State *L) {
|
||||
static std::string dumpLuaState(lua_State *L) {
|
||||
std::stringstream ostr;
|
||||
int i;
|
||||
int top = lua_gettop(L);
|
||||
@ -20,7 +20,7 @@ std::string dumpLuaState(lua_State *L) {
|
||||
ostr << " " << i << ": " << lua_tonumber(L, i) << "\n";
|
||||
break;
|
||||
default:
|
||||
ostr << " " << i << ": TYPE=" << lua_typename(L, t) << "\n";
|
||||
ostr << " " << i << ": TYPE=" << lua_typename(L, t) << ": " << lua_topointer(L, i)<< "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user