refactor message receiving/distributing code into superclass.

This commit is contained in:
Eric House 2016-04-11 06:01:25 -07:00
parent f288fe2860
commit 33225f3bc5
5 changed files with 87 additions and 111 deletions

View file

@ -55,6 +55,7 @@ import org.eehouse.android.xw4.jni.LastMoveInfo;
import org.eehouse.android.xw4.jni.XwJNI;
import org.eehouse.android.xw4.jni.JNIThread;
import org.eehouse.android.xw4.loc.LocUtils;
import org.eehouse.android.xw4.XWService.ReceiveResult;
import junit.framework.Assert;
@ -574,47 +575,20 @@ public class BTService extends XWService {
BluetoothDevice host = socket.getRemoteDevice();
addAddr( host );
// check if still here
long[] rowids = DBUtils.getRowIDsFor( BTService.this,
gameID );
boolean haveGame = null != rowids && 0 < rowids.length;
BTCmd result = haveGame ?
BTCmd.MESG_ACCPT : BTCmd.MESG_GAMEGONE;
CommsAddrRec addr = new CommsAddrRec( host.getName(),
host.getAddress() );
ReceiveResult rslt
= BTService.this.receiveMessage( BTService.this, gameID,
m_btMsgSink, buffer, addr );
BTCmd result = rslt == ReceiveResult.GAME_GONE ?
BTCmd.MESG_GAMEGONE : BTCmd.MESG_ACCPT;
DataOutputStream os =
new DataOutputStream( socket.getOutputStream() );
os.writeByte( result.ordinal() );
os.flush();
socket.close();
CommsAddrRec addr = new CommsAddrRec( host.getName(),
host.getAddress() );
boolean[] isLocalP = new boolean[1];
for ( long rowid : rowids ) {
JNIThread jniThread = JNIThread.getRetained( rowid, false );
boolean consumed = false;
if ( null != jniThread ) {
consumed = true;
jniThread.receive( buffer, addr ).release();
} else if ( haveGame ) {
GameUtils.BackMoveResult bmr =
new GameUtils.BackMoveResult();
if ( GameUtils.feedMessage( BTService.this, rowid,
buffer, addr,
m_btMsgSink, bmr,
isLocalP ) ) {
consumed = true;
GameUtils.postMoveNotification( BTService.this,
rowid, bmr,
isLocalP[0] );
}
}
if ( !consumed ) {
DbgUtils.logf( "nobody took msg for gameID %X",
gameID );
}
}
} else {
DbgUtils.logf( "receiveMessages: read only %d of %d bytes",
nRead, len );

View file

@ -50,7 +50,7 @@ public class MultiMsgSink implements TransportProcs {
// rowID is used as token to identify game on relay. Anything that
// uniquely identifies a game on a device would work
public long getRowID() { return m_rowid; };
public void setRowID( long rowID ) { m_rowid = rowID; };
public MultiMsgSink setRowID( long rowID ) { m_rowid = rowID; return this; };
// These will be overridden by e.g. BTService which for sendViaBluetooth()
// can just insert a message into its queue

View file

@ -317,6 +317,12 @@ public class RelayService extends XWService
return intent;
}
@Override
protected MultiMsgSink getSink( long rowid )
{
return new RelayMsgSink().setRowID( rowid );
}
@Override
public void onCreate()
{
@ -400,7 +406,7 @@ public class RelayService extends XWService
String relayID = intent.getStringExtra( RELAY_ID );
sendNoConnMessage( rowid, relayID, msg );
} else {
feedMessage( rowid, msg );
receiveMessage( this, rowid, null, msg, s_addr );
}
break;
case INVITE:
@ -996,28 +1002,6 @@ public class RelayService extends XWService
return devid;
}
private void feedMessage( long rowid, byte[] msg )
{
DbgUtils.logdf( "RelayService::feedMessage: %d bytes for rowid %d",
msg.length, rowid );
JNIThread jniThread = JNIThread.getRetained( rowid, false );
if ( null != jniThread ) {
jniThread.receive( msg, s_addr ).release();
DbgUtils.logdf( "RelayService.feedMessage(): jniThread.receive() ate it" );
} else {
RelayMsgSink sink = new RelayMsgSink();
sink.setRowID( rowid );
BackMoveResult bmr = new BackMoveResult();
boolean[] isLocalP = new boolean[1];
if ( GameUtils.feedMessage( this, rowid, msg, s_addr,
sink, bmr, isLocalP ) ) {
GameUtils.postMoveNotification( this, rowid, bmr, isLocalP[0] );
} else {
DbgUtils.logdf( "feedMessage(): background dropped it" );
}
}
}
private void fetchAndProcess()
{
long[][] rowIDss = new long[1][];
@ -1041,45 +1025,14 @@ public class RelayService extends XWService
boolean[] isLocalP = new boolean[1];
for ( int ii = 0; ii < nameCount; ++ii ) {
byte[][] forOne = msgs[ii];
// if game has messages, open it and feed 'em to it.
if ( null != forOne ) {
BackMoveResult bmr = new BackMoveResult();
long rowid = rowIDs[ii];
sink.setRowID( rowid );
// since BoardDelegate.feedMessages can't know:
isLocalP[0] = false;
boolean delivered = true;
JNIThread jniThread = JNIThread.getRetained( rowid, false );
if ( null != jniThread ) {
for ( byte[] msg : forOne ) {
jniThread.receive( msg, s_addr );
}
jniThread.release();
} else if ( GameUtils.feedMessages( this, rowid, forOne, s_addr,
sink, bmr, isLocalP ) ) {
} else {
delivered = false;
}
if ( delivered ) {
idsWMsgs.add( relayIDs[ii] );
bmrs.add( bmr );
isLocals.add( isLocalP[0] );
} else {
DbgUtils.logf( "RelayService.process(): message for %s (rowid %d)"
+ " not consumed", relayIDs[ii], rowid );
for ( byte[] msg : forOne ) {
receiveMessage( this, rowid, sink, msg, s_addr );
}
}
}
if ( 0 < idsWMsgs.size() ) {
String[] tmp = new String[idsWMsgs.size()];
idsWMsgs.toArray( tmp );
BackMoveResult[] bmrsa = new BackMoveResult[bmrs.size()];
bmrs.toArray( bmrsa );
setupNotifications( tmp, bmrsa, isLocals );
}
sink.send( this );
}
}

View file

@ -55,6 +55,7 @@ import java.util.Set;
import junit.framework.Assert;
import org.eehouse.android.xw4.XWService.ReceiveResult;
import org.eehouse.android.xw4.GameUtils.BackMoveResult;
import org.eehouse.android.xw4.MultiService.DictFetchOwner;
import org.eehouse.android.xw4.MultiService.MultiEvent;
@ -288,6 +289,12 @@ public class SMSService extends XWService {
return s_showToasts;
}
@Override // abstract
protected MultiMsgSink getSink( long rowid )
{
return new SMSMsgSink( this );
}
@Override
public void onCreate()
{
@ -704,25 +711,9 @@ public class SMSService extends XWService {
private void feedMessage( int gameID, byte[] msg, CommsAddrRec addr )
{
long[] rowids = DBUtils.getRowIDsFor( this, gameID );
if ( null == rowids || 0 == rowids.length ) {
ReceiveResult rslt = receiveMessage( this, gameID, null, msg, addr );
if ( ReceiveResult.GAME_GONE == rslt ) {
sendDiedPacket( addr.sms_phone, gameID );
} else {
boolean[] isLocalP = new boolean[1];
for ( long rowid : rowids ) {
JNIThread jniThread = JNIThread.getRetained( rowid, false );
if ( null != jniThread ) {
jniThread.receive( msg, addr ).release();
} else {
SMSMsgSink sink = new SMSMsgSink( this );
BackMoveResult bmr = new BackMoveResult();
if ( GameUtils.feedMessage( this, rowid, msg, addr,
sink, bmr, isLocalP ) ) {
GameUtils.postMoveNotification( this, rowid, bmr,
isLocalP[0] );
}
}
}
}
}

View file

@ -21,17 +21,23 @@
package org.eehouse.android.xw4;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import java.util.HashSet;
import java.util.Set;
import junit.framework.Assert;
import org.eehouse.android.xw4.MultiService.MultiEvent;
import org.eehouse.android.xw4.jni.CommsAddrRec;
import org.eehouse.android.xw4.jni.JNIThread;
import org.eehouse.android.xw4.jni.UtilCtxt;
import org.eehouse.android.xw4.jni.UtilCtxtImpl;
public class XWService extends Service {
class XWService extends Service {
public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED };
protected static MultiService s_srcMgr = null;
private static Set<String> s_seen = new HashSet<String>();
@ -85,4 +91,56 @@ public class XWService extends Service {
}
return m_utilCtxt;
}
// Meant to be overridden
protected MultiMsgSink getSink( long rowid ) { Assert.fail(); return null; }
protected ReceiveResult receiveMessage( Context context, int gameID,
MultiMsgSink sink, byte[] msg,
CommsAddrRec addr )
{
ReceiveResult result;
long[] rowids = DBUtils.getRowIDsFor( context, gameID );
if ( null == rowids || 0 == rowids.length ) {
result = ReceiveResult.GAME_GONE;
} else {
result = ReceiveResult.UNCONSUMED;
for ( long rowid : rowids ) {
if ( receiveMessage( context, rowid, sink, msg, addr ) ) {
result = ReceiveResult.OK;
}
}
}
return result;
}
protected boolean receiveMessage( Context context, long rowid,
MultiMsgSink sink, byte[] msg,
CommsAddrRec addr )
{
boolean allConsumed = true;
boolean[] isLocalP = new boolean[1];
JNIThread jniThread = JNIThread.getRetained( rowid, false );
boolean consumed = false;
if ( null != jniThread ) {
consumed = true;
jniThread.receive( msg, addr ).release();
} else {
GameUtils.BackMoveResult bmr =
new GameUtils.BackMoveResult();
if ( null == sink ) {
sink = getSink( rowid );
}
if ( GameUtils.feedMessage( context, rowid, msg, addr,
sink, bmr, isLocalP ) ) {
consumed = true;
GameUtils.postMoveNotification( context, rowid, bmr,
isLocalP[0] );
}
}
if ( allConsumed && !consumed ) {
allConsumed = false;
}
return allConsumed;
}
}