//----------------------------------------------------------------// int MOAILuaObject::_gc ( lua_State* L ) { MOAILuaState state ( L ); MOAILuaObject* self = ( MOAILuaObject* )state.GetPtrUserData ( 1 ); self->mCollected = true; if ( MOAILuaRuntime::IsValid ()) { if ( self->mFinalizer ) { self->mFinalizer.PushRef ( state ); if ( state.IsType ( -1, LUA_TFUNCTION )) { state.DebugCall ( 0, 0 ); } else if ( state.IsType ( -1, LUA_TSTRING )) { printf ( "%s\n", state.GetValue < cc8* >( -1, "" )); } else { state.Pop ( 1 ); } self->mFinalizer.Clear (); } if ( MOAILuaRuntime::Get ().mReportGC ) { printf ( "GC %s <%p>\n", self->TypeName (), self ); } } if ( self->GetRefCount () == 0 ) { delete ( self ); } return 0; }
//----------------------------------------------------------------// int MOAILuaObject::_tostring ( lua_State* L ) { MOAILuaState state ( L ); MOAILuaObject* data = ( MOAILuaObject* )state.GetPtrUserData ( 1 ); if ( data ) { STLString str; lua_getfield ( state, 1, "getClassName" ); if ( state.IsType ( -1, LUA_TFUNCTION )) { lua_pushvalue ( state, 1 ); state.DebugCall ( 1, 1 ); cc8* classname = state.GetValue < cc8* >( -1, "" ); str.write ( "%p <%s>", data, classname ); state.Push ( str ); return 1; } str.write ( "%p <%s>", data, data->TypeName ()); state.Push ( str ); return 1; } return 0; }
//----------------------------------------------------------------// int MOAILuaRuntime::_debugCall ( lua_State* L ) { MOAILuaState state ( L ); state.DebugCall ( 0, 0 ); return 0; }
//----------------------------------------------------------------// int MOAILuaClass::_new ( lua_State* L ) { // upvalues: // 1: interface table // 2: original 'new' MOAILuaState state ( L ); lua_pushvalue ( L, lua_upvalueindex ( 2 )); if ( state.IsType ( -1, LUA_TFUNCTION )) { // call the original new state.DebugCall ( 0, 1 ); if ( state.IsType ( -1, LUA_TUSERDATA )) { // get the ref table if ( lua_getmetatable ( state, -1 )) { // get the member table if ( lua_getmetatable ( state, -1 )) { // get the interface table lua_pushvalue ( L, lua_upvalueindex ( 1 )); // set the interface table as the metatable lua_setmetatable ( L, -2 ); // done with the member table lua_pop ( L, 1 ); } // done with the ref table lua_pop ( L, 1 ); } } return 1; } return 0; }
//----------------------------------------------------------------// void MOAIEnvironment::SetValue ( lua_State* L ) { MOAILuaState state ( L ); int top = state.GetTop (); this->PushLuaClassTable ( state ); state.CopyToTop ( -3 ); // key state.CopyToTop ( -3 ); // value lua_settable ( state, -3 ); state.Pop ( 1 ); if ( this->PushListener ( EVENT_VALUE_CHANGED, state )) { state.CopyToTop ( -3 ); // key state.CopyToTop ( -3 ); // value state.DebugCall ( 2, 0 ); } top = state.GetTop (); }
//----------------------------------------------------------------// int MOAILuaClass::_extendFactory ( lua_State* L ) { MOAILuaState state ( L ); // upvalues: // 1: class table // 2: interface table // clone the class table state.CloneTable ( lua_upvalueindex ( 1 )); // add getClassName to class table lua_pushvalue ( L, 1 ); lua_pushcclosure ( L, _getUpvalue, 1 ); lua_setfield ( L, -2, "getClassName" ); // clone the interface table state.CloneTable ( lua_upvalueindex ( 2 )); // set the interface table as its own __index lua_pushvalue ( state, -1 ); lua_setfield ( state, -2, "__index" ); // add getClass to interface table lua_pushvalue ( L, -2 ); lua_pushcclosure ( L, _getUpvalue, 1 ); lua_setfield ( L, -2, "getClass" ); // add getClassName to interface table lua_pushvalue ( L, 1 ); lua_pushcclosure ( L, _getUpvalue, 1 ); lua_setfield ( L, -2, "getClassName" ); // stack: // -1: interface table // -2: class table // copy the extended interface table lua_pushvalue ( L, -1 ); // get and push the original factory method lua_pushvalue ( L, lua_upvalueindex ( 1 )); lua_getfield ( L, -1, "new" ); lua_replace ( L, -2 ); // push the 'new' function with the interface table and original factory method as upvalues lua_pushcclosure ( L, _new, 2 ); // set the extended 'new' method into the class table lua_setfield ( L, -3, "new" ); // stack: // -1: interface table // -2: class table // now copy the extended class and interface tables lua_pushvalue ( L, -2 ); lua_pushvalue ( L, -2 ); // push the 'extend' method with the extended class and interface tables as upvalues lua_pushcclosure ( L, _extendFactory, 2 ); // set the extended 'extend' method into the class table lua_setfield ( L, -3, "extend" ); // stack: // -1: interface table // -2: class table // init the getInterfaceTable method lua_pushvalue ( L, -1 ); lua_pushcclosure ( state, _getInterfaceTable, 1 ); lua_setfield ( state, -3, "getInterfaceTable" ); // stack: // -1: interface table // -2: class table // call the extender if ( state.IsType ( 2, LUA_TFUNCTION )) { lua_pushvalue ( L, 2 ); // function lua_pushvalue ( L, -2 ); // interface table lua_pushvalue ( L, -4 ); // class table lua_pushvalue ( L, lua_upvalueindex ( 2 )); // super interface table lua_pushvalue ( L, lua_upvalueindex ( 1 )); // super class table state.DebugCall ( 4, 0 ); } // stack: // -1: interface table // -2: class table lua_pop ( L, 1 ); // stack: // -1: class table // and we're done cc8* classname = state.GetValue < cc8* >( 1, "" ); lua_setglobal ( state, classname ); return 0; }
//----------------------------------------------------------------// int MOAILuaClass::_extendSingleton ( lua_State* L ) { MOAILuaState state ( L ); // upvalues: // 1: singleton userdata // 2: class table // set the userdata MOAILuaObject* luaData = ( MOAILuaObject* )state.GetPtrUserData ( lua_upvalueindex ( 1 )); state.PushPtrUserData ( luaData ); // clone the class table state.CloneTable ( lua_upvalueindex ( 2 )); lua_pushvalue ( state, -1 ); lua_setfield ( state, -2, "__index" ); lua_pushvalue ( state, -1 ); lua_setfield ( state, -2, "__newindex" ); // add getClassName to class table lua_pushvalue ( L, 1 ); lua_pushcclosure ( L, _getUpvalue, 1 ); lua_setfield ( L, -2, "getClassName" ); // copy the extended userdata lua_pushvalue ( L, -2 ); // copy the extended table lua_pushvalue ( L, -2 ); // push the 'extend' method with the singleton userdata and extended class table upvalues lua_pushcclosure ( L, _extendSingleton, 2 ); // set the extended 'extend' method... lua_setfield ( L, -2, "extend" ); // stack: // -1: extended class table // -2: extended userdata // call the extender if ( state.IsType ( 2, LUA_TFUNCTION )) { lua_pushvalue ( L, 2 ); lua_pushvalue ( L, -2 ); lua_pushvalue ( L, lua_upvalueindex ( 2 )); state.DebugCall ( 2, 0 ); } // stack: // -1: extended class table // -2: extended userdata // set the table as a metatable on the userdata lua_setmetatable ( L, -2 ); // and we're done cc8* classname = state.GetValue < cc8* >( 1, "" ); lua_setglobal ( state, classname ); return 0; }