//----------------------------------------------------------------// // userdata -> memberTable -> refTable -> interfaceTable // userdata is the object // memberTable is for ad hoc members added by the scripter // refTable is for ad hoc mambers added by the engine // interfaceTable is the 'class' table - methods and constants // __index looks in membertTable then *skips* refTable to fall back on interfaceTable void MOAILuaObject::BindToLua ( MOAILuaState& state ) { assert ( !this->mUserdata ); if ( MOAILuaRuntime::IsValid ()) { MOAILuaRuntime::Get ().RegisterObject ( state, *this ); } MOAILuaClass* type = this->GetLuaClass (); assert ( type ); // both singletons and instances may be bound to a userdata state.PushPtrUserData ( this ); // userdata // for now, singletons are just userdata with no add'l metatables // so only build the metatable stack if we're *not* a singleton if ( !type->IsSingleton ()) { // instances get the 'full stack' of metatables lua_newtable ( state ); // ref table lua_newtable ( state ); // member table type->PushInterfaceTable ( state ); // interface table this->MakeLuaBinding ( state ); } // and take a weak ref back to the userdata this->mUserdata.SetRef ( state, -1 ); assert ( !lua_isnil ( state, -1 )); // NOTE: we have to do this *after* mUserdata has been initialized as LuaRetain calls PushLuaUserdata // which in turn calls BindToLua if there is no mUserdata... if ( type->IsSingleton ()) { this->LuaRetain ( this ); // create a circular reference to 'pin' the userdata } }
//----------------------------------------------------------------// void MOAISerializer::WriteObjectInits ( USStream& stream ) { if ( !this->mPending.size ()) return; while ( this->mPending.size ()) { MOAILuaObject* object = this->mPending.front (); assert ( object ); this->mPending.pop_front (); u32 id = this->GetID ( object ); stream.Print ( "\t--%s\n", object->TypeName ()); stream.Print ( "\tserializer:initObject (\n" ); MOAILuaClass* type = object->GetLuaClass (); if ( type->IsSingleton ()) { stream.Print ( "\t\t%s.get (),\n", object->TypeName ()); } else { stream.Print ( "\t\tobjects [ 0x%08X ],\n", id ); } MOAILuaStateHandle state = MOAILuaRuntime::Get ().State (); object->PushMemberTable ( state ); stream.Print ( "\t\tobjects [ 0x%08X ],\n", this->AffirmMemberID ( state, -1 )); state.Pop ( 1 ); // this should fill the table for the class lua_newtable ( state ); object->SerializeOut ( state, *this ); stream.Print ( "\t\t{" ); if ( this->WriteTable ( stream, state, -1, 3 )) { stream.Print ( "\t\t}\n" ); } else { stream.Print ( "}\n" ); } state.Pop ( 1 ); stream.Print ( "\t)\n\n" ); } }
//----------------------------------------------------------------// void MOAISerializer::WriteObjectDecls ( USStream& stream ) { if ( !this->mObjectMap.size ()) return; stream.Print ( "\t--Declaring Instances\n" ); ObjectMapIt objectIt; objectIt = this->mObjectMap.begin (); for ( ; objectIt != this->mObjectMap.end (); ++objectIt ) { MOAILuaObject* object = objectIt->second; if ( !object ) continue; uintptr id = this->GetID ( object ); MOAILuaClass* type = object->GetLuaClass (); if ( !type->IsSingleton ()) { stream.Print ( "\t[ 0x%08X ] = serializer:registerObjectID ( %s.new (), 0x%08X ),\n", id, object->TypeName (), id ); } } stream.Print ( "\n" ); }
//----------------------------------------------------------------// bool MOAILuaObject::PushRefTable ( MOAILuaState& state ) { MOAILuaClass* luaClass = this->GetLuaClass (); if ( !luaClass ) { lua_pushnil ( state ); return false; } if ( luaClass->IsSingleton ()) { luaClass->PushRefTable ( state ); return true; } if ( this->PushLuaUserdata ( state )) { int result = lua_getmetatable ( state, -1 ); if ( result ) { lua_replace ( state, -2 ); return true; } } return false; }
//----------------------------------------------------------------// bool MOAILuaObject::PushMemberTable ( MOAILuaState& state ) { MOAILuaClass* luaType = this->GetLuaClass (); if ( luaType->IsSingleton ()) { this->PushLuaClassTable ( state ); return true; } int top = state.GetTop (); if ( this->PushLuaUserdata ( state )) { if ( lua_getmetatable ( state, -1 )) { lua_replace ( state, -2 ); if ( lua_getmetatable ( state, -1 )) { lua_replace ( state, -2 ); return true; } } } state.SetTop ( top ); lua_pushnil ( state ); return false; }
//----------------------------------------------------------------// bool MOAILuaObject::IsSingleton () { MOAILuaClass* luaClass = this->GetLuaClass (); return luaClass->IsSingleton (); }