From a4da0747e1e29cac6cc37bbf8b1ffdedd381f8e8 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 26 Aug 2016 19:01:09 +0200 Subject: allow to access data-members in weak/shared ptr classes --- libs/lua/LuaBridge/detail/CFunctions.h | 60 ++++++++++++++++++++++++++++++++++ libs/lua/LuaBridge/detail/Namespace.h | 60 ++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) (limited to 'libs') diff --git a/libs/lua/LuaBridge/detail/CFunctions.h b/libs/lua/LuaBridge/detail/CFunctions.h index fafad5d0a7..824bdd7e96 100644 --- a/libs/lua/LuaBridge/detail/CFunctions.h +++ b/libs/lua/LuaBridge/detail/CFunctions.h @@ -461,6 +461,66 @@ struct CFunc } }; + template + static int getPtrProperty (lua_State* L) + { + boost::shared_ptr cp = luabridge::Stack >::get (L, 1); + C const* const c = cp.get(); + if (!c) { + return luaL_error (L, "shared_ptr is nil"); + } + T C::** mp = static_cast (lua_touserdata (L, lua_upvalueindex (1))); + Stack ::push (L, c->**mp); + return 1; + } + + template + static int getWPtrProperty (lua_State* L) + { + boost::weak_ptr cw = luabridge::Stack >::get (L, 1); + boost::shared_ptr 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 (lua_touserdata (L, lua_upvalueindex (1))); + Stack ::push (L, c->**mp); + return 1; + } + + template + static int setPtrProperty (lua_State* L) + { + boost::shared_ptr cp = luabridge::Stack >::get (L, 1); + C* const c = cp.get(); + if (!c) { + return luaL_error (L, "shared_ptr is nil"); + } + T C::** mp = static_cast (lua_touserdata (L, lua_upvalueindex (1))); + c->**mp = Stack ::get (L, 2); + return 0; + } + + template + static int setWPtrProperty (lua_State* L) + { + boost::weak_ptr cw = luabridge::Stack >::get (L, 1); + boost::shared_ptr 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 (lua_touserdata (L, lua_upvalueindex (1))); + c->**mp = Stack ::get (L, 2); + return 0; + } + template ::ReturnType> struct CallMemberWPtr diff --git a/libs/lua/LuaBridge/detail/Namespace.h b/libs/lua/LuaBridge/detail/Namespace.h index 7774b9f873..d05effc410 100644 --- a/libs/lua/LuaBridge/detail/Namespace.h +++ b/libs/lua/LuaBridge/detail/Namespace.h @@ -1314,6 +1314,66 @@ private: return *this; } + template + WSPtrClass & 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 , 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 , 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 , 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 , 1); + rawsetfield (L, -2, name); + lua_pop (L, 1); + } + + return *this; + } + + Namespace endClass () { return Namespace (this); -- cgit v1.2.3