From a8ae47ada29108540c04ef0503fa30a68ba57f73 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 21 Feb 2016 19:26:06 +0100 Subject: LuaBridge: support argument references via table return --- libs/lua/LuaBridge/LuaBridge.h | 1 + libs/lua/LuaBridge/detail/CFunctions.h | 239 +++++++++++++++++++++++++++++++ libs/lua/LuaBridge/detail/FuncArgs.h | 51 +++++++ libs/lua/LuaBridge/detail/FuncTraits.h | 96 ++++++------- libs/lua/LuaBridge/detail/Namespace.h | 18 +++ libs/lua/LuaBridge/detail/Stack.h | 247 +++++++++++++++++++++++++++++++-- 6 files changed, 594 insertions(+), 58 deletions(-) create mode 100644 libs/lua/LuaBridge/detail/FuncArgs.h (limited to 'libs/lua') diff --git a/libs/lua/LuaBridge/LuaBridge.h b/libs/lua/LuaBridge/LuaBridge.h index fb61340bcc..d03120ae00 100644 --- a/libs/lua/LuaBridge/LuaBridge.h +++ b/libs/lua/LuaBridge/LuaBridge.h @@ -77,6 +77,7 @@ class LuaRef; #include "detail/LuaException.h" #include "detail/LuaRef.h" #include "detail/Iterator.h" +#include "detail/FuncArgs.h" //------------------------------------------------------------------------------ /** diff --git a/libs/lua/LuaBridge/detail/CFunctions.h b/libs/lua/LuaBridge/detail/CFunctions.h index 1c0caa84ac..fa78b78fd6 100644 --- a/libs/lua/LuaBridge/detail/CFunctions.h +++ b/libs/lua/LuaBridge/detail/CFunctions.h @@ -378,7 +378,106 @@ struct CFunc } }; + /** + lua_CFunction to calls for function references. + */ + template ::ReturnType> + struct CallMemberRef + { + typedef typename FuncTraits ::ClassType T; + typedef typename FuncTraits ::Params Params; + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T* const t = Userdata::get (L, 1, false); + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList args (L); + Stack ::push (L, FuncTraits ::call (t, fnptr, args)); + LuaRef v (newTable (L)); + FuncArgs ::refs (v, args); + v.push(L); + return 2; + } + }; + + template ::ReturnType> + struct CallConstMemberRef + { + typedef typename FuncTraits ::ClassType T; + typedef typename FuncTraits ::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T const* const t = Userdata::get (L, 1, true); + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList args(L); + Stack ::push (L, FuncTraits ::call (t, fnptr, args)); + LuaRef v (newTable (L)); + FuncArgs ::refs (v, args); + v.push(L); + return 2; + } + }; + + template ::ReturnType> + struct CallMemberRefPtr + { + typedef typename FuncTraits ::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + boost::shared_ptr* const t = Userdata::get > (L, 1, false); + T* const tt = t->get(); + if (!tt) { + return luaL_error (L, "shared_ptr is nil"); + } + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList args (L); + Stack ::push (L, FuncTraits ::call (tt, fnptr, args)); + LuaRef v (newTable (L)); + FuncArgs ::refs (v, args); + v.push(L); + return 2; + } + }; + + template ::ReturnType> + struct CallMemberRefWPtr + { + typedef typename FuncTraits ::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + boost::weak_ptr* const tw = Userdata::get > (L, 1, false); + boost::shared_ptr const t = tw->lock(); + if (!t) { + return luaL_error (L, "cannot lock weak_ptr"); + } + T* const tt = t.get(); + if (!tt) { + return luaL_error (L, "weak_ptr is nil"); + } + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList args (L); + Stack ::push (L, FuncTraits ::call (tt, fnptr, args)); + LuaRef v (newTable (L)); + FuncArgs ::refs (v, args); + v.push(L); + return 2; + } + }; //---------------------------------------------------------------------------- /** @@ -466,7 +565,99 @@ struct CFunc } }; + template + struct CallMemberRef + { + typedef typename FuncTraits ::ClassType T; + typedef typename FuncTraits ::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T* const t = Userdata::get (L, 1, false); + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList args (L); + FuncTraits ::call (t, fnptr, args); + LuaRef v (newTable (L)); + FuncArgs ::refs (v, args); + v.push(L); + return 1; + } + }; + + template + struct CallConstMemberRef + { + typedef typename FuncTraits ::ClassType T; + typedef typename FuncTraits ::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T const* const t = Userdata::get (L, 1, true); + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList args (L); + FuncTraits ::call (t, fnptr, args); + LuaRef v (newTable (L)); + FuncArgs ::refs (v, args); + v.push(L); + return 1; + } + }; + + template + struct CallMemberRefPtr + { + typedef typename FuncTraits ::Params Params; + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + boost::shared_ptr* const t = Userdata::get > (L, 1, false); + T* const tt = t->get(); + if (!tt) { + return luaL_error (L, "shared_ptr is nil"); + } + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList args (L); + FuncTraits ::call (tt, fnptr, args); + LuaRef v (newTable (L)); + FuncArgs ::refs (v, args); + v.push(L); + return 1; + } + }; + + template + struct CallMemberRefWPtr + { + typedef typename FuncTraits ::Params Params; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + boost::weak_ptr* const tw = Userdata::get > (L, 1, false); + boost::shared_ptr const t = tw->lock(); + if (!t) { + return luaL_error (L, "cannot lock weak_ptr"); + } + T* const tt = t.get(); + if (!tt) { + return luaL_error (L, "weak_ptr is nil"); + } + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + ArgList args (L); + FuncTraits ::call (tt, fnptr, args); + LuaRef v (newTable (L)); + FuncArgs ::refs (v, args); + v.push(L); + return 1; + } + }; //-------------------------------------------------------------------------- /** @@ -543,6 +734,18 @@ struct CFunc } }; + template + struct CallMemberRefPtrFunctionHelper + { + typedef typename FuncTraits ::ClassType T; + static void add (lua_State* L, char const* name, MemFnPtr mf) + { + new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); + lua_pushcclosure (L, &CallMemberRefPtr ::f, 1); + rawsetfield (L, -3, name); // class table + } + }; + template struct CallMemberWPtrFunctionHelper { @@ -555,6 +758,42 @@ struct CFunc } }; + template + struct CallMemberRefWPtrFunctionHelper + { + typedef typename FuncTraits ::ClassType T; + static void add (lua_State* L, char const* name, MemFnPtr mf) + { + new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); + lua_pushcclosure (L, &CallMemberRefWPtr ::f, 1); + rawsetfield (L, -3, name); // class table + } + }; + + template + struct CallMemberRefFunctionHelper + { + static void add (lua_State* L, char const* name, MemFnPtr mf) + { + new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); + lua_pushcclosure (L, &CallConstMemberRef ::f, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -5, name); // const table + rawsetfield (L, -3, name); // class table + } + }; + + template + struct CallMemberRefFunctionHelper + { + static void add (lua_State* L, char const* name, MemFnPtr mf) + { + new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); + lua_pushcclosure (L, &CallMemberRef ::f, 1); + rawsetfield (L, -3, name); // class table + } + }; + //-------------------------------------------------------------------------- /** __gc metamethod for a class. diff --git a/libs/lua/LuaBridge/detail/FuncArgs.h b/libs/lua/LuaBridge/detail/FuncArgs.h new file mode 100644 index 0000000000..38d0543175 --- /dev/null +++ b/libs/lua/LuaBridge/detail/FuncArgs.h @@ -0,0 +1,51 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2016, Robin Gareus + Copyright 2012, Vinnie Falco + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +template +struct FuncArgs +{ +}; + +template +struct FuncArgs +{ + static void refs (LuaRef, TypeListValues ) + { + } +}; + +template +struct FuncArgs, Start > +{ + static void refs (LuaRef l, TypeListValues > tvl) + { + l[Start + 1] = tvl.hd; + FuncArgs ::refs (l, tvl.tl); + } +}; diff --git a/libs/lua/LuaBridge/detail/FuncTraits.h b/libs/lua/LuaBridge/detail/FuncTraits.h index a99cbab299..c99d028e86 100644 --- a/libs/lua/LuaBridge/detail/FuncTraits.h +++ b/libs/lua/LuaBridge/detail/FuncTraits.h @@ -81,7 +81,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd); } @@ -94,7 +94,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd); } @@ -107,7 +107,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); } @@ -120,7 +120,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); } @@ -133,7 +133,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); } @@ -146,7 +146,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); } @@ -159,7 +159,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); } @@ -172,7 +172,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > > > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); } @@ -204,7 +204,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues &tvl) { return (obj->*fp)(tvl.hd); } @@ -219,7 +219,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd); } @@ -234,7 +234,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); } @@ -249,7 +249,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); } @@ -264,7 +264,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); } @@ -279,7 +279,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); } @@ -294,7 +294,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); } @@ -309,7 +309,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); } @@ -341,7 +341,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd); } @@ -357,7 +357,7 @@ struct FuncTraits typedef R ReturnType; typedef TypeList > Params; static R call (T const* obj, R (T::*fp) (P1, P2) const, - TypeListValues tvl) + TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd); } @@ -372,7 +372,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); } @@ -387,7 +387,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); } @@ -402,7 +402,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); } @@ -417,7 +417,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); } @@ -432,7 +432,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); } @@ -447,7 +447,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); } @@ -477,7 +477,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd); } @@ -490,7 +490,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd); } @@ -503,7 +503,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); } @@ -516,7 +516,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); } @@ -529,7 +529,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); } @@ -542,7 +542,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); } @@ -555,7 +555,7 @@ struct FuncTraits typedef D DeclType; typedef R ReturnType; typedef TypeList > > > > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); } @@ -568,7 +568,7 @@ struct FuncTraits > > > > > > > Params; - static R call (D fp, TypeListValues tvl) + static R call (D fp, TypeListValues & tvl) { return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); } @@ -600,7 +600,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd); } @@ -615,7 +615,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd); } @@ -630,7 +630,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); } @@ -645,7 +645,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); } @@ -660,7 +660,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); } @@ -675,7 +675,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); } @@ -690,7 +690,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); } @@ -705,7 +705,7 @@ struct FuncTraits > > > > > > > Params; - static R call (T* obj, D fp, TypeListValues tvl) + static R call (T* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); } @@ -737,7 +737,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd); } @@ -752,7 +752,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd); } @@ -767,7 +767,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); } @@ -782,7 +782,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); } @@ -797,7 +797,7 @@ struct FuncTraits typedef T ClassType; typedef R ReturnType; typedef TypeList > > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); @@ -813,7 +813,7 @@ struct FuncTraits > > > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); } @@ -828,7 +828,7 @@ struct FuncTraits > > > > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); } @@ -843,7 +843,7 @@ struct FuncTraits > > > > > > > Params; - static R call (T const* obj, D fp, TypeListValues tvl) + static R call (T const* obj, D fp, TypeListValues & tvl) { return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); } diff --git a/libs/lua/LuaBridge/detail/Namespace.h b/libs/lua/LuaBridge/detail/Namespace.h index 464d9d08a0..eae70dd41e 100644 --- a/libs/lua/LuaBridge/detail/Namespace.h +++ b/libs/lua/LuaBridge/detail/Namespace.h @@ -815,6 +815,13 @@ private: return *this; } + template + Class & addRefFunction (char const* name, MemFn mf) + { + CFunc::CallMemberRefFunctionHelper ::isConstMemberFunction>::add (L, name, mf); + return *this; + } + //-------------------------------------------------------------------------- /** @@ -1031,6 +1038,17 @@ private: return *this; } + template + WSPtrClass & addRefFunction (char const* name, MemFn mf) + { + set_weak_class (); + CFunc::CallMemberRefWPtrFunctionHelper ::add (L, name, mf); + + set_shared_class (); + CFunc::CallMemberRefPtrFunctionHelper ::add (L, name, mf); + return *this; + } + template WSPtrClass & addConstructor () { diff --git a/libs/lua/LuaBridge/detail/Stack.h b/libs/lua/LuaBridge/detail/Stack.h index a569093ad1..0d4919be27 100644 --- a/libs/lua/LuaBridge/detail/Stack.h +++ b/libs/lua/LuaBridge/detail/Stack.h @@ -59,6 +59,31 @@ struct Stack } }; +//------------------------------------------------------------------------------ +/** + Stack specialization for passing references to built-in types. + + This allows to call functions using primitives, but + the value assigned by the C++ function is *lost*. + + http://sourceforge.net/p/luabind/mailman/message/32692027/ + + Alternatives: + - wrap all C++ function that have non const reference arguments + (cleanest solution) + + - use a struct to wrap the value (not a primitive) + (needs major work to special case arguments in CFunc::) + + - wrap the function and provide the assigned value + as addition return values + + Either would place hard constraints on the lua code though. + + We currently only need this for Ardour::Editor::do_import() framecnt_t& + and the returned position is not important. +*/ + //------------------------------------------------------------------------------ /** Stack specialization for `int`. @@ -90,6 +115,23 @@ struct Stack return static_cast (luaL_checknumber (L, index)); } }; + +template <> +struct Stack +{ + static inline void push (lua_State* L, int &value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline int& get (lua_State* L, int index) + { + int l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `unsigned int`. @@ -122,6 +164,22 @@ struct Stack } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, unsigned int& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline unsigned int& get (lua_State* L, int index) + { + unsigned int l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `unsigned char`. @@ -154,6 +212,22 @@ struct Stack } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, unsigned char& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline unsigned char& get (lua_State* L, int index) + { + unsigned char l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `short`. @@ -186,6 +260,22 @@ struct Stack } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, short& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline short& get (lua_State* L, int index) + { + short l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `unsigned short`. @@ -218,6 +308,22 @@ struct Stack } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, unsigned short& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline unsigned short& get (lua_State* L, int index) + { + unsigned short l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `long`. @@ -250,6 +356,22 @@ struct Stack } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, long& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline long& get (lua_State* L, int index) + { + long l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `unsigned long`. @@ -282,6 +404,22 @@ struct Stack } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, unsigned long& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline unsigned long& get (lua_State* L, int index) + { + unsigned long l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `long long`. @@ -314,6 +452,22 @@ struct Stack } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, long long& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline long long& get (lua_State* L, int index) + { + long long l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `unsigned long long`. @@ -378,6 +532,22 @@ struct Stack } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, float& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline float& get (lua_State* L, int index) + { + float l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `double`. @@ -408,6 +578,21 @@ template <> struct Stack } }; +template <> struct Stack +{ + static inline void push (lua_State* L, double& value) + { + lua_pushnumber (L, static_cast (value)); + } + + static inline double& get (lua_State* L, int index) + { + double l = static_cast (luaL_checknumber (L, index)); + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `bool`. @@ -438,6 +623,21 @@ struct Stack { } }; +template <> +struct Stack { + static inline void push (lua_State* L, bool& value) + { + lua_pushboolean (L, value ? 1 : 0); + } + + static inline bool& get (lua_State* L, int index) + { + bool l = lua_toboolean (L, index) ? true : false; + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `char`. @@ -472,12 +672,8 @@ struct Stack } }; -//------------------------------------------------------------------------------ -/** - Stack specialization for `float`. -*/ template <> -struct Stack +struct Stack { static inline void push (lua_State* L, char const* str) { @@ -487,12 +683,29 @@ struct Stack lua_pushnil (L); } - static inline char const* get (lua_State* L, int index) + static inline char const *get (lua_State* L, int index) { return lua_isnil (L, index) ? 0 : luaL_checkstring (L, index); } }; +template <> +struct Stack +{ + static inline void push (lua_State* L, char& value) + { + char str [2] = { value, 0 }; + lua_pushstring (L, str); + } + + static inline char get (lua_State* L, int index) + { + char l = luaL_checkstring (L, index) [0]; + boost::reference_wrapper r (l); + return r.get(); + } +}; + //------------------------------------------------------------------------------ /** Stack specialization for `std::string`. @@ -513,10 +726,6 @@ struct Stack } }; -//------------------------------------------------------------------------------ -/** - Stack specialization for `std::string const&`. -*/ template <> struct Stack { @@ -532,3 +741,21 @@ struct Stack return std::string (str, len); } }; + +template <> +struct Stack +{ + static inline void push (lua_State* L, std::string& str) + { + lua_pushlstring (L, str.c_str (), str.size()); + } + + static inline std::string& get (lua_State* L, int index) + { + size_t len; + const char *str = luaL_checklstring(L, index, &len); + std::string l (str, len); + boost::reference_wrapper r (l); + return r.get(); + } +}; -- cgit v1.2.3