Changeset 77


Ignore:
Timestamp:
06/01/13 22:47:44 (12 years ago)
Author:
epyon
Message:
  • types - typemap based on type_index, allowing type retrival by typeid
  • object - autoinitialization of uid and lua_index, based on root's capabilities
  • object - proper cleanup of uid and lua_index
  • object - root accessor
  • lua_state - implementation of register_object and unregister_object
Location:
trunk
Files:
6 edited

Legend:

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

    r74 r77  
    7272                        void log_stack();
    7373                        lua_State* get_raw();
     74                        reference register_object( object * o );
     75                        void unregister_object( object * o );
    7476                        ~state();
    7577                private:
    7678                        int do_current( const std::string& name );
    7779                        bool push( const std::string& path, bool global = true );
     80                        void deep_pointer_copy( int index, void* obj );
    7881                private:
    7982                        bool m_owner;
  • trunk/nv/object.hh

    r66 r77  
    3434                 * Object constructor
    3535                 */
    36                 object( root* aroot, const string& aid, uid auid );
     36                object( root* aroot, const string& aid );
    3737
    3838                /**
     
    132132
    133133                /**
     134                 * Returns the root object of this object.
     135                 *
     136                 * @returns root object of current object
     137                 */
     138                virtual root* get_root() const { return (root*)m_root; }
     139
     140                /**
    134141                 * Returns object UID
    135142                 */
  • trunk/nv/types.hh

    r72 r77  
    1010#include <nv/object.hh>
    1111#include <type_traits>
     12#include <typeinfo>
     13#include <typeindex>
    1214#include <utility>
    1315#include <unordered_map>
     
    363365    };
    364366
     367        // TODO: we don't need the get_type_name template? Can we just base on typeid now, and
     368        //       pass type name on creation?
    365369    class type_database
    366370    {
     
    384388                        i_type->destructor  = DestructObject<TYPE>;
    385389
    386                         m_types[name] = i_type;
     390                        m_types[name]             = i_type;
     391                        m_idx_types[typeid(TYPE)] = i_type;
    387392                        return *i_type;
    388393                }
    389 
     394                // TODO: delete?
    390395        type_entry* get_type( hash_string name )
    391396                {
     
    397402                        return nullptr;
    398403                }
     404                type_entry* get_type( const type_info& t )
     405                {
     406                        type_info_map::iterator it = m_idx_types.find( std::type_index(t) );
     407                        if ( it != m_idx_types.end() )
     408                        {
     409                                return it->second;
     410                        }
     411                        return nullptr;
     412                }
    399413    private:
    400         typedef std::unordered_map<hash_string, type_entry*> type_map;
    401         type_map m_types;
     414                struct compare_type_info {
     415                        bool operator ()(const type_info* a, const type_info* b) const {
     416                                return a->before(*b);
     417                        }
     418                };
     419
     420        typedef std::unordered_map<hash_string, type_entry*>     type_map;
     421                typedef std::unordered_map<std::type_index, type_entry*> type_info_map;
     422        type_map      m_types;
     423                type_info_map m_idx_types;
    402424        };
    403425
  • trunk/src/gui/gui_element.cc

    r69 r77  
    1313
    1414element::element( root* aroot, const rectangle r )
    15         : object( aroot, "", 0 ), m_class(""), m_relative( r ), m_absolute( r ), m_enabled( true ), m_visible( true ), m_dirty( true )
     15        : object( aroot, "" ), m_class(""), m_relative( r ), m_absolute( r ), m_enabled( true ), m_visible( true ), m_dirty( true )
    1616{
    1717
  • trunk/src/lua/lua_state.cc

    r74 r77  
    1010#include "nv/logging.hh"
    1111#include "nv/string.hh"
     12#include "nv/root.hh"
     13#include "nv/types.hh"
    1214
    1315using namespace nv;
     
    286288}
    287289
    288 
     290lua::reference lua::state::register_object( object * o )
     291{
     292        if (!o) return ref_none;
     293        type_database *db = o->get_root()->get_type_database();
     294        if (!db) return ref_none;
     295        type_entry* t = db->get_type(typeid(o));
     296        if (!t) return ref_none;
     297        stack_guard guard( this );
     298        lua_getglobal( L, t->name.text );
     299        if ( lua_isnil( L, -1 ) )
     300        {
     301                NV_THROW( runtime_error, std::string( t->name.text ) + " type not registered!" );
     302        }
     303        deep_pointer_copy( -1, o );
     304    return luaL_ref( L, LUA_REGISTRYINDEX );
     305}
     306
     307void lua::state::unregister_object( object * o )
     308{
     309        if (!o) return;
     310        stack_guard guard( this );
     311        lua_rawgeti( L, LUA_REGISTRYINDEX, o->get_lua_index() );
     312        lua_pushstring( L, "__ptr" );
     313        lua_pushboolean( L, false );
     314        lua_rawset( L, -3 );
     315        lua_pop( L, 1 );
     316        luaL_unref( L, LUA_REGISTRYINDEX, o->get_lua_index() );
     317}
     318
     319void lua::state::deep_pointer_copy( int index, void* obj )
     320{
     321        index = lua_absindex( L, index );
     322        lua_newtable( L );
     323        lua_pushnil( L );
     324        bool has_functions = false;
     325        bool has_metatable = false;
     326
     327        while ( lua_next( L, index ) != 0 )
     328        {
     329                if ( lua_isfunction( L, -1 ) )
     330                        has_functions = true;
     331                else if ( lua_istable( L, -1 ) )
     332                {
     333                        deep_pointer_copy( -1, obj );
     334                        lua_insert( L, -2 );
     335                        lua_pop( L, 1 );
     336                }
     337                lua_pushvalue( L, -2 );
     338                lua_insert( L, -2 );
     339                lua_settable( L, -4 );
     340        }
     341
     342        if ( lua_getmetatable( L, -2 ) )
     343        {
     344                lua_setmetatable( L, -2 );
     345                has_metatable = true;
     346        }
     347
     348        if ( has_functions || has_metatable )
     349        {
     350                lua_pushstring( L, "__ptr" );
     351                lua_pushlightuserdata( L, obj );
     352                lua_rawset( L, -3 );
     353        }
     354}
  • trunk/src/object.cc

    r66 r77  
    99#include "nv/root.hh"
    1010#include "nv/types.hh"
     11#include "nv/lua/lua_state.hh"
     12#include "nv/uid.hh"
    1113
    1214using namespace nv;
     
    1921}
    2022
    21 object::object( root* aroot, const string& aid, uid auid )
    22         : m_root( aroot ), m_id(aid), m_name(), m_uid( auid ), m_lua_index(-2), m_parent( nullptr ), m_children(), m_child_count(0)
     23object::object( root* aroot, const string& aid )
     24        : m_root( aroot ), m_id(aid), m_name(), m_uid( 0 ), m_lua_index(-2), m_parent( nullptr ), m_children(), m_child_count(0)
    2325{
    24         //      uid_store::register_object( this, auid );
     26        if ( m_root )
     27        {
     28                uid_store*  store = get_root()->get_uid_store();
     29                lua::state* state = get_root()->get_lua_state();
     30                if (store)
     31                {
     32                        m_uid = store->insert( this );
     33                }
     34                if (state)
     35                {
     36                        m_lua_index = state->register_object( this );
     37                }
     38        }
     39
    2540}
    2641
     
    7792object::~object()
    7893{
    79 //      if ( m_lua_index != lua::ref_none )
    80 //      {
    81 //              lua::state::get()->unregister_object( this );
    82 //      }
    83 //      uid_store::unregister_object( m_uid );
     94        if ( m_lua_index != lua::ref_none )
     95        {
     96                lua::state* state = get_root()->get_lua_state();
     97                state->unregister_object( this );
     98        }
     99        if ( m_uid != 0 && m_root )
     100        {
     101                uid_store* store = get_root()->get_uid_store();
     102                if (store) store->remove( m_uid );
     103        }
    84104        detach();
    85105        destroy_children();
Note: See TracChangeset for help on using the changeset viewer.