Exemple #1
0
//----------------------------------------------------------------//
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;
}
//----------------------------------------------------------------//
void MOAILuaObject::LuaRetain ( MOAILuaObject& object ) {

	if ( this->mInstanceTable ) {
		MOAILuaStateHandle state = MOAILuaRuntime::Get ().State ();

		// affirm container table
		if ( this->mContain ) {
			this->PushLocal ( state, this->mContain );
		}
		else {
			lua_newtable ( state );
			this->SetLocal ( state, -1, this->mContain );
		}
		
		lua_pop ( state, 1 );
		this->PushLocal ( state, this->mContain );
		
		object.PushLuaUserdata ( state );
		lua_pushvalue ( state, -1 );
		lua_rawset ( state, -3 );
		
		lua_pop ( state, 1 );
	}
	object.Retain ();
}
//----------------------------------------------------------------//
void MOAILuaClass::InitLuaSingletonClass ( MOAILuaObject& data, MOAILuaState& state ) {

	// push class table
	lua_newtable ( state );
	this->RegisterLuaClass ( state );
	data.MOAILuaObject::RegisterLuaClass ( state );
	data.RegisterLuaClass ( state );
	
	// init the extend method
	lua_pushvalue ( state, -1 ); // copy of userdata //used to be 1
	lua_pushvalue ( state, -2 ); // copy of class table
	lua_pushcclosure ( state, _extendSingleton, 2 );
	lua_setfield ( state, -2, "extend" );
	
	// ref class table
	this->mClassTable.SetRef ( state, -1 );
	
	lua_pushvalue ( state, -1 );
	lua_setfield ( state, -2, "__index" );

	lua_pushvalue ( state, -1 );
	lua_setfield ( state, -2, "__newindex" );

	lua_setglobal ( state, data.TypeName ());
}
//----------------------------------------------------------------//
int MOAILuaObject::_getClassName ( lua_State* L ) {

	MOAILuaState state ( L );
	MOAILuaObject* object = ( MOAILuaObject* )state.GetPtrUserData ( 1 );

	if ( object ) {
		lua_pushstring ( L, object->TypeName ());
		return 1;
	}
	return 0;
}
//----------------------------------------------------------------//
int MOAILuaObject::_getClass ( lua_State* L ) {

	MOAILuaState state ( L );
	MOAILuaObject* object = ( MOAILuaObject* )state.GetPtrUserData ( 1 );

	if ( object ) {
		object->PushLuaClassTable ( state );
		return 1;
	}
	return 0;
}
//----------------------------------------------------------------//
int MOAIDeserializer::_initObject ( lua_State* L ) {
	LUA_SETUP ( MOAIDeserializer, "UUTT" );

	MOAILuaObject* object = state.GetLuaObject < MOAILuaObject >( 2 );
	if ( !object ) return 0;

	object->SetMemberTable ( state, 3 );
	object->SerializeIn ( state, *self );

	return 0;
}
Exemple #8
0
//----------------------------------------------------------------//
int MOAIDeserializer::_initObject ( lua_State* L ) {
	MOAI_LUA_SETUP ( MOAIDeserializer, "UU*T" );

	MOAILuaObject* object = state.GetLuaObject < MOAILuaObject >( 2, false );
	if ( !object ) return 0;

	if ( state.IsType ( 3, LUA_TTABLE )) {
		object->SetMemberTable ( state, 3 );
	}
	object->SerializeIn ( state, *self );

	return 0;
}
//----------------------------------------------------------------//
int MOAILuaObject::_tostring ( lua_State* L ) {

	MOAILuaState state ( L );

	MOAILuaObject* data = ( MOAILuaObject* )state.GetPtrUserData ( 1 );
	if ( data ) {
	
		STLString str;
		str.write ( "0x%p <%s>", data, data->TypeName ()); // TODO: 64-bit
		state.Push ( str );
		return 1;
	}
	return 0;
}
//----------------------------------------------------------------//
void MOAILuaObject::LuaRelease ( MOAILuaObject& object ) {

	if ( this->mContain && MOAILuaRuntime::IsValid ()) {
	
		MOAILuaStateHandle state = MOAILuaRuntime::Get ().State ();
	
		if ( this->PushLocal ( state, this->mContain )) {
			
			object.PushLuaUserdata ( state );
			lua_pushnil ( state );
			lua_rawset ( state, -3 );
		}
		lua_pop ( state, 1 );
	}
	object.Release ();
}
Exemple #11
0
//----------------------------------------------------------------//
void MOAILuaRuntime::BuildHistogram ( HistMap& histogram ) {

	HistSet::iterator histSetIt = this->mHistSet.begin ();
	for ( ; histSetIt != this->mHistSet.end (); ++histSetIt ) {
	
		MOAILuaObject* obj = *histSetIt;
		cc8* name = obj->TypeName ();
	
		if ( !histogram.contains ( name )) {
			histogram [ name ] = 1;
		}
		else {
			histogram [ name ]++;
		}
	}
}
//----------------------------------------------------------------//
void MOAILuaClass::InitLuaFactoryClass ( MOAILuaObject& data, MOAILuaState& state ) {

	int top = lua_gettop ( state );

	// push interface table
	lua_newtable ( state );
	
	// interface table is its own __index
	lua_pushvalue ( state, -1 );
	lua_setfield ( state, -2, "__index" );
	
	data.MOAILuaObject::RegisterLuaFuncs ( state );
	data.RegisterLuaFuncs ( state );

	this->mInterfaceTable.SetRef ( state, -1 );
	
	// reset top
	lua_settop ( state, top );

	// push class table
	lua_newtable ( state );
	this->RegisterLuaClass ( state );
	data.MOAILuaObject::RegisterLuaClass ( state );
	data.RegisterLuaClass ( state );

	// init the extend method
	lua_pushvalue ( state, -1 ); // class table
	this->mInterfaceTable.PushRef ( state ); // interface table
	lua_pushcclosure ( state, _extendFactory, 2 );
	lua_setfield ( state, -2, "extend" );

	// init the getInterfaceTable method
	this->mInterfaceTable.PushRef ( state ); // interface table
	lua_pushcclosure ( state, _getInterfaceTable, 1 );
	lua_setfield ( state, -2, "getInterfaceTable" );

	// ref class table and expose as global
	this->mClassTable.SetRef ( state, -1 );
	lua_setglobal ( state, data.TypeName ());

	// reset top
	lua_settop ( state, top );
}
Exemple #13
0
//----------------------------------------------------------------//
void MOAILuaRuntime::ReportLeaksFormatted ( FILE *f ) {

	this->ForceGarbageCollection ();

	lua_State* L = this->mMainState;
		
	// First, correlate leaks by identical stack traces.
	LeakStackMap stacks;
	
	for ( LeakMap::const_iterator i = this->mLeaks.begin (); i != this->mLeaks.end (); ++i ) {
		stacks [ i->second ].push_back ( i->first );
	}
	
	fprintf ( f, "-- BEGIN LUA OBJECT LEAKS --\n" );
	
	// Then, print out each unique allocation spot along with all references
	// (including multiple references) followed by the alloction stack
	int top = lua_gettop ( L );
	UNUSED ( top );
	for ( LeakStackMap::const_iterator i = stacks.begin (); i != stacks.end (); ++i ) {
		
		const LeakPtrList& list = i->second;
		
		MOAILuaObject *o = list.front ();
		fprintf ( f, "Allocation: %lu x %s\n", list.size (), o->TypeName ()); 
		for( LeakPtrList::const_iterator j = list.begin (); j != list.end (); ++j ) {
			fprintf ( f, "\t(%6d) %p\n", ( *j )->GetRefCount (), *j );
		}
		// A table to use as a traversal set.
		lua_newtable ( L );
		// And the table to use as seed
		lua_pushglobaltable ( L );
		
		this->FindAndPrintLuaRefs ( -2, "_G", f, list );
		
		lua_pop ( L, 2 ); // Pop the 'done' set and our globals table
		fputs ( i->first.c_str (), f );
		fputs ( "\n", f );
		fflush ( f );
	}
	assert ( top == lua_gettop ( L ));
	fprintf ( f, "-- END LUA LEAKS --\n" );
}
Exemple #14
0
//----------------------------------------------------------------//
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" );
}
//----------------------------------------------------------------//
int MOAILuaObject::_gc ( lua_State* L ) {

	MOAILuaState state ( L );
	
	MOAILuaObject* data = ( MOAILuaObject* )state.GetPtrUserData ( 1 );

	bool cleanup = ( data->GetRefCount () == 0 ); // ready to cleanup if no references

	// in any event, let's get rid of the userdata and lua refs we know about
	data->ClearLocal ( data->mContain );
	data->mUserdata.Clear ();
	data->mMemberTable.Clear ();
	
	// check to see if gc is being invoked during finalization
	if ( MOAILuaRuntime::IsValid ()) {
		MOAILuaRuntime::Get ().ClearObjectStackTrace ( data );
	}

	// delete if no references
	if ( cleanup ) {
		delete data;
	}
	return 0;
}
Exemple #16
0
//----------------------------------------------------------------//
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" );
	}
}