13
0

allow to access data-members in weak/shared ptr classes

This commit is contained in:
Robin Gareus 2016-08-26 19:01:09 +02:00
parent 1d7c144967
commit a4da0747e1
2 changed files with 120 additions and 0 deletions

View File

@ -461,6 +461,66 @@ struct CFunc
}
};
template <class C, typename T>
static int getPtrProperty (lua_State* L)
{
boost::shared_ptr<C> cp = luabridge::Stack<boost::shared_ptr<C> >::get (L, 1);
C const* const c = cp.get();
if (!c) {
return luaL_error (L, "shared_ptr is nil");
}
T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
Stack <T>::push (L, c->**mp);
return 1;
}
template <class C, typename T>
static int getWPtrProperty (lua_State* L)
{
boost::weak_ptr<C> cw = luabridge::Stack<boost::weak_ptr<C> >::get (L, 1);
boost::shared_ptr<C> const cp = cw.lock();
if (!cp) {
return luaL_error (L, "cannot lock weak_ptr");
}
C const* const c = cp.get();
if (!c) {
return luaL_error (L, "weak_ptr is nil");
}
T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
Stack <T>::push (L, c->**mp);
return 1;
}
template <class C, typename T>
static int setPtrProperty (lua_State* L)
{
boost::shared_ptr<C> cp = luabridge::Stack<boost::shared_ptr<C> >::get (L, 1);
C* const c = cp.get();
if (!c) {
return luaL_error (L, "shared_ptr is nil");
}
T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
c->**mp = Stack <T>::get (L, 2);
return 0;
}
template <class C, typename T>
static int setWPtrProperty (lua_State* L)
{
boost::weak_ptr<C> cw = luabridge::Stack<boost::weak_ptr<C> >::get (L, 1);
boost::shared_ptr<C> cp = cw.lock();
if (!cp) {
return luaL_error (L, "cannot lock weak_ptr");
}
C* const c = cp.get();
if (!c) {
return luaL_error (L, "weak_ptr is nil");
}
T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
c->**mp = Stack <T>::get (L, 2);
return 0;
}
template <class MemFnPtr, class T,
class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
struct CallMemberWPtr

View File

@ -1314,6 +1314,66 @@ private:
return *this;
}
template <class U>
WSPtrClass <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
{
DATADOC ("Data Member", name, mp)
typedef const U T::*mp_t;
set_weak_class ();
assert (lua_istable (L, -1));
// Add to __propget in class and const tables.
{
rawgetfield (L, -2, "__propget");
rawgetfield (L, -4, "__propget");
new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
lua_pushcclosure (L, &CFunc::getWPtrProperty <T,U>, 1);
lua_pushvalue (L, -1);
rawsetfield (L, -4, name);
rawsetfield (L, -2, name);
lua_pop (L, 2);
}
if (isWritable)
{
// Add to __propset in class table.
rawgetfield (L, -2, "__propset");
assert (lua_istable (L, -1));
new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
lua_pushcclosure (L, &CFunc::setWPtrProperty <T,U>, 1);
rawsetfield (L, -2, name);
lua_pop (L, 1);
}
set_shared_class ();
assert (lua_istable (L, -1));
// Add to __propget in class and const tables.
{
rawgetfield (L, -2, "__propget");
rawgetfield (L, -4, "__propget");
new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
lua_pushcclosure (L, &CFunc::getPtrProperty <T,U>, 1);
lua_pushvalue (L, -1);
rawsetfield (L, -4, name);
rawsetfield (L, -2, name);
lua_pop (L, 2);
}
if (isWritable)
{
// Add to __propset in class table.
rawgetfield (L, -2, "__propset");
assert (lua_istable (L, -1));
new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
lua_pushcclosure (L, &CFunc::setPtrProperty <T,U>, 1);
rawsetfield (L, -2, name);
lua_pop (L, 1);
}
return *this;
}
Namespace endClass ()
{
return Namespace (this);