mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-29 08:34:37 +01:00
Back out change adding Looper. Using own queue is better because its
length can be tested and there's no race condition (between the looper being available and the parent thread wanting to post messages) when the constructor inits the queue.
This commit is contained in:
parent
5c183acb5e
commit
69c8577dcb
2 changed files with 115 additions and 124 deletions
|
@ -51,7 +51,6 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
|||
private Intent m_resultIntent = null;
|
||||
|
||||
private JNIThread m_jniThread;
|
||||
private JNIThread m_jniThread_pending;
|
||||
|
||||
public class TimerRunnable implements Runnable {
|
||||
private int m_gamePtr;
|
||||
|
@ -65,10 +64,8 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
|||
}
|
||||
public void run() {
|
||||
m_timers[m_why] = null;
|
||||
if ( null != m_jniThread ) {
|
||||
m_jniThread.handle( JNICmd.CMD_TIMER_FIRED,
|
||||
m_jniThread.handle( JNICmd.CMD_TIMER_FIRED,
|
||||
m_why, m_when, m_handle );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,26 +155,22 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
|||
m_prefs, null, dictBytes );
|
||||
}
|
||||
|
||||
m_jniThread_pending = new
|
||||
m_jniThread = new
|
||||
JNIThread( m_jniGamePtr,
|
||||
new Handler() {
|
||||
public void handleMessage( Message msg ) {
|
||||
Utils.logf( "handleMessage() called" );
|
||||
switch( msg.what ) {
|
||||
case JNIThread.RUNNING:
|
||||
m_jniThread = m_jniThread_pending;
|
||||
m_view.startHandling( m_jniThread,
|
||||
m_jniGamePtr,
|
||||
m_gi );
|
||||
m_jniThread.handle( JNICmd.CMD_DO );
|
||||
break;
|
||||
case JNIThread.DRAW:
|
||||
m_view.invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} );
|
||||
m_jniThread_pending.start();
|
||||
m_jniThread.start();
|
||||
|
||||
m_view.startHandling( m_jniThread, m_jniGamePtr, m_gi );
|
||||
m_jniThread.handle( JNICmd.CMD_DO );
|
||||
|
||||
Utils.logf( "BoardActivity::onCreate() done" );
|
||||
} // onCreate
|
||||
|
@ -285,10 +278,8 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
|||
handled = false;
|
||||
}
|
||||
|
||||
if ( handled && cmd != JNIThread.JNICmd.CMD_NONE ) {
|
||||
if ( null != m_jniThread ) {
|
||||
m_jniThread.handle( cmd );
|
||||
}
|
||||
if ( handled && cmd != JNIThread.JNICmd.CMD_NONE ) {
|
||||
m_jniThread.handle( cmd );
|
||||
}
|
||||
|
||||
return handled;
|
||||
|
@ -433,7 +424,7 @@ public class BoardActivity extends Activity implements XW_UtilCtxt, Runnable {
|
|||
|
||||
public boolean engineProgressCallback()
|
||||
{
|
||||
return null != m_jniThread && !m_jniThread.busy();
|
||||
return ! m_jniThread.busy();
|
||||
}
|
||||
|
||||
public String getUserString( int stringCode )
|
||||
|
|
|
@ -9,7 +9,6 @@ import java.lang.InterruptedException;
|
|||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Looper;
|
||||
|
||||
public class JNIThread extends Thread {
|
||||
|
||||
|
@ -30,26 +29,36 @@ public class JNIThread extends Thread {
|
|||
CMD_HINT,
|
||||
CMD_NEXT_HINT,
|
||||
CMD_VALUES,
|
||||
|
||||
CMD_STOP,
|
||||
};
|
||||
|
||||
public static final int RUNNING = 1;
|
||||
public static final int DRAW = 2;
|
||||
|
||||
private boolean m_stopped = false;
|
||||
private int m_jniGamePtr;
|
||||
private Handler m_parentHandler;
|
||||
private Handler m_loopHandler;
|
||||
private boolean[] m_barr = new boolean[1]; // scratch boolean
|
||||
|
||||
private Handler m_handler;
|
||||
LinkedBlockingQueue<QueueElem> m_queue;
|
||||
|
||||
private class QueueElem {
|
||||
protected QueueElem( JNICmd cmd, Object[] args )
|
||||
{
|
||||
m_cmd = cmd; m_args = args;
|
||||
}
|
||||
JNICmd m_cmd;
|
||||
Object[] m_args;
|
||||
}
|
||||
|
||||
public JNIThread( int gamePtr, Handler handler ) {
|
||||
Utils.logf( "in JNIThread()" );
|
||||
m_jniGamePtr = gamePtr;
|
||||
m_parentHandler = handler;
|
||||
m_handler = handler;
|
||||
|
||||
m_queue = new LinkedBlockingQueue<QueueElem>();
|
||||
}
|
||||
|
||||
public void waitToStop() {
|
||||
handle( JNICmd.CMD_STOP );
|
||||
m_stopped = true;
|
||||
handle( JNICmd.CMD_NONE ); // tickle it
|
||||
try {
|
||||
join();
|
||||
} catch ( java.lang.InterruptedException ie ) {
|
||||
|
@ -58,10 +67,9 @@ public class JNIThread extends Thread {
|
|||
}
|
||||
|
||||
public boolean busy()
|
||||
{
|
||||
// HTF to I tell if my queue has anything in it. Do I have to
|
||||
// keep a counter? Which means synchronizing...
|
||||
return false;
|
||||
{ // synchronize this!!!
|
||||
int siz = m_queue.size();
|
||||
return siz > 0;
|
||||
}
|
||||
|
||||
private boolean toggleTray() {
|
||||
|
@ -77,111 +85,103 @@ public class JNIThread extends Thread {
|
|||
|
||||
public void run()
|
||||
{
|
||||
Looper.prepare();
|
||||
|
||||
m_loopHandler = new Handler() {
|
||||
public void handleMessage( Message msg ) {
|
||||
boolean draw = false;
|
||||
Object[] args = (Object[])msg.obj;
|
||||
switch( JNICmd.values()[msg.what] ) {
|
||||
boolean[] barr = new boolean[1]; // scratch boolean
|
||||
while ( !m_stopped ) {
|
||||
QueueElem elem;
|
||||
Object[] args;
|
||||
try {
|
||||
elem = m_queue.take();
|
||||
} catch ( InterruptedException ie ) {
|
||||
Utils.logf( "interrupted; killing thread" );
|
||||
break;
|
||||
}
|
||||
boolean draw = false;
|
||||
args = elem.m_args;
|
||||
switch( elem.m_cmd ) {
|
||||
|
||||
case CMD_DRAW:
|
||||
draw = true;
|
||||
break;
|
||||
case CMD_DO:
|
||||
draw = XwJNI.server_do( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_DRAW:
|
||||
draw = true;
|
||||
break;
|
||||
case CMD_DO:
|
||||
draw = XwJNI.server_do( m_jniGamePtr );
|
||||
break;
|
||||
|
||||
case CMD_PEN_DOWN:
|
||||
draw = XwJNI.board_handlePenDown( m_jniGamePtr,
|
||||
((Integer)args[0]).intValue(),
|
||||
((Integer)args[1]).intValue(),
|
||||
m_barr );
|
||||
break;
|
||||
case CMD_PEN_MOVE:
|
||||
draw = XwJNI.board_handlePenMove( m_jniGamePtr,
|
||||
((Integer)args[0]).intValue(),
|
||||
((Integer)args[1]).intValue() );
|
||||
break;
|
||||
case CMD_PEN_UP:
|
||||
draw = XwJNI.board_handlePenUp( m_jniGamePtr,
|
||||
((Integer)args[0]).intValue(),
|
||||
((Integer)args[1]).intValue() );
|
||||
break;
|
||||
case CMD_PEN_DOWN:
|
||||
draw = XwJNI.board_handlePenDown( m_jniGamePtr,
|
||||
((Integer)args[0]).intValue(),
|
||||
((Integer)args[1]).intValue(),
|
||||
barr );
|
||||
break;
|
||||
case CMD_PEN_MOVE:
|
||||
draw = XwJNI.board_handlePenMove( m_jniGamePtr,
|
||||
((Integer)args[0]).intValue(),
|
||||
((Integer)args[1]).intValue() );
|
||||
break;
|
||||
case CMD_PEN_UP:
|
||||
draw = XwJNI.board_handlePenUp( m_jniGamePtr,
|
||||
((Integer)args[0]).intValue(),
|
||||
((Integer)args[1]).intValue() );
|
||||
break;
|
||||
|
||||
case CMD_COMMIT:
|
||||
draw = XwJNI.board_commitTurn( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_COMMIT:
|
||||
draw = XwJNI.board_commitTurn( m_jniGamePtr );
|
||||
break;
|
||||
|
||||
case CMD_JUGGLE:
|
||||
draw = XwJNI.board_juggleTray( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_FLIP:
|
||||
draw = XwJNI.board_flip( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_TOGGLE_TRAY:
|
||||
draw = toggleTray();
|
||||
break;
|
||||
case CMD_TOGGLE_TRADE:
|
||||
draw = XwJNI.board_beginTrade( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_UNDO_CUR:
|
||||
draw = XwJNI.board_replaceTiles( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_UNDO_LAST:
|
||||
XwJNI.server_handleUndo( m_jniGamePtr );
|
||||
draw = true;
|
||||
break;
|
||||
case CMD_JUGGLE:
|
||||
draw = XwJNI.board_juggleTray( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_FLIP:
|
||||
draw = XwJNI.board_flip( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_TOGGLE_TRAY:
|
||||
draw = toggleTray();
|
||||
break;
|
||||
case CMD_TOGGLE_TRADE:
|
||||
draw = XwJNI.board_beginTrade( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_UNDO_CUR:
|
||||
draw = XwJNI.board_replaceTiles( m_jniGamePtr );
|
||||
break;
|
||||
case CMD_UNDO_LAST:
|
||||
XwJNI.server_handleUndo( m_jniGamePtr );
|
||||
draw = true;
|
||||
break;
|
||||
|
||||
case CMD_HINT:
|
||||
XwJNI.board_resetEngine( m_jniGamePtr );
|
||||
// fallthru
|
||||
case CMD_NEXT_HINT:
|
||||
draw = XwJNI.board_requestHint( m_jniGamePtr, false, m_barr );
|
||||
if ( m_barr[0] ) {
|
||||
handle( JNICmd.CMD_NEXT_HINT );
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_VALUES:
|
||||
draw = XwJNI.board_toggle_showValues( m_jniGamePtr );
|
||||
break;
|
||||
|
||||
case CMD_TIMER_FIRED:
|
||||
draw = XwJNI.timerFired( m_jniGamePtr,
|
||||
((Integer)args[0]).intValue(),
|
||||
((Integer)args[1]).intValue(),
|
||||
((Integer)args[2]).intValue() );
|
||||
break;
|
||||
|
||||
case CMD_STOP:
|
||||
Looper.myLooper().quit();
|
||||
break;
|
||||
}
|
||||
|
||||
if ( draw ) {
|
||||
if ( !XwJNI.board_draw( m_jniGamePtr ) ) {
|
||||
Utils.logf( "draw not complete" );
|
||||
}
|
||||
Message.obtain( m_parentHandler, DRAW ).sendToTarget();
|
||||
}
|
||||
case CMD_HINT:
|
||||
XwJNI.board_resetEngine( m_jniGamePtr );
|
||||
// fallthru
|
||||
case CMD_NEXT_HINT:
|
||||
draw = XwJNI.board_requestHint( m_jniGamePtr, false, barr );
|
||||
if ( barr[0] ) {
|
||||
handle( JNICmd.CMD_NEXT_HINT );
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
// Safe to use us now
|
||||
Message.obtain( m_parentHandler, RUNNING ).sendToTarget();
|
||||
|
||||
Looper.loop();
|
||||
case CMD_VALUES:
|
||||
draw = XwJNI.board_toggle_showValues( m_jniGamePtr );
|
||||
break;
|
||||
|
||||
case CMD_TIMER_FIRED:
|
||||
draw = XwJNI.timerFired( m_jniGamePtr,
|
||||
((Integer)args[0]).intValue(),
|
||||
((Integer)args[1]).intValue(),
|
||||
((Integer)args[2]).intValue() );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( draw ) {
|
||||
if ( !XwJNI.board_draw( m_jniGamePtr ) ) {
|
||||
Utils.logf( "draw not complete" );
|
||||
}
|
||||
Message.obtain( m_handler, DRAW ).sendToTarget();
|
||||
}
|
||||
}
|
||||
Utils.logf( "run exiting" );
|
||||
} // run
|
||||
|
||||
|
||||
/** Post a cmd to be handled by the JNI thread
|
||||
*/
|
||||
public void handle( JNICmd cmd, Object... args )
|
||||
{
|
||||
Message message = Message.obtain( m_loopHandler, cmd.ordinal(), args );
|
||||
message.sendToTarget();
|
||||
QueueElem elem = new QueueElem( cmd, args );
|
||||
m_queue.add( elem );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue