//----------------------------------------------------------------// void MOAIGlyph::SerializeIn ( MOAILuaState& state ) { this->mCode = state.GetField ( -1, "mCode", this->mCode ); this->mPageID = state.GetField ( -1, "mPageID", this->mPageID ); this->mWidth = state.GetField ( -1, "mWidth", this->mWidth ); this->mHeight = state.GetField ( -1, "mHeight", this->mHeight ); this->mAdvanceX = state.GetField ( -1, "mAdvanceX", this->mAdvanceX ); this->mBearingX = state.GetField ( -1, "mBearingX", this->mBearingX ); this->mBearingY = state.GetField ( -1, "mBearingY", this->mBearingY ); this->mSrcX = state.GetField ( -1, "mSrcX", this->mSrcX ); this->mSrcY = state.GetField ( -1, "mSrcY", this->mSrcY ); if ( state.GetFieldWithType ( -1, "mKernTable", LUA_TTABLE )) { u32 size = lua_objlen ( state, -1 ); this->mKernTable.Init ( size ); for ( u32 i = 0; i < size; ++i ) { if ( state.GetFieldWithType ( -1, i + 1, LUA_TTABLE )) { this->mKernTable [ i ].mName = state.GetField ( -1, "mName", 0 ); this->mKernTable [ i ].mX = state.GetField ( -1, "mX", 0.0f ); this->mKernTable [ i ].mY = state.GetField ( -1, "mY", 0.0f ); } state.Pop ( 1 ); } state.Pop ( 1 ); } }
//----------------------------------------------------------------// void MOAILuaObject::PushLuaUserdata ( MOAILuaState& state ) { bool hasUserdata = !this->mUserdata.IsNil (); // create the handle userdata for reference counting if ( !this->mUserdata.PushRef ( state )) { // pop the 'nil' pushed by PushRef state.Pop ( 1 ); // this is a nasty edge case where the userdata has been tagged for garbage // collection, but not actually collected. the result is that the ref hasn't // be cleared yet, but when we push it we get nil. this should only happen to // refs to userdata. it's tempting to try and clear out the ref here, but if // the ref is to a MOAILuaObject's userdata, the next step may be to recreate // the object... which means when it is garbage collected the wrong (new) // userdata will be cleaned up! so all we can do is force a full collection // step, set ourselves to nil and return failure. if ( hasUserdata ) { USLog::Print ( "Attempt to access MOAILuaObject userdata tagged for garbage collection; running a full cycle of GC prior to reallocation.\n" ); MOAILuaRuntime::Get ().ForceGarbageCollection (); } // initialize and bind the userdata this->BindToLua ( state ); } assert ( !lua_isnil ( state, -1 )); }
//----------------------------------------------------------------// void MOAIGlyphSet::SerializeIn ( MOAILuaState& state ) { UNUSED ( state ); this->mSize = state.GetField ( -1, "mSize", this->mSize ); this->mHeight = state.GetField ( -1, "mHeight", this->mHeight ); this->mAscent = state.GetField ( -1, "mAscent", this->mAscent ); if ( state.GetFieldWithType ( -1, "mGlyphMap", LUA_TTABLE )) { u32 itr = state.PushTableItr ( -1 ); while ( state.TableItrNext ( itr )) { u32 c = state.GetValue < u32 >( -2, 0 ); MOAIGlyph& glyph = this->mGlyphMap [ c ]; glyph.SerializeIn ( state ); } state.Pop ( 1 ); } GlyphMapIt glyphMapIt = this->mGlyphMap.begin (); for ( ; glyphMapIt != this->mGlyphMap.end (); ++glyphMapIt ) { MOAIGlyph& glyph = glyphMapIt->second; if ( glyph.mPageID == MOAIGlyph::NULL_PAGE_ID ) { glyph.mNext = this->mPending; this->mPending = &glyph; } else { glyph.mNext = this->mGlyphs; this->mGlyphs = &glyph; } } }
//----------------------------------------------------------------// 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; }
//----------------------------------------------------------------// void MOAIMesh::SerializeIn ( MOAILuaState& state, MOAIDeserializer& serializer ) { MOAIVertexArray::SerializeIn ( state, serializer ); this->SetIndexBuffer ( serializer.MemberIDToObject < MOAIIndexBuffer >( state.GetField < MOAISerializer::ObjID >( -1, "mIndexBuffer", 0 ))); this->mTotalElements = state.GetField < u32 >( -1, "mTotalElements", 0 ); this->mHasBounds = state.GetField < bool >( -1, "mHasBounds", 0 ); if ( state.GetFieldWithType ( -1, "mBounds", LUA_TTABLE )) { this->mBounds.mMin.mX = state.GetField < float >( -1, "mMinX", 0 ); this->mBounds.mMin.mY = state.GetField < float >( -1, "mMinY", 0 ); this->mBounds.mMin.mZ = state.GetField < float >( -1, "mMinZ", 0 ); this->mBounds.mMax.mX = state.GetField < float >( -1, "mMaxX", 0 ); this->mBounds.mMax.mY = state.GetField < float >( -1, "mMaxY", 0 ); this->mBounds.mMax.mZ = state.GetField < float >( -1, "mMaxZ", 0 ); state.Pop (); } this->mPenWidth = state.GetField < float >( -1, "mPenWidth", 0 ); }
//----------------------------------------------------------------// bool MOAILuaObject::IsMoaiUserdata ( MOAILuaState& state, int idx ) { bool result = false; if ( state.IsType ( idx, LUA_TUSERDATA )) { if ( lua_getmetatable ( state, idx )) { result = state.HasField ( -1, MOAI_TAG ); state.Pop ( 1 ); } } return result; }
//----------------------------------------------------------------// void MOAILuaObject::SetMemberTable ( MOAILuaState& state, int idx ) { UNUSED ( state ); UNUSED ( idx ); // TODO: what if object is a singleton? assert ( !this->GetLuaClass ()->IsSingleton ()); // TODO: should actually set the member table, not just crash idx = state.AbsIndex ( idx ); this->PushLuaUserdata ( state ); // userdata lua_getmetatable ( state, - 1 ); // ref table lua_getmetatable ( state, - 1 ); // member table lua_getmetatable ( state, - 1 ); // interface table lua_pushvalue ( state, idx ); lua_replace ( state, -3 ); this->MakeLuaBinding ( state ); state.Pop ( 1 ); }
//----------------------------------------------------------------// 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 (); }
//----------------------------------------------------------------// static void _dumpType ( lua_State* L, int idx, const char *name, bool verbose, TableSet& foundTables ) { MOAILuaState state ( L ); const char *format = DUMP_FORMAT; idx = state.AbsIndex( idx ); StkId tvalue = state->base + idx - 1; switch ( lua_type ( state, idx )) { case LUA_TBOOLEAN: ZLLog::Print ( format, tvalue, "bool", name ); ZLLog::Print ( " = %s", lua_toboolean ( state, idx ) ? "true" : "false" ); break; case LUA_TFUNCTION: { const char *funcType = iscfunction ( tvalue ) ? "C function" : "Lua function"; ZLLog::Print ( format, clvalue ( tvalue ), funcType, name ); break; } case LUA_TLIGHTUSERDATA: ZLLog::Print ( format, pvalue ( tvalue ), "pointer", name ); break; case LUA_TNIL: ZLLog::Print ( format, tvalue, "nil", name ); break; case LUA_TNONE: // Intentionally do nothing--not even the line break. return; case LUA_TNUMBER: ZLLog::Print ( format, tvalue, "number", name ); ZLLog::Print ( " = %f", lua_tonumber ( state, idx )); break; case LUA_TSTRING: ZLLog::Print ( format, rawtsvalue( tvalue ), "string", name ); ZLLog::Print ( " = \"%s\"", lua_tostring ( state, idx )); break; case LUA_TTABLE: { struct Table* htable = hvalue( tvalue ); if ( foundTables.contains ( htable )) { ZLLog::Print ( DUMP_FORMAT " (see above)", htable, "table", name ); break; } else { foundTables.insert ( htable ); ZLLog::Print ( format, htable, "table", name ); if ( verbose ) { ZLLog::Print ( "\n" ); lua_pushnil ( state ); while ( lua_next ( state, idx ) ) { STLString elementName( name ); elementName.append ( "." ); elementName.append ( lua_tostring ( state, -2 )); _dumpType ( state, -1, elementName.c_str (), verbose, foundTables ); lua_pop ( state, 1 ); } } } } return; // suppress newline case LUA_TTHREAD: ZLLog::Print ( format, thvalue( tvalue ), "thread", name ); break; case LUA_TUSERDATA: if ( lua_islightuserdata ( state, idx ) ) { ZLLog::Print ( format, lua_topointer ( state, idx ) , "light userdata", name ); } else { ZLLog::Print ( format, lua_topointer( state, idx ), "userdata", name ); if ( verbose ) { lua_getglobal ( state, "tostring" ); lua_pushvalue ( state, idx ); lua_pcall ( state, 1, 1, 0 ); ZLLog::Print ( "\n\t%s", lua_tostring ( state, -1 )); state.Pop ( 1 ); } } break; default: ZLLog::Print ( "*** Unexpected type: %d ***", lua_type ( state, idx )); } ZLLog::Print ( "\n" ); }