Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
How to code a good Event Dispatcher for Android plugin - Gideros Forum

How to code a good Event Dispatcher for Android plugin

RickyngkRickyngk Member
edited April 2013 in General questions
Hi,

I write a function which detect Android Ringer mode changed

MyActivity.java
public class MyActivity extends Activity
{
	<a href="/profile/Override">@Override</a>
	public void onCreate(Bundle savedInstanceState)
	{
		....
		IntentFilter filter=new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
		registerReceiver(mRingerReceiver,filter);
	}
 
	private final BroadcastReceiver mRingerReceiver = new BroadcastReceiver() 
	{
		<a href="/profile/Override">@Override</a>
		public void onReceive(Context context, Intent intent) 
		{
			String params[] = {"mode", GetRingerMode() + ""};
			DispatchLua("gGameInstance", "OnRingerModeChanged", params);
		}
	};
 
 
	static void DispatchLua(String receiver, String func, String[] keys_value)
	{
		NativeLuaBridgeDispatchEvent(receiver, func, keys_value);
	}
 
	public static native void NativeLuaBridgeDispatchEvent(String receiver, String func, String[] kv);
}
Native
typedef struct _CGuava7LuaBridgeEvent {
	const char * key;
	const char * value;
}CGuava7LuaBridgeEvent;
 
JNIEXPORT void JNICALL Java_com_giderosmobile_android_MyActivity_NativeLuaBridgeDispatchEvent(JNIEnv * env, jobject obj, jstring receiver, jstring func, jobjectArray _keys_values)
{
	const char *_func = (*env).GetStringUTFChars(func, 0);
	const char *_rec = (*env).GetStringUTFChars(receiver, 0);
	int n = 0;
	if (_keys_values) n = ((*env).GetArrayLength(_keys_values))>>1;
 
	CGuava7LuaBridgeEvent event[512];
	bool p_release[512];
	jstring key[512];
	jstring value[512];
 
	for (int i = 0; i < n; i++)
	{
		key[i] = (jstring) (*env).GetObjectArrayElement(_keys_values, i<<1);
		value[i] = (jstring) (*env).GetObjectArrayElement(_keys_values, (i<<1) + 1);
		if (key[i] && value[i])
		{
			event[i].key = (*env).GetStringUTFChars(key[i], 0);
			event[i].value = (*env).GetStringUTFChars(value[i], 0);
			p_release[i] = true;
		}
		else
		{
			event[i].key = "null";
			event[i].value = "null";
			p_release[i] = false;
		}
	}
	gv7_luabridgeDispatchEvent(_rec, _func, n, event);
 
	for (int i = 0; i < n; i++)
	{
		if (p_release[i])
		{
			(*env).ReleaseStringUTFChars(key[i], event[i].key);
			(*env).ReleaseStringUTFChars(value[i], event[i].value);
		}
	}
   (*env).ReleaseStringUTFChars(func, _func);
   (*env).ReleaseStringUTFChars(receiver, _rec);
}
 
 
void gv7_luabridgeDispatchEvent(const char* receiver, const char* func, int n, CGuava7LuaBridgeEvent* event)
{
	if (L)
	{
		lua_getglobal(L, receiver);
		if (!lua_isnil(L, -1))
		{
			lua_getfield(L, -1, "dispatchEvent");	// get the dispatchEvent function of receiver
			lua_pushvalue(L, -2);	// duplicate receiver, this will be the 1st parameter of dispatchEvent
 
			// create an Event object (this will be the 2nd parameter of dispatchEvent)
			lua_getglobal(L, "Event");		// get the global Event table
			lua_getfield(L, -1, "new");		// get its new function
			lua_remove(L, -2);				// remove the global Event table
			lua_pushstring(L, func);
			lua_call(L, 1, 1);				// call as Event.new("complete")
 
			if (event)
			{
				for (int i = 0; i < n; i++)
				{
					lua_pushstring(L, event->value);
					lua_setfield(L, -2, event->key);
				}
			}
			__android_log_print(ANDROID_LOG_INFO, "CGuava7LuaBridge", "DispatchEvent: %s %s %d\n",receiver,func,n);
			if (lua_pcall(L, 2, 0, 0) != 0)  // call dispatchEvent with receiver and event
			{
				__android_log_print(ANDROID_LOG_INFO, "CGuava7LuaBridge", "!!! error when DispatchEvent function %s %s: %s\n",receiver, func, lua_tostring(L, -1));
			}
		}
		else
		{
			__android_log_print(ANDROID_LOG_INFO, "CGuava7LuaBridge", "!!! DispatchEvent receiver NOT FOUND");
		}
		lua_pop(L, 1);	// pop nil or receiver
	}
}

It usually runs properly. But sometimes crashed with vary reasons. Did I do something wrong with Event Dispatcher ?

Thx,

Comments

Sign In or Register to comment.