From dc1431fd08b3749d678b960f6d04bfd2f15767f0 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 12 Feb 2019 06:13:36 -0800 Subject: [PATCH] make GamePtr AutoCloseable and use where possible --- .../eehouse/android/xw4/BoardDelegate.java | 33 ++- .../org/eehouse/android/xw4/BoardView.java | 2 +- .../org/eehouse/android/xw4/DelegateBase.java | 9 +- .../android/xw4/GameConfigDelegate.java | 184 ++++++------ .../org/eehouse/android/xw4/GameUtils.java | 276 +++++++++--------- .../eehouse/android/xw4/jni/JNIThread.java | 8 +- .../org/eehouse/android/xw4/jni/XwJNI.java | 12 +- 7 files changed, 277 insertions(+), 247 deletions(-) diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java index fca8ad21e..85de8e13a 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java @@ -2074,7 +2074,7 @@ public class BoardDelegate extends DelegateBase success = m_jniThreadRef.configure( m_activity, m_view, m_utils, this, makeJNIHandler() ); if ( success ) { - m_jniGamePtr = m_jniThreadRef.getGamePtr(); + m_jniGamePtr = m_jniThreadRef.getGamePtr(); // .retain()? Assert.assertNotNull( m_jniGamePtr ); } } @@ -2785,35 +2785,42 @@ public class BoardDelegate extends DelegateBase public static void setupRematchFor( Activity activity, long rowID ) { - GamePtr gamePtr = null; GameSummary summary = null; CurGameInfo gi = null; try ( JNIThread thread = JNIThread.getRetained( rowID ) ) { if ( null != thread ) { - gamePtr = thread.getGamePtr().retain(); - summary = thread.getSummary(); - gi = thread.getGI(); + try ( GamePtr gamePtr = thread.getGamePtr().retain() ) { + summary = thread.getSummary(); + gi = thread.getGI(); + setupRematchFor( activity, gamePtr, summary, gi ); + } } else { try ( GameLock lock = GameLock.tryLockRO( rowID ) ) { if ( null != lock ) { summary = DBUtils.getSummary( activity, lock ); gi = new CurGameInfo( activity ); - gamePtr = GameUtils.loadMakeGame( activity, gi, lock ); + try ( GamePtr gamePtr = GameUtils + .loadMakeGame( activity, gi, lock ) ) { + setupRematchFor( activity, gamePtr, summary, gi ); + } } else { DbgUtils.toastNoLock( TAG, activity, rowID, "setupRematchFor(%d)", rowID ); } } } + } + } - if ( null != gamePtr ) { - doRematchIf( activity, null, rowID, DBUtils.GROUPID_UNSPEC, - summary, gi, gamePtr ); - gamePtr.release(); - } else { - Log.w( TAG, "setupRematchFor(): unable to lock game" ); - } + private static void setupRematchFor( Activity activity, GamePtr gamePtr, + GameSummary summary, CurGameInfo gi ) + { + if ( null != gamePtr ) { + doRematchIf( activity, null, gamePtr.getRowid(), + DBUtils.GROUPID_UNSPEC, summary, gi, gamePtr ); + } else { + Log.w( TAG, "setupRematchFor(): unable to lock game" ); } } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardView.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardView.java index f290a6c94..58c117d5c 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardView.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardView.java @@ -298,7 +298,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw { Assert.assertTrue( null != parent || !BuildConfig.DEBUG ); m_parent = parent; m_jniThread = thread; - m_jniGamePtr = thread.getGamePtr(); + m_jniGamePtr = thread.getGamePtr(); // .retain()? m_gi = thread.getGI(); m_isSolo = CurGameInfo.DeviceRole.SERVER_STANDALONE == m_gi.serverRole; m_connTypes = connTypes; diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java index b8e62206c..c79f0e85a 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java @@ -670,10 +670,11 @@ public class DelegateBase implements DlgClickNotify, Log.d( TAG, "onStatusClicked(%d)", rowid ); try ( GameLock lock = GameLock.tryLockRO( rowid ) ) { if ( null != lock ) { - GamePtr gamePtr = GameUtils.loadMakeGame( getActivity(), lock ); - if ( null != gamePtr ) { - onStatusClicked( gamePtr ); - gamePtr.release(); + try ( GamePtr gamePtr = GameUtils + .loadMakeGame( getActivity(), lock ) ) { + if ( null != gamePtr ) { + onStatusClicked( gamePtr ); + } } } } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameConfigDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameConfigDelegate.java index a349a7ce5..d3e928a56 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameConfigDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameConfigDelegate.java @@ -536,102 +536,108 @@ public class GameConfigDelegate extends DelegateBase if ( null == m_giOrig ) { m_giOrig = new CurGameInfo( m_activity ); - XwJNI.GamePtr gamePtr = null; if ( null != m_jniThread ) { - gamePtr = m_jniThread.getGamePtr().retain(); + try ( XwJNI.GamePtr gamePtr = m_jniThread + .getGamePtr().retain() ) { + loadGame( gamePtr ); + } } else { try ( GameLock lock = GameLock.tryLockRO( m_rowid ) ) { if ( null != lock ) { - gamePtr = GameUtils.loadMakeGame( m_activity, m_giOrig, - lock ); - } - } - } - - if ( null == gamePtr ) { - Assert.assertFalse( BuildConfig.DEBUG ); - } else { - m_gameStarted = XwJNI.model_getNMoves( gamePtr ) > 0 - || XwJNI.comms_isConnected( gamePtr ); - - if ( m_gameStarted ) { - if ( null == m_gameLockedCheck ) { - m_gameLockedCheck = - (CheckBox)findViewById( R.id.game_locked_check ); - m_gameLockedCheck.setVisibility( View.VISIBLE ); - m_gameLockedCheck.setOnClickListener( this ); - } - handleLockedChange(); - } - - if ( null == m_gi ) { - m_gi = new CurGameInfo( m_giOrig ); - } - - m_carOrig = new CommsAddrRec(); - if ( XwJNI.game_hasComms( gamePtr ) ) { - XwJNI.comms_getAddr( gamePtr, m_carOrig ); - m_remoteAddrs = XwJNI.comms_getAddrs( gamePtr ); - } else if ( !localOnlyGame() ) { - String relayName = XWPrefs.getDefaultRelayHost( m_activity ); - int relayPort = XWPrefs.getDefaultRelayPort( m_activity ); - XwJNI.comms_getInitialAddr( m_carOrig, relayName, - relayPort ); - } - - // load if the first time through.... - if ( null == m_conTypes ) { - m_conTypes = (CommsConnTypeSet)m_carOrig.conTypes.clone(); - } - - buildDisabledsMap( gamePtr ); - setDisableds(); - - gamePtr.release(); - - m_car = new CommsAddrRec( m_carOrig ); - - setTitle(); - - TextView label = (TextView)findViewById( R.id.lang_separator ); - label.setText( getString( localOnlyGame() ? R.string.lang_label - : R.string.langdict_label ) ); - - m_dictSpinner = (Spinner)findViewById( R.id.dict_spinner ); - if ( localOnlyGame() ) { - m_dictSpinner.setVisibility( View.GONE ); - m_dictSpinner = null; - } - - setConnLabel(); - setupRelayStuffIf(); - loadPlayersList(); - configLangSpinner(); - - m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() ); - - setSmartnessSpinner(); - - setChecked( R.id.hints_allowed, !m_gi.hintsNotAllowed ); - setChecked( R.id.pick_faceup, m_gi.allowPickTiles ); - setInt( R.id.timer_minutes_edit, - m_gi.gameSeconds/60/m_gi.nPlayers ); - - CheckBox check = (CheckBox)findViewById( R.id.use_timer ); - OnCheckedChangeListener lstnr = - new OnCheckedChangeListener() { - public void onCheckedChanged( CompoundButton buttonView, - boolean checked ) { - showTimerSet( checked ); + try ( XwJNI.GamePtr gamePtr = GameUtils. + loadMakeGame( m_activity, m_giOrig, lock ) ) { + loadGame( gamePtr ); } - }; - check.setOnCheckedChangeListener( lstnr ); - setChecked( R.id.use_timer, m_gi.timerEnabled ); - showTimerSet( m_gi.timerEnabled ); - - setBoardsizeSpinner(); + } + } } } + } + + // Exists only to be called from inside two try-with-resource blocks above + private void loadGame( XwJNI.GamePtr gamePtr ) + { + if ( null == gamePtr ) { + Assert.assertFalse( BuildConfig.DEBUG ); + } else { + m_gameStarted = XwJNI.model_getNMoves( gamePtr ) > 0 + || XwJNI.comms_isConnected( gamePtr ); + + if ( m_gameStarted ) { + if ( null == m_gameLockedCheck ) { + m_gameLockedCheck = + (CheckBox)findViewById( R.id.game_locked_check ); + m_gameLockedCheck.setVisibility( View.VISIBLE ); + m_gameLockedCheck.setOnClickListener( this ); + } + handleLockedChange(); + } + + if ( null == m_gi ) { + m_gi = new CurGameInfo( m_giOrig ); + } + + m_carOrig = new CommsAddrRec(); + if ( XwJNI.game_hasComms( gamePtr ) ) { + XwJNI.comms_getAddr( gamePtr, m_carOrig ); + m_remoteAddrs = XwJNI.comms_getAddrs( gamePtr ); + } else if ( !localOnlyGame() ) { + String relayName = XWPrefs.getDefaultRelayHost( m_activity ); + int relayPort = XWPrefs.getDefaultRelayPort( m_activity ); + XwJNI.comms_getInitialAddr( m_carOrig, relayName, + relayPort ); + } + + // load if the first time through.... + if ( null == m_conTypes ) { + m_conTypes = (CommsConnTypeSet)m_carOrig.conTypes.clone(); + } + + buildDisabledsMap( gamePtr ); + setDisableds(); + + m_car = new CommsAddrRec( m_carOrig ); + + setTitle(); + + TextView label = (TextView)findViewById( R.id.lang_separator ); + label.setText( getString( localOnlyGame() ? R.string.lang_label + : R.string.langdict_label ) ); + + m_dictSpinner = (Spinner)findViewById( R.id.dict_spinner ); + if ( localOnlyGame() ) { + m_dictSpinner.setVisibility( View.GONE ); + m_dictSpinner = null; + } + + setConnLabel(); + setupRelayStuffIf(); + loadPlayersList(); + configLangSpinner(); + + m_phoniesSpinner.setSelection( m_gi.phoniesAction.ordinal() ); + + setSmartnessSpinner(); + + setChecked( R.id.hints_allowed, !m_gi.hintsNotAllowed ); + setChecked( R.id.pick_faceup, m_gi.allowPickTiles ); + setInt( R.id.timer_minutes_edit, + m_gi.gameSeconds/60/m_gi.nPlayers ); + + CheckBox check = (CheckBox)findViewById( R.id.use_timer ); + OnCheckedChangeListener lstnr = + new OnCheckedChangeListener() { + public void onCheckedChanged( CompoundButton buttonView, + boolean checked ) { + showTimerSet( checked ); + } + }; + check.setOnCheckedChangeListener( lstnr ); + setChecked( R.id.use_timer, m_gi.timerEnabled ); + showTimerSet( m_gi.timerEnabled ); + + setBoardsizeSpinner(); + } } // loadGame private void showTimerSet( boolean show ) diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java index e5eab57b1..27954dd14 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java @@ -124,42 +124,42 @@ public class GameUtils { { CurGameInfo gi = new CurGameInfo( context ); CommsAddrRec addr = null; - - GamePtr gamePtr = loadMakeGame( context, gi, lockSrc ); String[] dictNames = gi.dictNames(); DictUtils.DictPairs pairs = DictUtils.openDicts( context, dictNames ); - if ( XwJNI.game_hasComms( gamePtr ) ) { - addr = new CommsAddrRec(); - XwJNI.comms_getAddr( gamePtr, addr ); - } - gamePtr.release(); - - gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes, pairs.m_paths, - gi.langName( context ), (UtilCtxt)null, - (DrawCtx)null, CommonPrefs.get( context ), - (TransportProcs)null ); - - if ( juggle ) { - gi.juggle(); - } - - if ( null != addr ) { - XwJNI.comms_setAddr( gamePtr, addr ); - } - - if ( null == lockDest ) { - if ( DBUtils.GROUPID_UNSPEC == groupID ) { - groupID = DBUtils.getGroupForGame( context, lockSrc.getRowid() ); + try ( GamePtr gamePtr = loadMakeGame( context, gi, lockSrc ) ) { + if ( XwJNI.game_hasComms( gamePtr ) ) { + addr = new CommsAddrRec(); + XwJNI.comms_getAddr( gamePtr, addr ); } - long rowid = saveNewGame( context, gamePtr, gi, groupID ); - lockDest = GameLock.tryLock( rowid ); - } else { - saveGame( context, gamePtr, gi, lockDest, true ); } - summarizeAndRelease( context, lockDest, gamePtr, gi ); - DBUtils.saveThumbnail( context, lockDest, null ); + try ( GamePtr gamePtr = XwJNI + .initNew( gi, dictNames, pairs.m_bytes, pairs.m_paths, + gi.langName( context ), (UtilCtxt)null, + (DrawCtx)null, CommonPrefs.get( context ), + (TransportProcs)null ) ) { + + if ( juggle ) { + gi.juggle(); + } + + if ( null != addr ) { + XwJNI.comms_setAddr( gamePtr, addr ); + } + + if ( null == lockDest ) { + if ( DBUtils.GROUPID_UNSPEC == groupID ) { + groupID = DBUtils.getGroupForGame( context, lockSrc.getRowid() ); + } + long rowid = saveNewGame( context, gamePtr, gi, groupID ); + lockDest = GameLock.tryLock( rowid ); + } else { + saveGame( context, gamePtr, gi, lockDest, true ); + } + summarize( context, lockDest, gamePtr, gi ); + DBUtils.saveThumbnail( context, lockDest, null ); + } return lockDest; } // resetGame @@ -196,17 +196,13 @@ public class GameUtils { return result; } - private static GameSummary summarizeAndRelease( Context context, - GameLock lock, - GamePtr gamePtr, - CurGameInfo gi ) + private static GameSummary summarize( Context context, GameLock lock, + GamePtr gamePtr, CurGameInfo gi ) { GameSummary summary = new GameSummary( gi ); XwJNI.game_summarize( gamePtr, summary ); DBUtils.saveSummary( context, lock, summary ); - - gamePtr.release(); return summary; } @@ -214,9 +210,10 @@ public class GameUtils { { GameSummary result = null; CurGameInfo gi = new CurGameInfo( context ); - GamePtr gamePtr = loadMakeGame( context, gi, lock ); - if ( null != gamePtr ) { - result = summarizeAndRelease( context, lock, gamePtr, gi ); + try ( GamePtr gamePtr = loadMakeGame( context, gi, lock ) ) { + if ( null != gamePtr ) { + result = summarize( context, lock, gamePtr, gi ); + } } return result; } @@ -411,11 +408,11 @@ public class GameUtils { try ( GameLock lock = GameLock.tryLockRO( rowid ) ) { if ( null != lock ) { CurGameInfo gi = new CurGameInfo( context ); - GamePtr gamePtr = loadMakeGame( context, gi, lock ); - if ( null != gamePtr ) { - thumb = takeSnapshot( context, gamePtr, gi ); - gamePtr.release(); - DBUtils.saveThumbnail( context, lock, thumb ); + try ( GamePtr gamePtr = loadMakeGame( context, gi, lock ) ) { + if ( null != gamePtr ) { + thumb = takeSnapshot( context, gamePtr, gi ); + DBUtils.saveThumbnail( context, lock, thumb ); + } } } } @@ -925,40 +922,41 @@ public class GameUtils { if ( null != lock ) { CurGameInfo gi = new CurGameInfo( context ); FeedUtilsImpl feedImpl = new FeedUtilsImpl( context, rowid ); - GamePtr gamePtr = loadMakeGame( context, gi, feedImpl, sink, lock ); - if ( null != gamePtr ) { - XwJNI.comms_resendAll( gamePtr, false, false ); + try ( GamePtr gamePtr = loadMakeGame( context, gi, feedImpl, sink, lock ) ) { + if ( null != gamePtr ) { + XwJNI.comms_resendAll( gamePtr, false, false ); - Assert.assertNotNull( ret ); - draw = XwJNI.game_receiveMessage( gamePtr, msg, ret ); - XwJNI.comms_ackAny( gamePtr ); + Assert.assertNotNull( ret ); + draw = XwJNI.game_receiveMessage( gamePtr, msg, ret ); + XwJNI.comms_ackAny( gamePtr ); - // update gi to reflect changes due to messages - XwJNI.game_getGi( gamePtr, gi ); + // update gi to reflect changes due to messages + XwJNI.game_getGi( gamePtr, gi ); - if ( draw && XWPrefs.getThumbEnabled( context ) ) { - Bitmap bitmap = takeSnapshot( context, gamePtr, gi ); - DBUtils.saveThumbnail( context, lock, bitmap ); - } - - if ( null != bmr ) { - if ( null != feedImpl.m_chat ) { - bmr.m_chat = feedImpl.m_chat; - bmr.m_chatFrom = feedImpl.m_chatFrom; - bmr.m_chatTs = feedImpl.m_ts; - } else { - LastMoveInfo lmi = new LastMoveInfo(); - XwJNI.model_getPlayersLastScore( gamePtr, -1, lmi ); - bmr.m_lmi = lmi; + if ( draw && XWPrefs.getThumbEnabled( context ) ) { + Bitmap bitmap = takeSnapshot( context, gamePtr, gi ); + DBUtils.saveThumbnail( context, lock, bitmap ); } - } - saveGame( context, gamePtr, gi, lock, false ); - GameSummary summary = summarizeAndRelease( context, lock, - gamePtr, gi ); - if ( null != isLocalOut ) { - isLocalOut[0] = 0 <= summary.turn - && gi.players[summary.turn].isLocal; + if ( null != bmr ) { + if ( null != feedImpl.m_chat ) { + bmr.m_chat = feedImpl.m_chat; + bmr.m_chatFrom = feedImpl.m_chatFrom; + bmr.m_chatTs = feedImpl.m_ts; + } else { + LastMoveInfo lmi = new LastMoveInfo(); + XwJNI.model_getPlayersLastScore( gamePtr, -1, lmi ); + bmr.m_lmi = lmi; + } + } + + saveGame( context, gamePtr, gi, lock, false ); + GameSummary summary = summarize( context, lock, + gamePtr, gi ); + if ( null != isLocalOut ) { + isLocalOut[0] = 0 <= summary.turn + && gi.players[summary.turn].isLocal; + } } int flags = setFromFeedImpl( feedImpl ); @@ -999,18 +997,18 @@ public class GameUtils { DictUtils.DictPairs pairs = DictUtils.openDicts( context, dictNames ); - GamePtr gamePtr = + try ( GamePtr gamePtr = XwJNI.initFromStream( rowid, stream, gi, dictNames, pairs.m_bytes, pairs.m_paths, gi.langName( context ), null, - null, CommonPrefs.get( context ), null ); - // second time required as game_makeFromStream can overwrite - gi.replaceDicts( context, newDict ); + null, CommonPrefs.get( context ), null ) ) { + // second time required as game_makeFromStream can overwrite + gi.replaceDicts( context, newDict ); - saveGame( context, gamePtr, gi, lock, false ); - - summarizeAndRelease( context, lock, gamePtr, gi ); + saveGame( context, gamePtr, gi, lock, false ); + summarize( context, lock, gamePtr, gi ); + } } else { DbgUtils.toastNoLock( TAG, context, rowid, "replaceDicts(): rowid %d", @@ -1042,7 +1040,6 @@ public class GameUtils { String[] dictNames = gi.dictNames(); DictUtils.DictPairs pairs = DictUtils.openDicts( context, dictNames ); String langName = gi.langName( context ); - GamePtr gamePtr = null; boolean madeGame = false; CommonPrefs cp = CommonPrefs.get( context ); @@ -1051,21 +1048,36 @@ public class GameUtils { } else { byte[] stream = savedGame( context, lock ); // Will fail if there's nothing in the stream but a gi. - gamePtr = XwJNI.initFromStream( lock.getRowid(), stream, - new CurGameInfo(context), - dictNames, pairs.m_bytes, - pairs.m_paths, langName, - null, null, cp, null ); - madeGame = null != gamePtr; + try ( GamePtr gamePtr = XwJNI + .initFromStream( lock.getRowid(), stream, + new CurGameInfo(context), + dictNames, pairs.m_bytes, + pairs.m_paths, langName, + null, null, cp, null ) ) { + if ( null != gamePtr ) { + applyChanges( context, sink, gi, car, disab, + lock, gamePtr ); + madeGame = true; + } + } } if ( forceNew || !madeGame ) { - Assert.assertNull( gamePtr ); - gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes, - pairs.m_paths, langName, util, - (DrawCtx)null, cp, sink ); + try ( GamePtr gamePtr = XwJNI.initNew( gi, dictNames, pairs.m_bytes, + pairs.m_paths, langName, util, + (DrawCtx)null, cp, sink ) ) { + if ( null != gamePtr ) { + applyChanges( context, sink, gi, car, disab, lock, gamePtr ); + } + } } + } + private static void applyChanges( Context context, MultiMsgSink sink, + CurGameInfo gi, CommsAddrRec car, + Map disab, + GameLock lock, GamePtr gamePtr ) + { if ( null != car ) { XwJNI.comms_setAddr( gamePtr, car ); } @@ -1086,7 +1098,6 @@ public class GameUtils { GameSummary summary = new GameSummary( gi ); XwJNI.game_summarize( gamePtr, summary ); - gamePtr.release(); DBUtils.saveSummary( context, lock, summary ); } // applyChanges @@ -1167,40 +1178,39 @@ public class GameUtils { } else if ( DeviceRole.SERVER_STANDALONE != summary.serverRole ) { int gameID = summary.gameID; - GamePtr gamePtr = loadMakeGame( context, lock ); - if ( null != gamePtr ) { - Assert.assertTrue( XwJNI.game_hasComms( gamePtr ) - || !BuildConfig.DEBUG ); - CommsAddrRec[] addrs = XwJNI.comms_getAddrs( gamePtr ); - for ( CommsAddrRec addr : addrs ) { - CommsConnTypeSet conTypes = addr.conTypes; - for ( CommsConnType typ : conTypes ) { - switch ( typ ) { - case COMMS_CONN_RELAY: - // see below - break; - case COMMS_CONN_BT: - BTService.gameDied( context, addr.bt_btAddr, gameID ); - break; - case COMMS_CONN_SMS: - SMSService.gameDied( context, gameID, addr.sms_phone ); - break; - case COMMS_CONN_P2P: - WiDirService.gameDied( addr.p2p_addr, gameID ); - break; + try ( GamePtr gamePtr = loadMakeGame( context, lock ) ) { + if ( null != gamePtr ) { + Assert.assertTrue( XwJNI.game_hasComms( gamePtr ) + || !BuildConfig.DEBUG ); + CommsAddrRec[] addrs = XwJNI.comms_getAddrs( gamePtr ); + for ( CommsAddrRec addr : addrs ) { + CommsConnTypeSet conTypes = addr.conTypes; + for ( CommsConnType typ : conTypes ) { + switch ( typ ) { + case COMMS_CONN_RELAY: + // see below + break; + case COMMS_CONN_BT: + BTService.gameDied( context, addr.bt_btAddr, gameID ); + break; + case COMMS_CONN_SMS: + SMSService.gameDied( context, gameID, addr.sms_phone ); + break; + case COMMS_CONN_P2P: + WiDirService.gameDied( addr.p2p_addr, gameID ); + break; + } } } - } - // comms doesn't have a relay address for us until the game's - // in play (all devices registered, at least.) To enable - // deleting on relay half-games that we created but nobody - // joined, special-case this one. - if ( summary.inRelayGame() ) { - tellRelayDied( context, summary, informNow ); + // comms doesn't have a relay address for us until the game's + // in play (all devices registered, at least.) To enable + // deleting on relay half-games that we created but nobody + // joined, special-case this one. + if ( summary.inRelayGame() ) { + tellRelayDied( context, summary, informNow ); + } } - - gamePtr.release(); } } } @@ -1275,17 +1285,17 @@ public class GameUtils { if ( null != lock ) { CurGameInfo gi = new CurGameInfo( m_context ); MultiMsgSink sink = new MultiMsgSink( m_context, rowid ); - GamePtr gamePtr = loadMakeGame( m_context, gi, sink, lock ); - if ( null != gamePtr ) { - int nSent = XwJNI.comms_resendAll( gamePtr, true, - m_filter, false ); - gamePtr.release(); - Log.d( TAG, "Resender.doInBackground(): sent %d " - + "messages for rowid %d", nSent, rowid ); - nSentTotal += sink.numSent(); - } else { - Log.d( TAG, "Resender.doInBackground(): loadMakeGame()" - + " failed for rowid %d", rowid ); + try ( GamePtr gamePtr = loadMakeGame( m_context, gi, sink, lock ) ) { + if ( null != gamePtr ) { + int nSent = XwJNI.comms_resendAll( gamePtr, true, + m_filter, false ); + Log.d( TAG, "Resender.doInBackground(): sent %d " + + "messages for rowid %d", nSent, rowid ); + nSentTotal += sink.numSent(); + } else { + Log.d( TAG, "Resender.doInBackground(): loadMakeGame()" + + " failed for rowid %d", rowid ); + } } } else { try ( JNIThread thread = JNIThread.getRetained( rowid ) ) { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java index c0ca56de5..cbf5cad61 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/JNIThread.java @@ -808,8 +808,8 @@ public class JNIThread extends Thread implements AutoCloseable { private void retain_sync() { ++m_refCount; - Log.i( TAG, "retain_sync(rowid=%d): m_refCount raised to %d", - m_rowid, m_refCount ); + // Log.i( TAG, "retain_sync(rowid=%d): m_refCount raised to %d", + // m_rowid, m_refCount ); } public JNIThread retain() @@ -831,8 +831,8 @@ public class JNIThread extends Thread implements AutoCloseable { stop = true; } } - Log.i( TAG, "release(rowid=%d): m_refCount dropped to %d", - m_rowid, m_refCount ); + // Log.i( TAG, "release(rowid=%d): m_refCount dropped to %d", + // m_rowid, m_refCount ); if ( stop ) { waitToStop( true ); diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java index a3d56077f..9030278a4 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java @@ -34,7 +34,7 @@ import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; public class XwJNI { private static final String TAG = XwJNI.class.getSimpleName(); - public static class GamePtr { + public static class GamePtr implements AutoCloseable { private int m_ptr = 0; private int m_refCount = 0; private long m_rowid; @@ -68,8 +68,8 @@ public class XwJNI { public synchronized void release() { --m_refCount; - Log.d( TAG, "release(this=%H, rowid=%d): refCount now %d", - this, m_rowid, m_refCount ); + // Log.d( TAG, "release(this=%H, rowid=%d): refCount now %d", + // this, m_rowid, m_refCount ); if ( 0 == m_refCount ) { if ( 0 != m_ptr ) { if ( !haveEnv( getJNI().m_ptr ) ) { @@ -81,6 +81,12 @@ public class XwJNI { } } + @Override + public void close() + { + release(); + } + // @Override public void finalize() throws java.lang.Throwable {