summaryrefslogtreecommitdiff
path: root/libs/lua
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-08-26 19:01:09 +0200
committerRobin Gareus <robin@gareus.org>2016-08-26 19:01:09 +0200
commita4da0747e1e29cac6cc37bbf8b1ffdedd381f8e8 (patch)
tree81254a396a25a74acee3142078ddfe9c8840c00c /libs/lua
parent1d7c144967b9cd24f4fd53270c340a8accc61cab (diff)
allow to access data-members in weak/shared ptr classes
Diffstat (limited to 'libs/lua')
-rw-r--r--libs/lua/LuaBridge/detail/CFunctions.h60
-rw-r--r--libs/lua/LuaBridge/detail/Namespace.h60
2 files changed, 120 insertions, 0 deletions
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 <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
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 <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);