Hello Droid devs,

I'm porting C application using NDK and have problems with proper touch 
events handling. I tried to apply the solution with "event queue" (here 
http://www.rbgrn.net/content/342-using-input-pipelines-your-android-game)  but 
from some reason the event processing locks the aplication when events are 
rapidly fired on the Java side. Here is the scenario:
-The native C code is executed in separate thread.(precisely HandlerThread)
-Once the native code is executed it goes to SELECT() based loop waiting 
for network changes.
-then in the SELECT() loop it calls Java side(thru JNI) to poll for any 
touch events (pollEvents()) that could be available in the Java event queue.
-Events in the queue are processed using native call (dispatchEvent()) back 
to the C code

But at some point(when lot of MOVE events is generated by user) the 
pollEvents() 
function stops being called (because the C side is busy with all the event 
processing??) and only feedInput() calls are made. This leads to 
application lock because there is no more free event instances available in 
the Java pool putting the inputObjectPool.take() call to waiting and the 
app stops responding.
It all seems to be logical to me but I don't understand why the C thread 
stops processing when inputObjectPool.take() call waits in the UI thread? I 
thought while the UI thread waits the C thread can catch up, process the 
pending events and put 'used' event instances back to the pool so the 
waiting is canceled and UI thread can continue? Am I missing something here?

I hope my explanation is not too confusing so if you get to this point you 
may look at the code below to see what I'm trying to achieve.
Any helpful feedback is welcome!

Thanks,

Rick

Here is simplified code part:

loop on the C side:

while (1) {
if (halted) break;
...
//poll for network changes etc.(using BSD sockets)
...
//call pollEvents() on Java side to check and process events
(*jni_env)->CallVoidMethod(jni_env, jni_obj, jni_pollEvents);
..
select(...); //wait for 16msecs
}

Java side:

private final Object inputQueueMutex = new Object();
private native void dispatchEvent(int action, int x, int y);

public void pollEvents(){
synchronized(inputQueueMutex) {
ArrayBlockingQueue<InputObject> inputQueue = this.inputQueue;
while (!inputQueue.isEmpty()) {
//process the events in queue
try {
InputObject input = inputQueue.take();
//following function dispathes the event for processing on the C side
dispatchEvent(input.action, input.x, input.y);
input.returnToPool();
} catch (InterruptedException e) {
}
}
}
}

public void feedInput(InputObject input) {
synchronized(inputQueueMutex) {
try {
//queue the event
inputQueue.put(input);
} catch (InterruptedException e) {
}
}
}

@Override
public boolean onTouchEvent(final MotionEvent event) {
try {
//get "free" instance from the pool
InputObject input = inputObjectPool.take();
//fill the event data and detect event type 
if (!input.useEvent(event)) {
//let OS process events we don't care about
input.returnToPool();
return false;
}
//queue the event
feedInput(input);
} catch (InterruptedException e) {
}
// don't allow more than 60 motion events per second
try {
Thread.sleep(16);
} catch (InterruptedException e) {
}
return true;
} 


-- 
-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to android-developers+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to