//----------------------------------------------------------------// void MOAILuaObject::BindToLuaWithTable ( MOAILuaState& state ) { assert ( !this->mUserdata ); assert ( state.IsType ( -1, LUA_TTABLE )); MOAILuaClass* type = this->GetLuaClass (); assert ( type ); // create and initialize a new userdata state.PushPtrUserData ( this ); // create and initialize the private table lua_newtable ( state ); // set the ref to the private table lua_pushvalue ( state, -3 ); lua_setfield ( state, -2, LUA_MEMBER_TABLE_NAME ); // initialize the private table lua_pushcfunction ( state, MOAILuaObject::_gc ); lua_setfield ( state, -2, "__gc" ); lua_pushcfunction ( state, MOAILuaObject::_tostring ); lua_setfield ( state, -2, "__tostring" ); lua_pushcfunction ( state, MOAILuaObject::_index ); lua_setfield ( state, -2, "__index" ); lua_pushcfunction ( state, MOAILuaObject::_newindex ); lua_setfield ( state, -2, "__newindex" ); // make the interface table the instance table's meta type->PushInterfaceTable ( state ); lua_setmetatable ( state, -2 ); // grab a ref to the instance table; attach it to the userdata this->mInstanceTable = state.GetWeakRef ( -1 ); lua_setmetatable ( state, -2 ); // and take a ref back to the userdata if ( this->GetRefCount () == 0 ) { this->mUserdata.SetWeakRef ( state, -1 ); } else { this->mUserdata.SetStrongRef ( state, -1 ); } // overwrite the member table lua_replace ( state, -2 ); assert ( !lua_isnil ( state, -1 )); }
//----------------------------------------------------------------// void MOAILuaObject::BindToLua ( MOAILuaState& state ) { assert ( !this->mUserdata ); MOAILuaClass* type = this->GetLuaClass (); assert ( type ); // create and initialize a new userdata state.PushPtrUserData ( this ); // create and initialize the member table lua_newtable ( state ); lua_pushvalue ( state, -1 ); lua_setfield ( state, -2, "__index" ); lua_pushvalue ( state, -1 ); lua_setfield ( state, -2, "__newindex" ); lua_pushcfunction ( state, MOAILuaObject::_gc ); lua_setfield ( state, -2, "__gc" ); lua_pushcfunction ( state, MOAILuaObject::_tostring ); lua_setfield ( state, -2, "__tostring" ); // attach the member table to the userdata lua_pushvalue ( state, -1 ); lua_setmetatable ( state, -3 ); // grab a ref to the member table this->mMemberTable = state.GetWeakRef ( -1 ); // stack: // -1: member table // -2: userdata // create an empty ref table and attach it to the member table lua_newtable ( state ); lua_pushvalue ( state, -1 ); lua_setmetatable ( state, -3 ); // stack: // -1: ref table // -2: member table // -3: userdata // push the interface table and attach it to the ref table type->PushInterfaceTable ( state ); lua_pushvalue ( state, -1 ); lua_setmetatable ( state, -3 ); // stack: // -1: interface table // -2: ref table // -3: member table // -4: userdata // use the interface table as the ref table's __index lua_setfield ( state, -2, "__index" ); // stack: // -1: ref table // -2: member table // -3: userdata lua_pop ( state, 2 ); // stack: // -1: userdata // and take a ref back to the userdata if ( this->GetRefCount () == 0 ) { this->mUserdata.SetWeakRef ( state, -1 ); } else { this->mUserdata.SetStrongRef ( state, -1 ); } assert ( !lua_isnil ( state, -1 )); }