allow to access data-members in weak/shared ptr classes
authorRobin Gareus <robin@gareus.org>
Fri, 26 Aug 2016 17:01:09 +0000 (19:01 +0200)
committerRobin Gareus <robin@gareus.org>
Fri, 26 Aug 2016 17:01:09 +0000 (19:01 +0200)
libs/lua/LuaBridge/detail/CFunctions.h
libs/lua/LuaBridge/detail/Namespace.h

index fafad5d0a79d932ec3e41794f534aa59ee9d66d0..824bdd7e963c8a52dd76cce5c75039dbda8b647b 100644 (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
index 7774b9f873e4220a1ec0096cd4cce85715bcbd4b..d05effc41074fc27e1ded013d11b3693b9c5abae 100644 (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);