Skip to content

Commit

Permalink
allow to access data-members in weak/shared ptr classes
Browse files Browse the repository at this point in the history
  • Loading branch information
x42 committed Aug 26, 2016
1 parent 1d7c144 commit a4da074
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
60 changes: 60 additions & 0 deletions libs/lua/LuaBridge/detail/CFunctions.h
Expand Up @@ -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
Expand Down
60 changes: 60 additions & 0 deletions libs/lua/LuaBridge/detail/Namespace.h
Expand Up @@ -1314,6 +1314,66 @@ class Namespace
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);
Expand Down

0 comments on commit a4da074

Please sign in to comment.