Changeset 208


Ignore:
Timestamp:
08/19/13 10:54:28 (12 years ago)
Author:
epyon
Message:
  • lua - rewrite of template and custom attribute passing - should be faster, and is way better designed
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/lua/lua_area.hh

    r207 r208  
    3939                        static void push( lua_State *L, const rectangle& p ) { detail::push_area( L, p ); }
    4040                        static void pop( lua_State *L, rectangle& p ) { p = detail::to_area( L, -1 ); detail::pop_and_discard( L, 1 ); }
     41                        static rectangle to( lua_State *L, int index ) { return detail::to_area( L, index ); }
    4142                };
    4243        }
  • trunk/nv/lua/lua_glm.hh

    r207 r208  
    4141
    4242                        template< typename T >
     43                        T to_vec( lua_State* L, int index, const T& def )
     44                        {
     45                                return ( is_vec<T>( L, index ) ? *(T*)to_pointer( L, index ) : def );
     46                        }
     47
     48                        template< typename T >
    4349                        T* to_pvec( lua_State* L, int index )
    4450                        {
     
    5864                        typedef glm::detail::tvec2<T> value_type;
    5965                        static void push( lua_State *L, const value_type& p ) { detail::push_vec< value_type >( L, p ); }
    60                         static void pop( lua_State *L, value_type& p ) { p = detail::to_vec< value_type >( L, -1 ); detail::pop_and_discard( L, 1 ); }
     66                        static value_type to( lua_State *L, int index ) { return detail::to_vec< value_type >( L, index ); }
     67                        static value_type to( lua_State *L, int index, const value_type& def ) { return detail::to_vec< value_type >( L, index, def ); }
    6168                };
    6269
     
    6673                        typedef glm::detail::tvec3<T> value_type;
    6774                        static void push( lua_State *L, const value_type& p ) { detail::push_vec< value_type >( L, p ); }
    68                         static void pop( lua_State *L, value_type& p ) { p = detail::to_vec< value_type >( L, -1 ); detail::pop_and_discard( L, 1 ); }
     75                        static value_type to( lua_State *L, int index ) { return detail::to_vec< value_type >( L, index ); }
     76                        static value_type to( lua_State *L, int index, const value_type& def ) { return detail::to_vec< value_type >( L, index, def ); }
    6977                };
    7078
     
    7482                        typedef glm::detail::tvec4<T> value_type;
    7583                        static void push( lua_State *L, const value_type& p ) { detail::push_vec< value_type >( L, p ); }
    76                         static void pop( lua_State *L, value_type& p ) { p = detail::to_vec< value_type >( L, -1 ); detail::pop_and_discard( L, 1 ); }
     84                        static value_type to( lua_State *L, int index ) { return detail::to_vec< value_type >( L, index ); }
     85                        static value_type to( lua_State *L, int index, const value_type& def ) { return detail::to_vec< value_type >( L, index, def ); }
    7786                };
    7887        }
  • trunk/nv/lua/lua_values.hh

    r207 r208  
    88#define NV_LUA_VALUES_HH
    99
    10 #include <type_traits>
    1110#include <nv/common.hh>
     11#include <nv/type_traits.hh>
    1212#include <nv/string.hh>
    1313
     
    1818        namespace lua
    1919        {
    20                 struct passer
     20                typedef ptrdiff_t     linteger;
     21                typedef unsigned long lunsigned;
     22                typedef double        lnumber;
     23
     24                struct passer
    2125                {
    2226                        virtual void push( lua_State *L ) const = 0;
     
    2428                };
    2529
    26                 struct returner_base
    27                 {
    28                         virtual void pop( lua_State *L ) = 0;
    29                         virtual ~returner_base(){}
    30                 };
    31 
    3230                template < typename T >
    33                 struct returner : public returner_base
    34                 {
     31                struct returner
     32                {
     33                        returner( lua_State *, int ) : value() {}
     34                        returner( lua_State *, int, const T& ) : value() {}
    3535                        operator T() { return value; }
    3636                        operator const T() const { return value; }
     37                        virtual returner<T> to( lua_State *L, int index ) = 0;
     38                        virtual returner<T> to( lua_State *L, int index, const T& def ) = 0;
     39                        virtual ~returner(){}
    3740                protected:
    3841                        T value;
     
    4346                {
    4447                        static void push( lua_State *L, const T& p ) { p.push( L ); }
    45                         static void pop( lua_State *L, T& p ) { p.pop( L ); }
     48                        static T to( lua_State *L, int index ) { return T( L, index ); }
     49                        static T to( lua_State *L, int index, const T& def ) { return T( L, index, def ); }
    4650                };
    4751
    4852                namespace detail
    4953                {
    50                         void push_value( lua_State *L, long n );
    51                         void push_value( lua_State *L, double n );
    52                         void push_value( lua_State *L, bool n );
    53                         void push_value( lua_State *L, const std::string& s );
    54                         void push_value( lua_State *L, const char* s );
    55                         void push_value( lua_State *L, object* o );
    56                         void push_value( lua_State *L, void* p );
    57 
    58                         template< typename D >
    59                         typename std::enable_if<std::is_base_of<object, D>::value>::type
    60                                 push_value( lua_State *L, D* o )
    61                         {
    62                                 push_value( L, (object*)o );
    63                         }
     54                        void push_unsigned( lua_State *L, lunsigned v );
     55                        void push_integer ( lua_State *L, linteger v );
     56                        void push_number  ( lua_State *L, lnumber v );
     57                        void push_bool    ( lua_State *L, bool v );
     58                        void push_string  ( lua_State *L, const std::string& s );
     59                        void push_cstring ( lua_State *L, const char* s );
     60                        void push_object  ( lua_State *L, object* o );
     61                        void push_pointer ( lua_State *L, void* p );
     62
     63                        lunsigned   to_unsigned( lua_State *L, int index );
     64                        linteger    to_integer ( lua_State *L, int index );
     65                        lnumber     to_number  ( lua_State *L, int index );
     66                        bool        to_bool    ( lua_State *L, int index );
     67                        std::string to_string  ( lua_State *L, int index );
     68                        const char* to_cstring ( lua_State *L, int index );
     69                        object*     to_object  ( lua_State *L, int index );
     70                        void*       to_pointer ( lua_State *L, int index );
     71
     72                        lunsigned   to_unsigned( lua_State *L, int index, lunsigned def );
     73                        linteger    to_integer ( lua_State *L, int index, linteger def );
     74                        lnumber     to_number  ( lua_State *L, int index, lnumber def );
     75                        bool        to_bool    ( lua_State *L, int index, bool def );
     76                        std::string to_string  ( lua_State *L, int index, const std::string& def );
     77                        const char* to_cstring ( lua_State *L, int index, const char* def );
     78                        object*     to_object  ( lua_State *L, int index, object* def );
     79                        void*       to_pointer ( lua_State *L, int index, void* def );
     80
     81                        void pop_and_discard( lua_State *L, int count );
     82                        bool is_userdata( lua_State *L, int index, const char* metatable );
     83                        void* check_userdata( lua_State *L, int index, const char* metatable );
     84                        void* allocate_userdata( lua_State *L, size_t size, const char* metatable );
     85                        template <typename T>
     86                        void push_userdata( lua_State *L, const T& v, const char* metatable )
     87                        {
     88                                new (allocate_userdata(L, sizeof(T), metatable)) T(v);
     89                        }
     90                }
     91
     92                template <>
     93                struct pass_traits<linteger>
     94                {
     95                        static void push( lua_State *L, linteger s ) { detail::push_integer( L, s ); }
     96                        static linteger to( lua_State *L, int index ) { return detail::to_integer( L, index ); }
     97                        static linteger to( lua_State *L, int index, linteger def ) { return detail::to_integer( L, index, def ); }
     98                };
     99
     100                template <>
     101                struct pass_traits<lunsigned>
     102                {
     103                        static void push( lua_State *L, lunsigned s ) { detail::push_unsigned( L, s ); }
     104                        static lunsigned to( lua_State *L, int index ) { return detail::to_unsigned( L, index ); }
     105                        static lunsigned to( lua_State *L, int index, lunsigned def ) { return detail::to_unsigned( L, index, def ); }
     106                };
     107
     108                template <>
     109                struct pass_traits<lnumber>
     110                {
     111                        static void push( lua_State *L, lnumber s ) { detail::push_number( L, s ); }
     112                        static lnumber to( lua_State *L, int index ) { return detail::to_number( L, index ); }
     113                        static lnumber to( lua_State *L, int index, lnumber def ) { return detail::to_number( L, index, def ); }
     114                };
     115
     116                template <>
     117                struct pass_traits<bool>
     118                {
     119                        static void push( lua_State *L, bool s ) { detail::push_bool( L, s ); }
     120                        static bool to( lua_State *L, int index ) { return detail::to_bool( L, index ); }
     121                        static bool to( lua_State *L, int index, bool def ) { return detail::to_bool( L, index, def ); }
     122                };
     123
     124                template <>
     125                struct pass_traits<const char*>
     126                {
     127                        static void push( lua_State *L, const char* s ) { detail::push_cstring( L, s ); }
     128                        static const char* to( lua_State *L, int index ) { return detail::to_cstring( L, index ); }
     129                        static const char* to( lua_State *L, int index, const char* def ) { return detail::to_cstring( L, index, def ); }
     130                };
     131
     132                template <>
     133                struct pass_traits<std::string>
     134                {
     135                        static void push( lua_State *L, const std::string& s ) { detail::push_string( L, s ); }
     136                        static std::string to( lua_State *L, int index ) { return detail::to_string( L, index ); }
     137                        static std::string to( lua_State *L, int index, const std::string& def ) { return detail::to_string( L, index, def ); }
     138                };
     139
     140                template <>
     141                struct pass_traits<object*>
     142                {
     143                        static void push( lua_State *L, object* o ) { detail::push_object( L, o ); }
     144                        static object* to( lua_State *L, int index ) { return detail::to_object( L, index ); }
     145                        static object* to( lua_State *L, int index, object* def ) { return detail::to_object( L, index, def ); }
     146                };
     147
     148                namespace detail
     149                {
     150
     151                        template <typename T, class ENABLE = void >
     152                        struct type_degrade
     153                        {
     154                                typedef T type;
     155                        };
     156
     157                        template <typename T>
     158                        struct type_degrade< T, typename std::enable_if< std::is_floating_point< T >::value >::type >
     159                        {
     160                                typedef lnumber type;
     161                        };
     162
     163                        template <typename T>
     164                        struct type_degrade< T, typename std::enable_if< std::is_integral< T >::value && std::is_signed< T >::value >::type >
     165                        {
     166                                typedef linteger type;
     167                        };
     168
     169                        template <typename T>
     170                        struct type_degrade< T, typename std::enable_if< std::is_integral< T >::value && std::is_unsigned< T >::value >::type >
     171                        {
     172                                typedef lunsigned type;
     173                        };
     174
     175                        template <typename T>
     176                        struct type_degrade< T, typename std::enable_if< is_cstring< T >::value >::type >
     177                        {
     178                                typedef const char* type;
     179                        };
     180
     181                        template <typename T>
     182                        struct type_degrade< T, typename std::enable_if< is_stdstring< T >::value >::type >
     183                        {
     184                                typedef std::string type;
     185                        };
     186
     187                        template <typename T>
     188                        struct type_degrade< T*, typename std::enable_if< std::is_base_of<object, T >::value >::type >
     189                        {
     190                                typedef object* type;
     191                        };
     192
     193                        template <>
     194                        struct type_degrade< bool >
     195                        {
     196                                typedef bool type;
     197                        };
    64198
    65199                        template < typename T >
    66200                        void push_value( lua_State *L, const T& p )
    67201                        {
    68                                 pass_traits<T>::push( L, p );
     202                                typedef typename type_degrade<T>::type degraded;
     203                                pass_traits<degraded>::push( L, p );
    69204                        }
    70205
     
    80215                        void push_values( lua_State *L, const T1& p1, const T2& p2, const T3& p3, const T4& p4, const T5& p5 ) { push_value( L, p1 ); push_value( L, p2 ); push_value( L, p3 ); push_value( L, p4 ); push_value( L, p5 ); }
    81216
    82                         void pop_value( lua_State *L, int& n );
    83                         void pop_value( lua_State *L, long& n );
    84                         void pop_value( lua_State *L, double& n );
    85                         void pop_value( lua_State *L, bool& n );
    86                         void pop_value( lua_State *L, std::string& s );
    87                         void pop_value( lua_State *L, object*& o );
    88                         void pop_value( lua_State *L, void*& p );
    89217                        template < typename T >
    90218                        inline void pop_value( lua_State *L, T& p )
    91219                        {
    92                                 pass_traits<T>::pop( L, p );
     220                                typedef typename type_degrade<T>::type degraded;
     221                                p = pass_traits<degraded>::to( L, -1 );
     222                                detail::pop_and_discard(L, 1);
    93223                        }
    94224                        template < typename T >
    95225                        inline T pop_return_value( lua_State *L )
    96226                        {
     227                                typedef typename type_degrade<T>::type degraded;
    97228                                T ret;
    98                                 pop_value( L, ret );
     229                                ret = pass_traits<degraded>::to( L, -1 );
     230                                detail::pop_and_discard(L, 1);
    99231                                return ret;
    100232                        }
     
    106238
    107239                        template < typename T >
     240                        inline T get_value( lua_State *L, int index )
     241                        {
     242                                typedef typename type_degrade<T>::type degraded;
     243                                return pass_traits<degraded>::to( L, index );
     244                        }
     245
     246                        template < typename T >
     247                        inline T get_value( lua_State *L, int index, const T& def )
     248                        {
     249                                typedef typename type_degrade<T>::type degraded;
     250                                return pass_traits<degraded>::to( L, index, def );
     251                        }
     252
     253                        template < typename T >
    108254                        struct return_count
    109255                        {
     
    117263                        };
    118264
    119 
    120                         void pop_and_discard( lua_State *L, int count );
    121                         bool is_userdata( lua_State *L, int index, const char* metatable );
    122                         void* check_userdata( lua_State *L, int index, const char* metatable );
    123                         void* allocate_userdata( lua_State *L, size_t size, const char* metatable );
    124                         template <typename T>
    125                         void push_userdata( lua_State *L, const T& v, const char* metatable )
    126                         {
    127                                 new (allocate_userdata(L, sizeof(T), metatable)) T(v);
    128                         }
    129265                }
    130266
  • trunk/nv/type_traits.hh

    r197 r208  
    1818namespace nv
    1919{
     20
     21        // These could be done much better
     22        template <typename T>
     23        struct is_cstring
     24                : public std::integral_constant<bool,
     25                std::is_same<       char *, typename std::decay< T >::type >::value ||
     26                std::is_same< const char *, typename std::decay< T >::type >::value >
     27                {};
     28
     29        template <typename T>
     30        struct is_stdstring
     31                : public std::integral_constant<bool,
     32                std::is_same< std::string, typename std::remove_cv< std::remove_reference< T > >::type >::value
     33                >
     34        {};
     35
     36        template < typename T > struct is_string : public std::integral_constant<bool, is_stdstring<T>::value || is_cstring<T>::value> {};
    2037
    2138        // Just for once, MSVC is the good guy, and everybody else sucks.
  • trunk/src/lua/lua_values.cc

    r207 r208  
    1010#include "nv/object.hh"
    1111
    12 void nv::lua::detail::push_value( lua_State *L, long n )
    13 {
    14         lua_pushinteger( L, n );
    15 }
    16 
    17 void nv::lua::detail::push_value( lua_State *L, double d )
    18 {
    19         lua_pushnumber( L, d );
    20 }
    21 
    22 void nv::lua::detail::push_value( lua_State *L, bool n )
    23 {
    24         lua_pushboolean( L, n );
    25 }
    26 
    27 void nv::lua::detail::push_value( lua_State *L, const char* s )
    28 {
    29         lua_pushstring( L, s );
    30 }
    31 
    32 void nv::lua::detail::push_value( lua_State *L, const std::string& s )
    33 {
    34         lua_pushstring( L, s.c_str() );
    35 }
    36 
    37 void nv::lua::detail::push_value( lua_State *L, object* o )
    38 {
    39         if ( o == nullptr )
    40         {
    41                 lua_pushnil( L );
    42         }
    43         else
    44         {
    45                 lua_rawgeti( L, LUA_REGISTRYINDEX, o->get_lua_index() );
    46         }
    47 }
    48 
    49 void nv::lua::detail::push_value( lua_State *L, void* p )
    50 {
    51         lua_pushlightuserdata( L, p );
    52 }
    53 
    54 void nv::lua::detail::pop_value( lua_State *L, int& n )
    55 {
    56         n = lua_tointeger( L, -1 );
    57         lua_pop( L, 1 );
    58 }
    59 
    60 void nv::lua::detail::pop_value( lua_State *L, long& n )
    61 {
    62         n = lua_tointeger( L, -1 );
    63         lua_pop( L, 1 );
    64 }
    65 
    66 void nv::lua::detail::pop_value( lua_State *L, double& d )
    67 {
    68         d = lua_tonumber( L, -1 );
    69         lua_pop( L, 1 );
    70 }
    71 
    72 void nv::lua::detail::pop_value( lua_State *L, bool& n )
    73 {
    74         n = lua_toboolean( L, -1 ) != 0;
    75         lua_pop( L, 1 );
    76 }
    77 
    78 void nv::lua::detail::pop_value( lua_State *L, std::string& s )
    79 {
    80         s = lua_tostring( L, -1 );
    81         lua_pop( L, 1 );
    82 }
    83 
    84 void nv::lua::detail::pop_value( lua_State *L, object*& o )
    85 {
    86         o = nullptr;
    87         if ( lua_istable( L , -1 ) )
    88         {
    89                 lua_pushstring( L, "__ptr" );
    90                 lua_rawget( L, -1 );
    91                 if ( lua_isuserdata( L, -1 ) )
    92                 {
    93                         o = (object*)( lua_touserdata( L, -1 ) );
    94                 }
    95                 lua_pop( L, 1 );
    96         }
    97         lua_pop( L, 1 );
    98 }
    99 
    100 void nv::lua::detail::pop_value( lua_State *L, void*& p )
    101 {
    102         p = lua_touserdata( L, -1 );
    103         lua_pop( L, 1 );
    104 }
     12using nv::lua::linteger;
     13using nv::lua::lnumber;
     14using nv::lua::lunsigned;
    10515
    10616bool nv::lua::detail::is_userdata( lua_State *L, int index, const char* metatable )
     
    12636}
    12737
     38void nv::lua::detail::push_unsigned( lua_State *L, lunsigned v )
     39{
     40        lua_pushunsigned( L, v );
     41}
     42
     43void nv::lua::detail::push_integer ( lua_State *L, linteger v )
     44{
     45        lua_pushinteger( L, v );
     46}
     47
     48void nv::lua::detail::push_number  ( lua_State *L, lnumber v )
     49{
     50        lua_pushnumber( L, v );
     51}
     52
     53void nv::lua::detail::push_bool    ( lua_State *L, bool v )
     54{
     55        lua_pushboolean( L, v );
     56}
     57
     58void nv::lua::detail::push_string  ( lua_State *L, const std::string& s )
     59{
     60        lua_pushlstring( L, s.c_str(), s.size() );
     61}
     62
     63void nv::lua::detail::push_cstring ( lua_State *L, const char* s )
     64{
     65        lua_pushstring( L, s );
     66}
     67
     68void nv::lua::detail::push_object  ( lua_State *L, object* o )
     69{
     70        if ( o == nullptr )
     71        {
     72                lua_pushnil( L );
     73        }
     74        else
     75        {
     76                lua_rawgeti( L, LUA_REGISTRYINDEX, o->get_lua_index() );
     77        }
     78}
     79
     80void nv::lua::detail::push_pointer ( lua_State *L, void* p )
     81{
     82        lua_pushlightuserdata( L, p );
     83}
     84
     85lunsigned   nv::lua::detail::to_unsigned( lua_State *L, int index )
     86{
     87        return lua_tounsigned( L, index );
     88}
     89
     90linteger    nv::lua::detail::to_integer ( lua_State *L, int index )
     91{
     92        return lua_tointeger( L, index );
     93}
     94
     95lnumber     nv::lua::detail::to_number  ( lua_State *L, int index )
     96{
     97        return lua_tonumber( L, index );
     98}
     99
     100bool        nv::lua::detail::to_bool    ( lua_State *L, int index )
     101{
     102        return lua_toboolean( L, index ) != 0;
     103}
     104
     105std::string nv::lua::detail::to_string  ( lua_State *L, int index )
     106{
     107        return lua_tostring( L, index );
     108}
     109
     110const char* nv::lua::detail::to_cstring ( lua_State *L, int index )
     111{
     112        return lua_tostring( L, index );
     113}
     114
     115nv::object* nv::lua::detail::to_object  ( lua_State *L, int index )
     116{
     117        object* o = nullptr;
     118        if ( lua_istable( L , index ) )
     119        {
     120                lua_pushstring( L, "__ptr" );
     121                lua_rawget( L, index );
     122                if ( lua_isuserdata( L, -1 ) )
     123                {
     124                        o = static_cast<object*>( lua_touserdata( L, -1 ) );
     125                }
     126                lua_pop( L, 1 );
     127        }
     128        return o;
     129}
     130
     131void*       nv::lua::detail::to_pointer ( lua_State *L, int index )
     132{
     133        return lua_touserdata( L, index );
     134}
     135
     136lunsigned   nv::lua::detail::to_unsigned( lua_State *L, int index, lunsigned def )
     137{
     138        return ( lua_type( L, index ) == LUA_TNUMBER ? lua_tounsigned( L, index ) : def );
     139}
     140
     141linteger    nv::lua::detail::to_integer ( lua_State *L, int index, linteger def )
     142{
     143        return ( lua_type( L, index ) == LUA_TNUMBER ? lua_tointeger( L, index ) : def );
     144}
     145
     146lnumber     nv::lua::detail::to_number  ( lua_State *L, int index, lnumber def )
     147{
     148        return ( lua_type( L, index ) == LUA_TNUMBER ? lua_tonumber( L, index ) : def );
     149}
     150
     151bool        nv::lua::detail::to_bool    ( lua_State *L, int index, bool def )
     152{
     153        return ( lua_type( L, index ) == LUA_TBOOLEAN ? lua_toboolean( L, index ) != 0 : def );
     154}
     155
     156std::string nv::lua::detail::to_string  ( lua_State *L, int index, const std::string& def )
     157{
     158        return ( lua_type( L, index ) == LUA_TSTRING ? lua_tostring( L, index ) : def );
     159}
     160
     161const char* nv::lua::detail::to_cstring ( lua_State *L, int index, const char* def )
     162{
     163        return ( lua_type( L, index ) == LUA_TSTRING ? lua_tostring( L, index ) : def );
     164}
     165
     166nv::object* nv::lua::detail::to_object  ( lua_State *L, int index, nv::object* def )
     167{
     168        object* o = def;
     169        if ( lua_istable( L , index ) )
     170        {
     171                lua_pushstring( L, "__ptr" );
     172                lua_rawget( L, index );
     173                if ( lua_isuserdata( L, -1 ) )
     174                {
     175                        o = static_cast<object*>( lua_touserdata( L, -1 ) );
     176                }
     177                lua_pop( L, 1 );
     178        }
     179        return o;
     180}
     181
     182void*       nv::lua::detail::to_pointer ( lua_State *L, int index, void* def )
     183{
     184        return ( lua_type( L, index ) == LUA_TUSERDATA ? lua_touserdata( L, index ) : def );
     185}
Note: See TracChangeset for help on using the changeset viewer.