예제 #1
0
//----------------------------------------------------------------//
uintptr MOAISerializer::AffirmMemberID ( MOAILuaState& state, int idx ) {

	// if we're an object, affirm as such...
	if ( state.IsType ( idx, LUA_TUSERDATA )) {
		return this->AffirmMemberID ( state.GetLuaObject < MOAILuaObject >( -1 ));
	}

	// bail if we're not a table
	if ( !state.IsType ( idx, LUA_TTABLE )) return 0;

	// get the table's address
	uintptr memberID = ( uintptr )lua_topointer ( state, idx );
	
	// bail if the table's already been added
	if ( this->mTableMap.contains ( memberID )) return memberID;

	// add the ref now to avoid cycles
	this->mTableMap [ memberID ].SetStrongRef ( state, idx );

	// follow the table's refs to make sure everything gets added
	u32 itr = state.PushTableItr ( idx );
	while ( state.TableItrNext ( itr )) {
		this->AffirmMemberID ( state, -1 );
	}
	
	return memberID;
}
예제 #2
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;
}
예제 #3
0
/**	@name	serializeToString
	@text	Serializes the specified table or object to a string.

	@overload

		@in		table data				The table to serialize.
		@out	string serialized		The serialized string.
	
	@overload

		@in		MOAILuaObject data			The object to serialize.
		@out	string serialized		The serialized string.
*/
int MOAISerializer::_serializeToString ( lua_State* L ) {

	MOAILuaState state ( L );
	if ( !( state.IsType ( 1, LUA_TTABLE ) || state.IsType ( 1, LUA_TUSERDATA ))) return 0;

	MOAISerializer serializer;
	serializer.AddLuaReturn ( state, 1 );
	STLString result = serializer.SerializeToString ();

	lua_pushstring ( state, result );

	return 1;
}
예제 #4
0
/**	@name	serializeToFile
	@text	Serializes the specified table or object to a file.

	@overload

		@in		string filename			The file to create.
		@in		table data				The table to serialize.
		@out	nil
	
	@overload

		@in		string filename			The file to create.
		@in		MOAILuaObject data			The object to serialize.
		@out	nil
*/
int MOAISerializer::_serializeToFile ( lua_State* L ) {

	MOAILuaState state ( L );
	if ( !( state.IsType ( 1, LUA_TSTRING ))) return 0;
	if ( !( state.IsType ( 2, LUA_TTABLE ) || state.IsType ( 2, LUA_TUSERDATA ))) return 0;

	cc8* filename = state.GetValue < cc8* >( 1, "" );

	MOAISerializer serializer;
	serializer.AddLuaReturn ( state, 2 );
	serializer.SerializeToFile ( filename );
	
	return 0;
}
예제 #5
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;
}
예제 #6
0
/**	@name	base64Encode
	@text	If a string is provided, encodes it in base64.  Otherwise, encodes the current data stored in this object as a base64 encoded sequence of characters.

	@opt	MOAIDataBuffer self
	@opt	string data				The string data to encode.  You must either provide either a MOAIDataBuffer (via a :base64Encode type call) or string data (via a .base64Encode type call), but not both.
	@out	string output			If passed a string, returns either a string or nil depending on whether it could be encoded.  Otherwise the encoding occurs inline on the existing data buffer in this object, and nil is returned.
*/
int MOAIDataBuffer::_base64Encode ( lua_State* L ) {
	MOAILuaState state ( L );
	
	if ( state.IsType ( 1, LUA_TSTRING )) {
		return state.Base64Encode ( 1 ) ? 1 : 0;
	}
	
	MOAIDataBuffer* self = state.GetLuaObject < MOAIDataBuffer >( 1, true );
	if ( self ) {
		if ( state.IsType ( 2, LUA_TSTRING )) {
			size_t len;
			cc8* str = lua_tolstring ( state, 2, &len );
			self->Load (( void* )str, len );
		}
		self->Base64Encode ();
	}
	return 0;
}
예제 #7
0
/**	@name	setValue
	@text	Sets an environment value and also triggers the listener
			callback (if any).

	@in		string key
	@opt	variant value		Default value is nil.
	@out	nil
*/
int MOAIEnvironment::_setValue ( lua_State* L ) {
	MOAILuaState state ( L );
	
	if ( state.IsType ( 1, LUA_TSTRING )) {
	
		MOAIEnvironment& environment = MOAIEnvironment::Get ();
		environment.SetValue ( state );
	}
	return 0;
}
예제 #8
0
	//----------------------------------------------------------------//
	// TODO: doxygen
	int MOAIMath::_randSFMT ( lua_State* L ) {
		MOAILuaState state ( L );
		
		double lower = 0.0;
		double upper = 1.0;
		
		if ( state.IsType ( 1, LUA_TNUMBER )) {
		
			upper = state.GetValue < double >( 1, 0.0 );
		
			if ( state.IsType ( 2, LUA_TNUMBER )) {
				lower = upper;
				upper = state.GetValue < double >( 2, 0.0 );
			}
		}
		
		double r = sfmt_genrand_real1 ( MOAIMath::Get ().mSFMT ); // [0, 1]
		state.Push ( lower + ( r * ( upper - lower )));
		return 1;
	}
예제 #9
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;
}
예제 #10
0
//----------------------------------------------------------------//
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 ));
}
예제 #11
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;
}
예제 #12
0
/**	@name	encode
	@text	Encode a hierarchy of Lua tables into a JSON string.
	
	@in		table input
	@out	string result
*/
int MOAIJsonParser::_encode ( lua_State* L ) {

	MOAILuaState state ( L );
	
	if ( state.IsType ( 1, LUA_TTABLE )) {
	
		json_t* json = _luaToJSON ( state, 1 );
		if ( json ) {
			
			int flags = state.IsType ( 2, 0 );
			char* str = json_dumps ( json, flags );
			json_decref ( json );
			
			if ( str ) {
				lua_pushstring ( state, str );
				free ( str );
				return 1;
			}
		}
	}
	return 0;
}
예제 #13
0
/**	@name	inflate
	@text	Decompresses the string or the current data stored in this object using the DEFLATE algorithm.

	@opt	MOAIDataBuffer self
	@opt	string data				The string data to inflate.  You must either provide either a MOAIDataBuffer (via a :base64Decode type call) or string data (via a .base64Decode type call), but not both.
	@in		number windowBits		The window bits used in the DEFLATE algorithm.  Pass nil to use the default value.
	@out	string output			If passed a string, returns either a string or nil depending on whether it could be decompressed.  Otherwise the decompression occurs inline on the existing data buffer in this object, and nil is returned.
*/
int MOAIDataBuffer::_inflate ( lua_State* L ) {
	MOAILuaState state ( L );

	int windowBits = state.GetValue < int >( 2, USDeflateReader::DEFAULT_WBITS );

	if ( state.IsType ( 1, LUA_TSTRING )) {
		return state.Inflate ( 1, windowBits ) ? 1 : 0;
	}
	
	MOAIDataBuffer* self = state.GetLuaObject < MOAIDataBuffer >( 1, true );
	if ( self ) {
		self->Inflate ( windowBits );
	}
	return 0;
}
예제 #14
0
/**	@name	showDialog
	@text	Show a native dialog to the user.
				
	@in		string		title			The title of the dialog box. Can be nil.
	@in		string		message			The message to show the user. Can be nil.
	@in		string		positive		The text for the positive response dialog button. Can be nil.
	@in		string		neutral			The text for the neutral response dialog button. Can be nil.
	@in		string		negative		The text for the negative response dialog button. Can be nil.
	@in		bool		cancelable		Specifies whether or not the dialog is cancelable
	@opt	function	callback		A function to callback when the dialog is dismissed. Default is nil.
	@out 	nil
*/
int MOAIDialogAndroid::_showDialog ( lua_State* L ) {
	
	MOAILuaState state ( L );	
	
	cc8* title = lua_tostring ( state, 1 );
	cc8* message = lua_tostring ( state, 2 );
	cc8* positive = lua_tostring ( state, 3 );
	cc8* neutral = lua_tostring ( state, 4 );
	cc8* negative = lua_tostring ( state, 5 );
	bool cancelable = lua_toboolean ( state, 6 );
	
	if ( state.IsType ( 7, LUA_TFUNCTION )) {
		
		// NOTE: This is fragile. We're storing the callback function in a global variable,
		// effectively. Invoking the showDialog method multiple times in succession can
		// therefore lead to unpredictable results. In fact, it's unknown how Android itself
		// handles multiple invocations - are they queued? On iOS, UIAlertView is LIFO and
		// new invocations supersede previous ones, but once dismissed, the system continues
		// down the alert stack.
		MOAIDialogAndroid::Get ().mDialogCallback.SetStrongRef ( state, 7 );
	}	
	
	JNI_GET_ENV ( jvm, env );

	JNI_GET_JSTRING ( title, jtitle );
	JNI_GET_JSTRING ( message, jmessage );
	JNI_GET_JSTRING ( positive, jpositive );
	JNI_GET_JSTRING ( neutral, jneutral );
	JNI_GET_JSTRING ( negative, jnegative );

	jclass moai = env->FindClass ( "com/ziplinegames/moai/Moai" );
    if ( moai == NULL ) {

		ZLLog::Print ( "MOAIDialogAndroid: Unable to find java class %s", "com/ziplinegames/moai/Moai" );
    } else {

    	jmethodID showDialog = env->GetStaticMethodID ( moai, "showDialog", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V" );
    	if ( showDialog == NULL ) {

			ZLLog::Print ( "MOAIDialogAndroid: Unable to find static java method %s", "showDialog" );
    	} else {

			env->CallStaticVoidMethod ( moai, showDialog, jtitle, jmessage, jpositive, jneutral, jnegative, cancelable );	
		}
	}
	
	return 0;
}
예제 #15
0
/**	@name	deflate
	@text	Compresses the string or the current data stored in this object using the DEFLATE algorithm.

	@opt	MOAIDataBuffer self
	@opt	string data				The string data to deflate.  You must either provide either a MOAIDataBuffer (via a :base64Decode type call) or string data (via a .base64Decode type call), but not both.
	@in		number level			The level used in the DEFLATE algorithm.  Pass nil to use the default value.
	@in		number windowBits		The window bits used in the DEFLATE algorithm.  Pass nil to use the default value.
	@out	string output			If passed a string, returns either a string or nil depending on whether it could be compressed.  Otherwise the compression occurs inline on the existing data buffer in this object, and nil is returned.
*/
int MOAIDataBuffer::_deflate ( lua_State* L ) {
	MOAILuaState state ( L );

	int level = state.GetValue < int >( 2, USDeflateWriter::DEFAULT_LEVEL );
	int windowBits = state.GetValue < int >( 3, USDeflateWriter::DEFAULT_WBITS );

	if ( state.IsType ( 1, LUA_TSTRING )) {
		return state.Deflate ( 1, level, windowBits ) ? 1 : 0;
	}
	
	MOAIDataBuffer* self = state.GetLuaObject < MOAIDataBuffer >( 1, true );
	if ( self ) {
		self->Deflate ( level, windowBits );
	}
	return 0;
}
예제 #16
0
/**	@name	decode
	@text	Decode a JSON string into a hierarchy of Lua tables.
	
	@in		string input
	@out	table result
*/
int MOAIJsonParser::_decode ( lua_State* L ) {
	UNUSED ( L );

	MOAILuaState state ( L );
	if ( state.IsType ( 1, LUA_TSTRING )) {
		
		size_t bufflen;
		cc8* buffer = lua_tolstring ( L, -1, &bufflen );
		
		json_error_t error;
		json_t* json = json_loadb ( buffer, bufflen, JSON_DISABLE_EOF_CHECK, &error );
		if ( json ) {
			
			_jsonToLua ( L, json );
			json_decref ( json );
			return 1;
		}
	}
	return 0;
}
예제 #17
0
/**	@lua	decode
	@text	Decode a JSON string into a hierarchy of Lua tables.

	@in		string input
	@out	table result
*/
int MOAIJsonParser::_decode ( lua_State* L ) {
    UNUSED ( L );

    MOAILuaState state ( L );
    if ( state.IsType ( 1, LUA_TSTRING )) {

        size_t bufflen;
        cc8* buffer = lua_tolstring ( L, -1, &bufflen );

        json_error_t error;
        json_t* json = json_loadb ( buffer, bufflen, JSON_DISABLE_EOF_CHECK, &error );

        if ( json ) {
            _jsonToLua ( L, json );
            json_decref ( json );
            return 1;
        }
        else {
            printf ( "%d %d %d %s %s\n", error.line, error.column, error.position, error.source, error.text );
        }
    }
    return 0;
}
예제 #18
0
/**	@name	toCppHeader
	@text	Convert data to CPP header file.

	@overload

		@in		string data				The string data to encode
		@in		string name
		@opt	number columns			Default value is 12
		@out	string output
	
	@overload

		@in		MOAIDataBuffer data		The data buffer to encode
		@in		string name
		@opt	number columns			Default value is 12
		@out	string output
*/
int MOAIDataBuffer::_toCppHeader ( lua_State* L ) {
	MOAILuaState state ( L );
	
	cc8* name		= state.GetValue < cc8* >( 2, "" );
	u32 columns		= state.GetValue < u32 >( 3, 12 );
	
	if ( !strlen ( name )) return 0;
	
	USMemStream memStream;
	
	if ( state.IsType ( 1, LUA_TSTRING )) {
		
		size_t size;
		const void* bytes = lua_tolstring ( state, 1, &size );
		USHexDump::DumpAsCPPHeader ( memStream, name, bytes, size, columns );
	}
	
	MOAIDataBuffer* dataBuffer = state.GetLuaObject < MOAIDataBuffer >( 1, true );
	if ( dataBuffer ) {
		
		size_t size;
		void* bytes;
		dataBuffer->Lock ( &bytes, &size );
		USHexDump::DumpAsCPPHeader ( memStream, name, bytes, size, columns );
	}
	
	if ( memStream.GetLength ()) {
		
		memStream.Seek ( 0, SEEK_SET );
		STLString result = memStream.ReadString ( memStream.GetLength ());
		
		lua_pushstring ( state, result );
		return 1;
	}
	return 0;
}
예제 #19
0
//----------------------------------------------------------------//
int MOAIApp::_showDialog ( lua_State* L ) {
	MOAILuaState state ( L );
	
	cc8* title = state.GetValue < cc8* >( 1, "" );
	cc8* message = state.GetValue < cc8* >( 2, "" );
	cc8* positive = state.GetValue < cc8* >( 3, "" );
	cc8* neutral = state.GetValue < cc8* >( 4, "" );
	cc8* negative = state.GetValue < cc8* >( 5, "" );
	bool cancelable = state.GetValue < bool >( 6, "" );
	
	if ( state.IsType ( 7, LUA_TFUNCTION )) {
		// NOTE: This is fragile. We're storing the callback function in a global variable,
		// effectively. Invoking the showDialog method multiple times in succession can
		// therefore lead to unpredictable results. In fact, it's unknown how Android itself
		// handles multiple invocations - are they queued? On iOS, UIAlertView is LIFO and
		// new invocations supersede previous ones, but once dismissed, the system continues
		// down the alert stack... 
		MOAIApp::Get ().mDialogCallback.SetStrongRef ( state, 7 );
	}	
		
	MOAIApp::Get ().showDialogFunc ( title, message, positive, neutral, negative, cancelable );
	
	return 0;
}
예제 #20
0
/**	@name	init
	@text	Initialize AdColony.
	
	@in		string	appId			Available in AdColony dashboard settings.
	@in 	table	zones			A list of zones to configure. Available in AdColony dashboard settings.
	@out 	nil
*/
int MOAIAdColonyAndroid::_init ( lua_State* L ) {
	
	MOAILuaState state ( L );
     
	cc8* identifier = lua_tostring ( state, 1 );
	
	JNI_GET_ENV ( jvm, env );
	
	JNI_GET_JSTRING ( identifier, jidentifier );
		
	jobjectArray jzones = NULL;
	
	if ( state.IsType ( 2, LUA_TTABLE )) {
	
		int numEntries = 0;
		for ( int key = 1; ; ++key ) {
	
			state.GetField ( 2, key );
			cc8* value = _luaParseTable ( state, -1 );
			lua_pop ( state, 1 );
	
			if ( !value ) {
				
				numEntries = key - 1;
				break;
			}
		}
	
		jzones = env->NewObjectArray ( numEntries, env->FindClass( "java/lang/String" ), 0 );
		for ( int key = 1; ; ++key ) {
	
			state.GetField ( 2, key );
			cc8* value = _luaParseTable ( state, -1 );
			lua_pop ( state, 1 );
	
			if ( value ) {
				
				JNI_GET_JSTRING ( value, jvalue );
				env->SetObjectArrayElement ( jzones, key - 1, jvalue );
			}
			else {
				
				break;
			}	
		}
	}
	
	if ( jzones == NULL ) {
		
		jzones = env->NewObjectArray ( 0, env->FindClass( "java/lang/String" ), 0 );
	}
	
	jclass adcolony = env->FindClass ( "com/ziplinegames/moai/MoaiAdColony" );
    if ( adcolony == NULL ) {

		ZLLog::Print ( "MOAIAdColonyAndroid: Unable to find java class %s", "com/ziplinegames/moai/MoaiAdColony" );
    } else {

    	jmethodID init = env->GetStaticMethodID ( adcolony, "init", "(Ljava/lang/String;[Ljava/lang/String;)V" );
    	if ( init == NULL ) {

			ZLLog::Print ( "MOAIAdColonyAndroid: Unable to find static java method %s", "init" );
    	} else {

			env->CallStaticVoidMethod ( adcolony, init, jidentifier, jzones );				
		}
	}
	    
	return 0;
}
예제 #21
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;
}
예제 #22
0
/**	@name	login
	@text	Prompt the user to login to Facebook.
				
	@opt	table	permissions			Optional set of required permissions. See Facebook documentation for a full list. Default is nil.
	@out 	nil
*/
int MOAIFacebookAndroid::_login ( lua_State *L ) {
	
	MOAILuaState state ( L );
	
	JNI_GET_ENV ( jvm, env );
	
	jobjectArray jpermissions = NULL;
	
	if ( state.IsType ( 1, LUA_TTABLE )) {
	
		int numEntries = 0;
		for ( int key = 1; ; ++key ) {
	
			state.GetField ( 1, key );
			cc8* value = _luaParseTable ( state, -1 );
			lua_pop ( state, 1 );
	
			if ( !value ) {
				
				numEntries = key - 1;
				break;
			}
		}
	
		jpermissions = env->NewObjectArray ( numEntries, env->FindClass( "java/lang/String" ), 0 );
		for ( int key = 1; ; ++key ) {
	
			state.GetField ( 1, key );
			cc8* value = _luaParseTable ( state, -1 );
			lua_pop ( state, 1 );
	
			if ( value ) {
				
				JNI_GET_JSTRING ( value, jvalue );
				env->SetObjectArrayElement ( jpermissions, key - 1, jvalue );
			}
			else {
				
				break;
			}	
		}
	}
	
	if ( jpermissions == NULL ) {
		
		jpermissions = env->NewObjectArray ( 0, env->FindClass( "java/lang/String" ), 0 );
	}
	
	jclass facebook = env->FindClass ( "com/ziplinegames/moai/MoaiFacebook" );
    if ( facebook == NULL ) {

		ZLLog::Print ( "MOAIFacebookAndroid: Unable to find java class %s", "com/ziplinegames/moai/MoaiFacebook" );
    } else {

    	jmethodID login = env->GetStaticMethodID ( facebook, "login", "([Ljava/lang/String;)V" );
    	if ( login == NULL ) {

			ZLLog::Print ( "MOAIFacebookAndroid: Unable to find static java method %s", "login" );
    	} else {

			env->CallStaticVoidMethod ( facebook, login, jpermissions );				
		}
	}
		
	return 0;
}
예제 #23
0
//----------------------------------------------------------------//
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;
}