Ignore:
Timestamp:
08/19/13 06:37:47 (12 years ago)
Author:
epyon
Message:
  • lua - major refactoring of the lua state/table
  • lua - added state_wrapper common to state/table
  • lua_values - fixed returning of simple types
  • lua_area - fixed area.coords and area.edges
  • lua_map_area - "fixed" case when object is used as base
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lua/lua_state.cc

    r204 r206  
    1616
    1717lua::stack_guard::stack_guard( lua::state* aL )
    18         : L(aL), m_level( lua_gettop(aL->L) )
     18        : L(aL), m_level( lua_gettop(aL->m_state) )
    1919{
    2020
     
    2222
    2323lua::stack_guard::stack_guard( lua::state& aL )
    24         : L(&aL), m_level( lua_gettop(aL.L) )
     24        : L(&aL), m_level( lua_gettop(aL.m_state) )
    2525{
    2626
     
    2929lua::stack_guard::~stack_guard()
    3030{
    31         lua_settop( L->L, m_level );
    32 }
    33 
    34 lua::state::state( bool load_libs /*= false*/ )
     31        lua_settop( L->m_state, m_level );
     32}
     33
     34lua::state::state( lua_State* state ) : state_wrapper( state, false )
     35{
     36
     37}
     38
     39lua::state::state( bool load_libs /*= false*/ ) : state_wrapper( nullptr, true )
    3540{
    3641        load_lua_library();
    3742        m_owner = true;
    38         L = luaL_newstate( );
    39 
    40         lua_pushcfunction(L, luaopen_base);
    41         lua_pushliteral(L, LUA_TABLIBNAME);
    42         lua_call(L, 1, 0);
     43        m_state = luaL_newstate( );
     44
     45        lua_pushcfunction(m_state, luaopen_base);
     46        lua_pushliteral(m_state, LUA_TABLIBNAME);
     47        lua_call(m_state, 1, 0);
    4348
    4449        if ( load_libs )
     
    5560                for(; lib->func != NULL; lib++)
    5661                {
    57                         lib->func( L );
     62                        lib->func( m_state );
    5863                }
    5964        }
     
    6570{
    6671        NV_LOG( nv::LOG_TRACE, "Loading Lua string '" << name << "'");
    67         return luaL_loadbuffer( L, code.c_str(), code.length(), name.c_str() );
     72        return luaL_loadbuffer( m_state, code.c_str(), code.length(), name.c_str() );
    6873}
    6974
     
    7984{
    8085        NV_LOG( nv::LOG_NOTICE, "Loading Lua file '" << filename << "'");
    81         return luaL_loadfile( L, filename.c_str() );
     86        return luaL_loadfile( m_state, filename.c_str() );
    8287}
    8388
     
    8893        if (result)
    8994        {
    90                 NV_LOG( nv::LOG_WARNING, "Failed to load string " << name << ": " << lua_tostring(L, -1));
     95                NV_LOG( nv::LOG_WARNING, "Failed to load string " << name << ": " << lua_tostring(m_state, -1));
    9196                return false;
    9297        }
     
    100105        if (result)
    101106        {
    102                 NV_LOG( nv::LOG_WARNING, "Failed to open stream " << name << ": " << lua_tostring(L, -1));
     107                NV_LOG( nv::LOG_WARNING, "Failed to open stream " << name << ": " << lua_tostring(m_state, -1));
    103108                return false;
    104109        }
     
    112117        if (result)
    113118        {
    114                 NV_LOG( nv::LOG_WARNING, "Failed to open file " << filename << ": " << lua_tostring(L, -1));
     119                NV_LOG( nv::LOG_WARNING, "Failed to open file " << filename << ": " << lua_tostring(m_state, -1));
    115120                return false;
    116121        }
     
    120125int lua::state::do_current( const std::string& name, int rvalues )
    121126{
    122         int result = lua_pcall(L, 0, rvalues, 0);
     127        int result = lua_pcall(m_state, 0, rvalues, 0);
    123128        if (result)
    124129        {
    125                 NV_LOG( nv::LOG_WARNING, "Failed to run script " << name << ": " << lua_tostring(L, -1));
    126                 lua_pop( L, 1 );
    127         }
    128         return result;
    129 }
    130 
    131 lua::state::~state()
     130                NV_LOG( nv::LOG_WARNING, "Failed to run script " << name << ": " << lua_tostring(m_state, -1));
     131                lua_pop( m_state, 1 );
     132        }
     133        return result;
     134}
     135
     136lua::state_wrapper::~state_wrapper()
    132137{
    133138        if (m_owner)
    134139        {
    135                 lua_close( L );
     140                lua_close( m_state );
    136141        }
    137142}
     
    145150                if (global)
    146151                {
    147                         lua_getglobal( L, path.c_str() );
     152                        lua_getglobal( m_state, path.c_str() );
    148153                }
    149154                else
    150155                {
    151                         lua_getfield( L, -1, path.c_str() );
    152                 }
    153                 return !lua_isnil( L, -1 );
     156                        lua_getfield( m_state, -1, path.c_str() );
     157                }
     158                return !lua_isnil( m_state, -1 );
    154159        }
    155160
     
    163168                        if (global)
    164169                        {
    165                                 lua_getglobal( L, path.substr(start,point-start).c_str() );
     170                                lua_getglobal( m_state, path.substr(start,point-start).c_str() );
    166171                        }
    167172                        else
    168173                        {
    169                                 lua_getfield( L, -1, path.substr(start,point-start).c_str() );
     174                                lua_getfield( m_state, -1, path.substr(start,point-start).c_str() );
    170175                        }
    171176                }
    172177                else
    173178                {
    174                         if ( lua_istable( L, -1 ) )
     179                        if ( lua_istable( m_state, -1 ) )
    175180                        {
    176                                 lua_pushstring( L, path.substr(start,point-start).c_str() );
    177                                 lua_gettable( L, -2 );
    178                                 lua_insert( L, -2 );
    179                                 lua_pop( L, 1 );
     181                                lua_pushstring( m_state, path.substr(start,point-start).c_str() );
     182                                lua_gettable( m_state, -2 );
     183                                lua_insert( m_state, -2 );
     184                                lua_pop( m_state, 1 );
    180185                        }
    181186                        else
    182187                        {
    183                                 lua_pop(L, 1);
    184                                 lua_pushnil(L);
     188                                lua_pop(m_state, 1);
     189                                lua_pushnil(m_state);
    185190                                return false;
    186191                        }
     
    195200int lua::state::get_stack_size()
    196201{
    197         return lua_gettop( L );
     202        return lua_gettop( m_state );
    198203}
    199204
    200205lua::table_guard::table_guard( lua::state* lstate, const path& p, bool global )
    201         : L(lstate), m_guard(lstate)
    202 {
    203         if ( !p.resolve( L->get_raw(), global ) )
     206        : state_wrapper( lstate->get_raw(), false ), m_level(0)
     207{
     208        m_global = false;
     209        m_level  = lua_gettop( m_state );
     210        if ( !p.resolve( m_state, global ) )
    204211        {
    205212                // TODO : error handling
     
    208215
    209216lua::table_guard::table_guard( const table_guard& parent, const path& p )
    210         : L( parent.L ), m_guard( parent.L )
    211 {
    212         if ( !p.resolve( L->get_raw(), false ) )
     217        : state_wrapper( parent.m_state, false ), m_level(0)
     218{
     219        m_global = false;
     220        m_level  = lua_gettop( m_state );
     221        if ( !p.resolve( m_state, false ) )
    213222        {
    214223                // TODO : error handling
     
    218227size_t lua::table_guard::get_size()
    219228{
    220         return lua_rawlen( L->get_raw(), -1 );
     229        return lua_rawlen( m_state, -1 );
    221230}
    222231
     
    224233bool lua::table_guard::has_field( const string& element )
    225234{
    226         lua_getfield( L->L, -1, element.c_str() );
    227         bool result = lua_isnil( L->L, -1 );
    228         lua_pop( L->L, 1 );
     235        lua_getfield( m_state, -1, element.c_str() );
     236        bool result = lua_isnil( m_state, -1 );
     237        lua_pop( m_state, 1 );
    229238        return result;
    230239}
     
    232241string lua::table_guard::get_string( const string& element, const string& defval /*= "" */ )
    233242{
    234         lua_getfield( L->L, -1, element.c_str() );
    235         string result( ( lua_type( L->L, -1 ) == LUA_TSTRING ) ? lua_tostring( L->L, -1 ) : defval );
    236         lua_pop( L->L, 1 );
     243        lua_getfield( m_state, -1, element.c_str() );
     244        string result( ( lua_type( m_state, -1 ) == LUA_TSTRING ) ? lua_tostring( m_state, -1 ) : defval );
     245        lua_pop( m_state, 1 );
    237246        return result;
    238247}
     
    240249char lua::table_guard::get_char( const string& element, char defval /*= "" */ )
    241250{
    242         lua_getfield( L->L, -1, element.c_str() );
    243         char result = ( lua_type( L->L, -1 ) == LUA_TSTRING && lua_rawlen( L->L, -1 ) > 0 ) ? lua_tostring( L->L, -1 )[0] : defval;
    244         lua_pop( L->L, 1 );
     251        lua_getfield( m_state, -1, element.c_str() );
     252        char result = ( lua_type( m_state, -1 ) == LUA_TSTRING && lua_rawlen( m_state, -1 ) > 0 ) ? lua_tostring( m_state, -1 )[0] : defval;
     253        lua_pop( m_state, 1 );
    245254        return result;
    246255}
     
    248257int lua::table_guard::get_integer( const string& element, int defval /*= "" */ )
    249258{
    250         lua_getfield( L->L, -1, element.c_str() );
    251         lua_Integer result = lua_type( L->L, -1 ) == LUA_TNUMBER ? lua_tointeger( L->L, -1 ) : defval;
    252         lua_pop( L->L, 1 );
     259        lua_getfield( m_state, -1, element.c_str() );
     260        lua_Integer result = lua_type( m_state, -1 ) == LUA_TNUMBER ? lua_tointeger( m_state, -1 ) : defval;
     261        lua_pop( m_state, 1 );
    253262        return static_cast< int >( result );
    254263}
     
    256265unsigned lua::table_guard::get_unsigned( const string& element, unsigned defval /*= "" */ )
    257266{
    258         lua_getfield( L->L, -1, element.c_str() );
    259         unsigned result = lua_type( L->L, -1 ) == LUA_TNUMBER ? lua_tounsigned( L->L, -1 ) : defval;
    260         lua_pop( L->L, 1 );
     267        lua_getfield( m_state, -1, element.c_str() );
     268        unsigned result = lua_type( m_state, -1 ) == LUA_TNUMBER ? lua_tounsigned( m_state, -1 ) : defval;
     269        lua_pop( m_state, 1 );
    261270        return result;
    262271}
     
    264273double lua::table_guard::get_double( const string& element, double defval /*= "" */ )
    265274{
    266         lua_getfield( L->L, -1, element.c_str() );
    267         double result = lua_type( L->L, -1 ) == LUA_TNUMBER ? lua_tonumber( L->L, -1 ) : defval;
    268         lua_pop( L->L, 1 );
     275        lua_getfield( m_state, -1, element.c_str() );
     276        double result = lua_type( m_state, -1 ) == LUA_TNUMBER ? lua_tonumber( m_state, -1 ) : defval;
     277        lua_pop( m_state, 1 );
    269278        return result;
    270279}
     
    272281bool lua::table_guard::get_boolean( const string& element, bool defval /*= "" */ )
    273282{
    274         lua_getfield( L->L, -1, element.c_str() );
    275         bool result = lua_type( L->L, -1 ) == LUA_TBOOLEAN ? lua_toboolean( L->L, -1 ) != 0 : defval;
    276         lua_pop( L->L, 1 );
    277         return result;
    278 }
    279 
    280 void lua::table_guard::call_get()
    281 {
    282         lua_gettable( L->L, -2 );
    283 }
    284 
    285 void lua::table_guard::call_get_raw()
    286 {
    287         lua_rawget( L->L, -2 );
    288 }
    289 
    290 bool nv::lua::table_guard::is_defined( const path& p )
    291 {
    292         return L->is_defined( p, false );
     283        lua_getfield( m_state, -1, element.c_str() );
     284        bool result = lua_type( m_state, -1 ) == LUA_TBOOLEAN ? lua_toboolean( m_state, -1 ) != 0 : defval;
     285        lua_pop( m_state, 1 );
     286        return result;
     287}
     288
     289void nv::lua::state_wrapper::push_global_table()
     290{
     291        lua_pushglobaltable( m_state );
     292}
     293
     294void nv::lua::state_wrapper::pop_global_table()
     295{
     296        lua_replace( m_state, -2 );
     297}
     298
     299void lua::state_wrapper::call_get()
     300{
     301        lua_gettable( m_state, -2 );
     302}
     303
     304void lua::state_wrapper::call_get_raw()
     305{
     306        lua_rawget( m_state, -2 );
    293307}
    294308
    295309void lua::table_guard::get_raw_flags( const std::string& element, uint8* data, uint32 count )
    296310{
    297         lua_getfield( L->L, -1, element.c_str() );
    298         if ( lua_type( L->L, -1 ) != LUA_TTABLE )
    299         {
    300                 lua_pop( L->L, 1 );
     311        lua_getfield( m_state, -1, element.c_str() );
     312        if ( lua_type( m_state, -1 ) != LUA_TTABLE )
     313        {
     314                lua_pop( m_state, 1 );
    301315                return;
    302316        }
    303         nlua_toflags( L->L, -1, data, count );
    304         lua_pop( L->L, 1 );
     317        nlua_toflags( m_state, -1, data, count );
     318        lua_pop( m_state, 1 );
    305319}
    306320
     
    308322void lua::state::log_stack()
    309323{
    310         int top = lua_gettop(L);
     324        int top = lua_gettop(m_state);
    311325        NV_LOG( LOG_DEBUG, "Stack dump (" << top << ")");
    312326        for ( int i = 0; i < top; ++i )
    313327        {
    314                 NV_LOG( LOG_DEBUG, "#" << i+1 << " - " << lua_typename(L, lua_type(L, i+1) ) << " = " << nlua_typecontent(L, i+1) );
     328                NV_LOG( LOG_DEBUG, "#" << i+1 << " - " << lua_typename(m_state, lua_type(m_state, i+1) ) << " = " << nlua_typecontent(m_state, i+1) );
    315329        }
    316330}
     
    318332lua_State* lua::state::get_raw()
    319333{
    320         return L;
     334        return m_state;
    321335}
    322336
     
    325339        if ( o == nullptr ) return ref_none;
    326340        stack_guard guard( this );
    327         lua_getglobal( L, lua_name );
    328         if ( lua_isnil( L, -1 ) )
     341        lua_getglobal( m_state, lua_name );
     342        if ( lua_isnil( m_state, -1 ) )
    329343        {
    330344                NV_THROW( runtime_error, std::string( lua_name ) + " type not registered!" );
    331345        }
    332346        deep_pointer_copy( -1, o );
    333         return luaL_ref( L, LUA_REGISTRYINDEX );
     347        return luaL_ref( m_state, LUA_REGISTRYINDEX );
    334348}
    335349
     
    348362        if (!o) return;
    349363        stack_guard guard( this );
    350         lua_rawgeti( L, LUA_REGISTRYINDEX, o->get_lua_index() );
    351         lua_pushstring( L, "__ptr" );
    352         lua_pushboolean( L, false );
    353         lua_rawset( L, -3 );
    354         lua_pop( L, 1 );
    355         luaL_unref( L, LUA_REGISTRYINDEX, o->get_lua_index() );
     364        lua_rawgeti( m_state, LUA_REGISTRYINDEX, o->get_lua_index() );
     365        lua_pushstring( m_state, "__ptr" );
     366        lua_pushboolean( m_state, false );
     367        lua_rawset( m_state, -3 );
     368        lua_pop( m_state, 1 );
     369        luaL_unref( m_state, LUA_REGISTRYINDEX, o->get_lua_index() );
    356370}
    357371
    358372void lua::state::deep_pointer_copy( int index, void* obj )
    359373{
    360         index = lua_absindex( L, index );
    361         lua_newtable( L );
    362         lua_pushnil( L );
     374        index = lua_absindex( m_state, index );
     375        lua_newtable( m_state );
     376        lua_pushnil( m_state );
    363377        bool has_functions = false;
    364378        bool has_metatable = false;
    365379
    366         while ( lua_next( L, index ) != 0 )
    367         {
    368                 if ( lua_isfunction( L, -1 ) )
     380        while ( lua_next( m_state, index ) != 0 )
     381        {
     382                if ( lua_isfunction( m_state, -1 ) )
    369383                        has_functions = true;
    370                 else if ( lua_istable( L, -1 ) )
     384                else if ( lua_istable( m_state, -1 ) )
    371385                {
    372386                        deep_pointer_copy( -1, obj );
    373                         lua_insert( L, -2 );
    374                         lua_pop( L, 1 );
    375                 }
    376                 lua_pushvalue( L, -2 );
    377                 lua_insert( L, -2 );
    378                 lua_settable( L, -4 );
    379         }
    380 
    381         if ( lua_getmetatable( L, -2 ) )
    382         {
    383                 lua_setmetatable( L, -2 );
     387                        lua_insert( m_state, -2 );
     388                        lua_pop( m_state, 1 );
     389                }
     390                lua_pushvalue( m_state, -2 );
     391                lua_insert( m_state, -2 );
     392                lua_settable( m_state, -4 );
     393        }
     394
     395        if ( lua_getmetatable( m_state, -2 ) )
     396        {
     397                lua_setmetatable( m_state, -2 );
    384398                has_metatable = true;
    385399        }
     
    387401        if ( has_functions || has_metatable )
    388402        {
    389                 lua_pushstring( L, "__ptr" );
    390                 lua_pushlightuserdata( L, obj );
    391                 lua_rawset( L, -3 );
     403                lua_pushstring( m_state, "__ptr" );
     404                lua_pushlightuserdata( m_state, obj );
     405                lua_rawset( m_state, -3 );
    392406        }
    393407}
     
    399413        for ( const auto& entry : et->enum_list )
    400414        {
    401                 lua_pushinteger( L, entry.value );
     415                lua_pushinteger( m_state, entry.value );
    402416                if ( prefix.empty() )
    403417                {
    404                         lua_setglobal( L, entry.name.c_str() );
     418                        lua_setglobal( m_state, entry.name.c_str() );
    405419                }
    406420                else
    407421                {
    408                         lua_setglobal( L, ( prefix + entry.name ).c_str() );
    409                 }
    410         }
    411 }
    412 
    413 
    414 bool nv::lua::state::is_defined( const path& p, bool global )
    415 {
    416         if ( !p.resolve( L, global ) )
    417         {
    418                 return false;
    419         }
    420         bool result = !lua_isnil( L, -1 );
    421         lua_pop( L, 1 );
    422         return result;
    423 }
    424 
    425 int lua::state::call_function( int nargs, int nresults )
    426 {
    427         int status = lua_pcall( L, nargs, nresults, 0 );
     422                        lua_setglobal( m_state, ( prefix + entry.name ).c_str() );
     423                }
     424        }
     425}
     426
     427void nv::lua::state::store_metadata( object* o, const std::string& metaname, void* pointer )
     428{
     429        if (!o) return;
     430        stack_guard guard( this );
     431        lua_rawgeti( m_state, LUA_REGISTRYINDEX, o->get_lua_index() );
     432        lua_pushstring( m_state, metaname.c_str() );
     433        lua_pushlightuserdata( m_state, pointer );
     434        lua_rawset( m_state, -3 );
     435        lua_pop( m_state, 1 );
     436}
     437
     438bool nv::lua::state_wrapper::is_defined( const path& p, bool global )
     439{
     440        if ( !p.resolve( m_state, global ) )
     441        {
     442                return false;
     443        }
     444        bool result = !lua_isnil( m_state, -1 );
     445        lua_pop( m_state, 1 );
     446        return result;
     447}
     448
     449bool nv::lua::state_wrapper::push_function( const path& p, bool global )
     450{
     451        if ( !p.resolve( m_state, global ) )
     452        {
     453                NV_LOG( LOG_ERROR, "Lua error : not a valid path - " + p.to_string() );
     454                return false;
     455        }
     456
     457        if ( !lua_isfunction( m_state, -1 ) )
     458        {
     459                lua_pop( m_state, 1 );
     460                NV_LOG( LOG_ERROR, "Lua error : not a valid function - " + p.to_string() );
     461                return false;
     462        }
     463        return true;
     464}
     465
     466int nv::lua::state_wrapper::call_function( int nargs, int nresults )
     467{
     468        int status = lua_pcall( m_state, nargs, nresults, 0 );
    428469        if ( status != 0 )
    429470        {
    430                 std::string error = lua_tostring( L, -1 );
    431                 lua_pop( L, 1 );
     471                std::string error = lua_tostring( m_state, -1 );
     472                lua_pop( m_state, 1 );
    432473                NV_LOG( LOG_ERROR, "Lua error : " << error )
    433474        }
     
    435476}
    436477
    437 bool lua::state::push_function( const path& p, bool global )
    438 {
    439         if ( !p.resolve( L, global ) )
    440         {
    441                 NV_LOG( LOG_ERROR, "Lua error : not a valid path - " + p.to_string() );
    442                 return false;
    443         }
    444 
    445         if ( !lua_isfunction( L, -1 ) )
    446         {
    447                 lua_pop( L, 1 );
    448                 NV_LOG( LOG_ERROR, "Lua error : not a valid function - " + p.to_string() );
    449                 return false;
    450         }
    451         return true;
    452 }
    453 
     478lua::table_guard::~table_guard()
     479{
     480        lua_settop( m_state, m_level );
     481}
Note: See TracChangeset for help on using the changeset viewer.