Changeset 185


Ignore:
Timestamp:
08/03/13 04:40:16 (12 years ago)
Author:
epyon
Message:
  • lua/state - call any function with any param count and any return value
  • lua/table_guard - call any table/subtable function with any param count and any return value
  • lua/function fix
Location:
trunk
Files:
4 edited

Legend:

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

    r182 r185  
    9292                inline void function<void>::call_result<void>( int params )
    9393                {
    94                         call( params, 1 );
     94                        call( params, 0 );
    9595                }
    9696
  • trunk/nv/lua/lua_state.hh

    r181 r185  
    44// This file is part of NV Libraries.
    55// For conditions of distribution and use, see copyright notice in nv.hh
     6//
     7// TODO: the call() templates are copied over in table/state - can we get around that?
    68
    79#ifndef NV_LUA_HH
     
    1315#include <nv/flags.hh>
    1416#include <nv/lua/lua_path.hh>
     17#include <nv/lua/lua_values.hh>
    1518#include <string>
    1619
     
    5255                        bool get_boolean( const std::string& element, bool defval = false );
    5356
     57                        template< typename R, typename T >
     58                        R get( const T& key )
     59                        {
     60                                detail::push_value( L->L, key );
     61                                call_get();
     62                                return detail::pop_return_value( L->L )
     63                        }
     64
     65                        template< typename R, typename T >
     66                        R raw_get( const T& key )
     67                        {
     68                                detail::push_value( L->L, key );
     69                                call_get_raw();
     70                                return detail::pop_return_value( L->L )
     71                        }
     72
    5473                        template< uint32 SIZE, typename T >
    5574                        flags< SIZE, T > get_flags( const std::string& element )
     
    6584                                get_raw_flags( element, flags.data(), flags.size() );
    6685                        }
    67                 private:
     86
     87                        template < typename R >
     88                        R call( const path& p )
     89                        {
     90                                if ( L->push_function( p, false ) )
     91                                {
     92                                        if ( call_function( 0, detail::return_count< R >::value ) == 0 )
     93                                        {
     94                                                return detail::pop_return_value<R>( L );
     95                                        }
     96                                }
     97                                return R();
     98                        }
     99                        template < typename R, typename T1 >
     100                        R call( const path& p, const T1& p1 )
     101                        {
     102                                if ( L->push_function( p, false ) )
     103                                {
     104                                        detail::push_value( L, p1 );
     105                                        if ( L->call_function( 1, detail::return_count< R >::value ) == 0 )
     106                                        {
     107                                                return detail::pop_return_value<R>( L );
     108                                        }
     109                                }
     110                                return R();
     111                        }
     112                        template < typename R, typename T1, typename T2 >
     113                        R call( const path& p, const T1& p1, const T2& p2 )
     114                        {
     115                                if ( L->push_function( p, false ) )
     116                                {
     117                                        detail::push_values( L, p1, p2 );
     118                                        if ( L->call_function( 2, detail::return_count< R >::value ) == 0 )
     119                                        {
     120                                                return detail::pop_return_value<R>( L );
     121                                        }
     122                                }
     123                                return R();
     124                        }
     125                        template < typename R, typename T1, typename T2, typename T3 >
     126                        R call( const path& p, const T1& p1, const T2& p2, const T3& p3 )
     127                        {
     128                                if ( L->push_function( p, false ) )
     129                                {
     130                                        detail::push_values( L, p1, p2, p3 );
     131                                        if ( L->call_function( 3, detail::return_count< R >::value ) == 0 )
     132                                        {
     133                                                return detail::pop_return_value<R>( L );
     134                                        }
     135                                }
     136                                return R();
     137                        }
     138                        template < typename R, typename T1, typename T2, typename T3, typename T4 >
     139                        R call( const path& p, const T1& p1, const T2& p2, const T3& p3, const T4& p4 )
     140                        {
     141                                if ( L->push_function( p, false ) )
     142                                {
     143                                        detail::push_value( L, p1, p2, p3, p4 );
     144                                        if ( L->call_function( 4, detail::return_count< R >::value ) == 0 )
     145                                        {
     146                                                return detail::pop_return_value<R>( L );
     147                                        }
     148                                }
     149                                return R();
     150                        }
     151
     152                private:
     153                        bool push_function( const path& p );
     154                        int call_function( int nargs, int nresults );
     155                        void call_get();
     156                        void call_get_raw();
    68157                        void get_raw_flags( const std::string& element, uint8* data, uint32 count );
    69158
     
    90179                        operator lua_State*() { return L; }
    91180                        ~state();
    92                 private:
     181
     182                        template < typename R >
     183                        R call( const path& p )
     184                        {
     185                                if ( push_function( p ) )
     186                                {
     187                                        if ( call_function( 0, detail::return_count< R >::value ) == 0 )
     188                                        {
     189                                                return detail::pop_return_value<R>( L );
     190                                        }
     191                                }
     192                                return R();
     193                        }
     194                        template < typename R, typename T1 >
     195                        R call( const path& p, const T1& p1 )
     196                        {
     197                                if ( push_function( p ) )
     198                                {
     199                                        detail::push_value( L, p1 );
     200                                        if ( call_function( 1, detail::return_count< R >::value ) == 0 )
     201                                        {
     202                                                return detail::pop_return_value<R>( L );
     203                                        }
     204                                }
     205                                return R();
     206                        }
     207                        template < typename R, typename T1, typename T2 >
     208                        R call( const path& p, const T1& p1, const T2& p2 )
     209                        {
     210                                if ( push_function( p ) )
     211                                {
     212                                        detail::push_values( L, p1, p2 );
     213                                        if ( call_function( 2, detail::return_count< R >::value ) == 0 )
     214                                        {
     215                                                return detail::pop_return_value<R>( L );
     216                                        }
     217                                }
     218                                return R();
     219                        }
     220                        template < typename R, typename T1, typename T2, typename T3 >
     221                        R call( const path& p, const T1& p1, const T2& p2, const T3& p3 )
     222                        {
     223                                if ( push_function( p ) )
     224                                {
     225                                        detail::push_values( L, p1, p2, p3 );
     226                                        if ( call_function( 3, detail::return_count< R >::value ) == 0 )
     227                                        {
     228                                                return detail::pop_return_value<R>( L );
     229                                        }
     230                                }
     231                                return R();
     232                        }
     233                        template < typename R, typename T1, typename T2, typename T3, typename T4 >
     234                        R call( const path& p, const T1& p1, const T2& p2, const T3& p3, const T4& p4 )
     235                        {
     236                                if ( push_function( p ) )
     237                                {
     238                                        detail::push_value( L, p1, p2, p3, p4 );
     239                                        if ( call_function( 4, detail::return_count< R >::value ) == 0 )
     240                                        {
     241                                                return detail::pop_return_value<R>( L );
     242                                        }
     243                                }
     244                                return R();
     245                        }
     246
     247                private:
     248                        bool push_function( const path& p, bool global = true );
     249                        int call_function( int nargs, int nresults );
    93250                        int load_string( const std::string& code, const std::string& name );
    94251                        int load_stream( std::istream& stream, const std::string& name );
  • trunk/nv/lua/lua_values.hh

    r183 r185  
    7676                        void pop_value( lua_State *L, void*& p );
    7777                        template < typename T >
    78                         void pop_value( lua_State *L, T& p )
     78                        inline void pop_value( lua_State *L, T& p )
    7979                        {
    8080                                pass_traits<T>::pop( L, p );
    8181                        }
     82                        template < typename T >
     83                        inline T pop_return_value( lua_State *L )
     84                        {
     85                                T ret;
     86                                pass_traits<T>::pop( L, ret );
     87                                return ret;
     88                        }
     89
     90                        template <>
     91                        inline void pop_return_value<void>( lua_State* )
     92                        {
     93                        }
     94
     95                        template < typename T >
     96                        struct return_count
     97                        {
     98                                const static int value = 1;
     99                        };
     100
     101                        template <>
     102                        struct return_count<void>
     103                        {
     104                                const static int value = 0;
     105                        };
    82106                }
    83107
  • trunk/src/lua/lua_state.cc

    r181 r185  
    264264}
    265265
     266void lua::table_guard::call_get()
     267{
     268        lua_gettable( L->L, -2 );
     269}
     270
     271void lua::table_guard::call_get_raw()
     272{
     273        lua_rawget( L->L, -2 );
     274}
     275
     276
    266277void lua::table_guard::get_raw_flags( const std::string& element, uint8* data, uint32 count )
    267278{
     
    375386        }
    376387}
     388
     389int lua::state::call_function( int nargs, int nresults )
     390{
     391        int status = lua_pcall( L, nargs, nresults, 0 );
     392        if ( status != 0 )
     393        {
     394                std::string error = lua_tostring( L, -1 );
     395                lua_pop( L, 1 );
     396                NV_LOG( LOG_ERROR, "Lua error : " << error )
     397        }
     398        return status;
     399}
     400
     401bool lua::state::push_function( const path& p, bool global )
     402{
     403        if ( !p.resolve( L, global ) )
     404        {
     405                lua_pop( L, 1 );
     406                NV_LOG( LOG_ERROR, "Lua error : not a valid path - " + p.to_string() );
     407                return false;
     408        }
     409
     410        if ( !lua_isfunction( L, -1 ) )
     411        {
     412                lua_pop( L, 1 );
     413                NV_LOG( LOG_ERROR, "Lua error : not a valid function - " + p.to_string() );
     414                return false;
     415        }
     416        return true;
     417}
Note: See TracChangeset for help on using the changeset viewer.