mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-03 23:04:08 +01:00
rough implementation of creating and inviting a known player
Followed the way rematch works. Which is gross. Eventually the two paths (invitee and rematch) should be unified with rematch getting a lot simpler.)
This commit is contained in:
parent
b8c588e02c
commit
fc05612b74
9 changed files with 315 additions and 48 deletions
|
@ -530,6 +530,8 @@ public class BoardDelegate extends DelegateBase
|
|||
Assert.assertTrue( 0 < state.nMissing );
|
||||
if ( state.summary.hasRematchInfo() ) {
|
||||
tryRematchInvites( true );
|
||||
} else if ( state.summary.hasInviteInfo() ) {
|
||||
tryOtherInvites( true );
|
||||
} else {
|
||||
callInviteChoices( sentInfo[0] );
|
||||
}
|
||||
|
@ -1770,6 +1772,8 @@ public class BoardDelegate extends DelegateBase
|
|||
} else if ( nMissing > 0 ) {
|
||||
if ( m_summary.hasRematchInfo() ) {
|
||||
skipDismiss = !tryRematchInvites( false );
|
||||
} else if ( m_summary.hasInviteInfo() ) {
|
||||
skipDismiss = !tryOtherInvites( false );
|
||||
} else if ( !m_haveInvited ) {
|
||||
m_haveInvited = true;
|
||||
showInviteAlertIf();
|
||||
|
@ -2770,6 +2774,8 @@ public class BoardDelegate extends DelegateBase
|
|||
{
|
||||
if ( 0 < m_mySIS.nMissing && m_summary.hasRematchInfo() ) {
|
||||
tryRematchInvites( false );
|
||||
} else if ( 0 < m_mySIS.nMissing && m_summary.hasInviteInfo() ) {
|
||||
tryOtherInvites( false );
|
||||
} else if ( null != m_missingDevs ) {
|
||||
Assert.assertNotNull( m_missingMeans );
|
||||
String gameName = GameUtils.getName( m_activity, m_rowid );
|
||||
|
@ -3136,6 +3142,15 @@ public class BoardDelegate extends DelegateBase
|
|||
}
|
||||
}
|
||||
|
||||
private NetLaunchInfo nliForMe()
|
||||
{
|
||||
int numHere = 1;
|
||||
int forceChannel = 1;
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_activity, m_summary, m_gi,
|
||||
numHere, forceChannel );
|
||||
return nli;
|
||||
}
|
||||
|
||||
// Return true if anything sent
|
||||
private boolean tryRematchInvites( boolean force )
|
||||
{
|
||||
|
@ -3148,10 +3163,7 @@ public class BoardDelegate extends DelegateBase
|
|||
Assert.assertNotNull( m_summary );
|
||||
Assert.assertNotNull( m_gi );
|
||||
// only supports a single invite for now!
|
||||
int numHere = 1;
|
||||
int forceChannel = 1;
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_activity, m_summary, m_gi,
|
||||
numHere, forceChannel );
|
||||
NetLaunchInfo nli = nliForMe();
|
||||
|
||||
String value;
|
||||
value = m_summary.getStringExtra( GameSummary.EXTRA_REMATCH_PHONE );
|
||||
|
@ -3184,6 +3196,47 @@ public class BoardDelegate extends DelegateBase
|
|||
return force;
|
||||
}
|
||||
|
||||
private boolean tryOtherInvites( boolean force )
|
||||
{
|
||||
boolean result = true;
|
||||
Assert.assertNotNull( m_summary );
|
||||
Assert.assertNotNull( m_gi );
|
||||
String str64 = m_summary.getStringExtra( GameSummary.EXTRA_REMATCH_ADDR );
|
||||
try {
|
||||
CommsAddrRec addr = (CommsAddrRec)Utils.string64ToSerializable( str64 );
|
||||
NetLaunchInfo nli = nliForMe();
|
||||
CommsConnTypeSet conTypes = addr.conTypes;
|
||||
for ( CommsConnType typ : conTypes ) {
|
||||
switch ( typ ) {
|
||||
case COMMS_CONN_MQTT:
|
||||
MQTTUtils.inviteRemote( m_activity, addr.mqtt_devID, nli );
|
||||
recordInviteSent( InviteMeans.MQTT, addr.mqtt_devID );
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
BTService.inviteRemote( m_activity, addr.bt_btAddr, nli );
|
||||
recordInviteSent( InviteMeans.BLUETOOTH, addr.bt_btAddr );
|
||||
break;
|
||||
// case COMMS_CONN_RELAY:
|
||||
// RelayService.inviteRemote( m_activity, m_jniGamePtr, 0, value, nli );
|
||||
// recordInviteSent( InviteMeans.RELAY );
|
||||
// break;
|
||||
case COMMS_CONN_SMS:
|
||||
sendNBSInviteIf( addr.sms_phone, nli, true );
|
||||
recordInviteSent( InviteMeans.SMS_DATA, addr.sms_phone );
|
||||
break;
|
||||
|
||||
default:
|
||||
Log.d( TAG, "not inviting using addr type %s", typ );
|
||||
}
|
||||
}
|
||||
} catch ( Exception ex ) {
|
||||
Log.ex( TAG, ex );
|
||||
Assert.failDbg();
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void sendNBSInviteIf( String phone, NetLaunchInfo nli,
|
||||
boolean askOk )
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ import android.text.TextUtils;
|
|||
import org.eehouse.android.xw4.DBHelper.TABLE_NAMES;
|
||||
import org.eehouse.android.xw4.DictUtils.DictLoc;
|
||||
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
|
||||
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
|
||||
import org.eehouse.android.xw4.jni.CurGameInfo;
|
||||
|
@ -369,6 +370,22 @@ public class DBUtils {
|
|||
}
|
||||
} // saveSummary
|
||||
|
||||
public static void addRematchInfo( Context context, long rowid, CommsAddrRec addr )
|
||||
{
|
||||
try ( GameLock lock = GameLock.tryLock(rowid) ) {
|
||||
if ( null != lock ) {
|
||||
String as64 = Utils.serializableToString64( addr );
|
||||
GameSummary summary = getSummary( context, lock )
|
||||
.putStringExtra( GameSummary.EXTRA_REMATCH_ADDR, as64 )
|
||||
;
|
||||
saveSummary( context, lock, summary );
|
||||
} else {
|
||||
Assert.failDbg();
|
||||
Log.e( TAG, "addRematchInfo(%d): unable to lock game" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addRematchInfo( Context context, long rowid, String btAddr,
|
||||
String phone, String relayID, String p2pAddr,
|
||||
String mqttDevID )
|
||||
|
|
|
@ -62,6 +62,7 @@ import org.eehouse.android.xw4.jni.CommsAddrRec;
|
|||
import org.eehouse.android.xw4.jni.CurGameInfo;
|
||||
import org.eehouse.android.xw4.jni.GameSummary;
|
||||
import org.eehouse.android.xw4.jni.LastMoveInfo;
|
||||
import org.eehouse.android.xw4.jni.XwJNI;
|
||||
import org.eehouse.android.xw4.loc.LocUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -89,6 +90,7 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
private static final String RELAYIDS_EXTRA = "relayids";
|
||||
private static final String ROWID_EXTRA = "rowid";
|
||||
private static final String GAMEID_EXTRA = "gameid";
|
||||
private static final String INVITEE_REC_EXTRA = "invitee_rec";
|
||||
private static final String REMATCH_ROWID_EXTRA = "rm_rowid";
|
||||
private static final String REMATCH_GROUPID_EXTRA = "rm_groupid";
|
||||
private static final String REMATCH_DICT_EXTRA = "rm_dict";
|
||||
|
@ -864,49 +866,14 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
}
|
||||
break;
|
||||
|
||||
case GAMES_LIST_NEWGAME: {
|
||||
case GAMES_LIST_NEWGAME:
|
||||
boolean solo = (Boolean)params[0];
|
||||
final LinearLayout view = (LinearLayout)
|
||||
LocUtils.inflate( m_activity, R.layout.msg_label_and_edit );
|
||||
final EditWClear edit = (EditWClear)view.findViewById( R.id.edit );
|
||||
edit.setText( GameUtils.makeDefaultName( m_activity ) );
|
||||
|
||||
boolean canDoDefaults = solo ||
|
||||
0 < XWPrefs.getAddrTypes( m_activity ).size();
|
||||
int iconResID = solo ? R.drawable.ic_sologame : R.drawable.ic_multigame;
|
||||
int titleID = solo ? R.string.new_game : R.string.new_game_networked;
|
||||
|
||||
String msg = getString( canDoDefaults ? R.string.new_game_message
|
||||
: R.string.new_game_message_nodflt );
|
||||
if ( !solo ) {
|
||||
msg += "\n\n" + getString( R.string.new_game_message_net );
|
||||
boolean forceConfig = 2 <= params.length && (Boolean)params[1];
|
||||
if ( !solo && !forceConfig && XwJNI.hasKnownPlayers() ) {
|
||||
dialog = mkNewWithKnowns();
|
||||
} else {
|
||||
dialog = mkNewGameDialog( solo );
|
||||
}
|
||||
TextView tmpEdit = (TextView)view.findViewById( R.id.msg );
|
||||
tmpEdit.setText( msg );
|
||||
|
||||
lstnr = new OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String name = edit.getText().toString();
|
||||
curThis().makeThenLaunchOrConfigure( name, true, false );
|
||||
}
|
||||
};
|
||||
|
||||
ab = makeAlertBuilder()
|
||||
.setView( view )
|
||||
.setTitle( titleID )
|
||||
.setIcon( iconResID )
|
||||
.setPositiveButton( R.string.newgame_configure_first, lstnr );
|
||||
if ( canDoDefaults ) {
|
||||
lstnr2 = new OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String name = edit.getText().toString();
|
||||
curThis().makeThenLaunchOrConfigure( name, false, false );
|
||||
}
|
||||
};
|
||||
ab.setNegativeButton( R.string.use_defaults, lstnr2 );
|
||||
}
|
||||
dialog = ab.create();
|
||||
}
|
||||
break;
|
||||
|
||||
case GAMES_LIST_NAME_REMATCH: {
|
||||
|
@ -916,7 +883,7 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
if ( null != m_rematchExtras ) {
|
||||
EditWClear edit = (EditWClear)view.findViewById( R.id.edit );
|
||||
edit.setText( m_rematchExtras.getString( REMATCH_NEWNAME_EXTRA ));
|
||||
boolean solo = m_rematchExtras.getBoolean( REMATCH_IS_SOLO, true );
|
||||
solo = m_rematchExtras.getBoolean( REMATCH_IS_SOLO, true );
|
||||
if ( !solo ) {
|
||||
iconResID = R.drawable.ic_multigame;
|
||||
}
|
||||
|
@ -947,6 +914,81 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
return dialog;
|
||||
} // makeDialog
|
||||
|
||||
private Dialog mkNewGameDialog( boolean solo )
|
||||
{
|
||||
final LinearLayout view = (LinearLayout)
|
||||
LocUtils.inflate( m_activity, R.layout.msg_label_and_edit );
|
||||
final EditWClear edit = (EditWClear)view.findViewById( R.id.edit );
|
||||
edit.setText( GameUtils.makeDefaultName( m_activity ) );
|
||||
|
||||
boolean canDoDefaults = solo ||
|
||||
0 < XWPrefs.getAddrTypes( m_activity ).size();
|
||||
int iconResID = solo ? R.drawable.ic_sologame : R.drawable.ic_multigame;
|
||||
int titleID = solo ? R.string.new_game : R.string.new_game_networked;
|
||||
|
||||
String msg = getString( canDoDefaults ? R.string.new_game_message
|
||||
: R.string.new_game_message_nodflt );
|
||||
if ( !solo ) {
|
||||
msg += "\n\n" + getString( R.string.new_game_message_net );
|
||||
}
|
||||
TextView tmpEdit = (TextView)view.findViewById( R.id.msg );
|
||||
tmpEdit.setText( msg );
|
||||
|
||||
OnClickListener lstnr = new OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String name = edit.getText().toString();
|
||||
curThis().makeThenLaunchOrConfigure( name, true, false );
|
||||
}
|
||||
};
|
||||
|
||||
AlertDialog.Builder ab = makeAlertBuilder()
|
||||
.setView( view )
|
||||
.setTitle( titleID )
|
||||
.setIcon( iconResID )
|
||||
.setPositiveButton( R.string.newgame_configure_first, lstnr );
|
||||
if ( canDoDefaults ) {
|
||||
OnClickListener lstnr2 = new OnClickListener() {
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String name = edit.getText().toString();
|
||||
curThis().makeThenLaunchOrConfigure( name, false, false );
|
||||
}
|
||||
};
|
||||
ab.setNegativeButton( R.string.use_defaults, lstnr2 );
|
||||
}
|
||||
return ab.create();
|
||||
}
|
||||
|
||||
private Dialog mkNewWithKnowns()
|
||||
{
|
||||
String[] names = XwJNI.kplr_getPlayers();
|
||||
final NewWithKnowns view = (NewWithKnowns)
|
||||
LocUtils.inflate( m_activity, R.layout.new_game_with_knowns );
|
||||
view.setNames( names, GameUtils.makeDefaultName( m_activity ) );
|
||||
AlertDialog.Builder ab = makeAlertBuilder()
|
||||
.setView( view )
|
||||
.setTitle( R.string.new_game_networked )
|
||||
.setIcon( R.drawable.ic_multigame )
|
||||
.setPositiveButton( "Play Now", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String player = view.getSelPlayer();
|
||||
CommsAddrRec rec = XwJNI.kplr_getAddr( player );
|
||||
String gameName = view.gameName();
|
||||
launchLikeRematch( rec, gameName );
|
||||
}
|
||||
} )
|
||||
.setNegativeButton( "Configure First", new OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
String name = view.gameName();
|
||||
curThis().makeThenLaunchOrConfigure( name, true, false );
|
||||
}
|
||||
} )
|
||||
;
|
||||
|
||||
return ab.create();
|
||||
}
|
||||
|
||||
private void enableMoveGroupButton( DialogInterface dlgi )
|
||||
{
|
||||
((AlertDialog)dlgi)
|
||||
|
@ -2332,6 +2374,22 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
return result;
|
||||
}
|
||||
|
||||
private boolean startWithInvitee( Intent intent )
|
||||
{
|
||||
boolean result = false;
|
||||
try {
|
||||
CommsAddrRec rec = (CommsAddrRec)intent.getSerializableExtra( INVITEE_REC_EXTRA );
|
||||
if ( null != rec ) {
|
||||
String name = intent.getStringExtra( REMATCH_NEWNAME_EXTRA );
|
||||
makeThenLaunchOrConfigure( name, false, false, rec );
|
||||
}
|
||||
} catch ( Exception ex ) {
|
||||
Log.ex( TAG, ex );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean startNewNetGame( NetLaunchInfo nli )
|
||||
{
|
||||
boolean handled = false;
|
||||
|
@ -2749,6 +2807,7 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
{
|
||||
Log.d( TAG, "tryStartsFromIntent(extras={%s})", DbgUtils.extrasToString( intent ) );
|
||||
boolean handled = startFirstHasDict( intent )
|
||||
|| startWithInvitee( intent )
|
||||
|| startNewNetGame( intent )
|
||||
|| startHasGameID( intent )
|
||||
|| startRematch( intent )
|
||||
|
@ -2890,6 +2949,12 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
|
||||
private void makeThenLaunchOrConfigure( String name, boolean doConfigure,
|
||||
boolean skipAsk )
|
||||
{
|
||||
makeThenLaunchOrConfigure( name, doConfigure, skipAsk, null );
|
||||
}
|
||||
|
||||
private void makeThenLaunchOrConfigure( String name, boolean doConfigure,
|
||||
boolean skipAsk, CommsAddrRec rec )
|
||||
{
|
||||
if ( skipAsk || !askingChangeName( name, doConfigure ) ) {
|
||||
long rowID;
|
||||
|
@ -2906,6 +2971,10 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
rowID = GameUtils.makeNewMultiGame( m_activity, groupID, name );
|
||||
}
|
||||
|
||||
if ( null != rec ) {
|
||||
DBUtils.addRematchInfo( m_activity, rowID, rec );
|
||||
}
|
||||
|
||||
if ( doConfigure ) {
|
||||
// configure it
|
||||
GameConfigDelegate.editForResult( getDelegator(),
|
||||
|
@ -2963,6 +3032,15 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
return intent;
|
||||
}
|
||||
|
||||
private void launchLikeRematch( CommsAddrRec rec, String name )
|
||||
{
|
||||
Intent intent = makeSelfIntent( m_activity )
|
||||
.putExtra( INVITEE_REC_EXTRA, (Serializable)rec )
|
||||
.putExtra( REMATCH_NEWNAME_EXTRA, name )
|
||||
;
|
||||
startActivity( intent );
|
||||
}
|
||||
|
||||
public static Intent makeRematchIntent( Context context, long rowid,
|
||||
long groupID, CurGameInfo gi,
|
||||
CommsConnTypeSet addrTypes,
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
|
||||
/*
|
||||
* Copyright 2020 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
public class NewWithKnowns extends LinearLayout {
|
||||
|
||||
public NewWithKnowns( Context cx, AttributeSet as )
|
||||
{
|
||||
super( cx, as );
|
||||
}
|
||||
|
||||
void setNames( String[] knowns, String gameName )
|
||||
{
|
||||
final ArrayAdapter<String> adapter =
|
||||
new ArrayAdapter<>( getContext(), android.R.layout.simple_spinner_item );
|
||||
for ( String msg : knowns ) {
|
||||
adapter.add( msg );
|
||||
}
|
||||
Spinner spinner = (Spinner)findViewById( R.id.names );
|
||||
spinner.setAdapter( adapter );
|
||||
|
||||
EditText et = (EditText)findViewById( R.id.name_edit );
|
||||
et.setText( gameName );
|
||||
}
|
||||
|
||||
String getSelPlayer()
|
||||
{
|
||||
Spinner spinner = (Spinner)findViewById( R.id.names );
|
||||
return spinner.getSelectedItem().toString();
|
||||
}
|
||||
|
||||
String gameName()
|
||||
{
|
||||
EditText et = (EditText)findViewById( R.id.name_edit );
|
||||
return et.getText().toString();
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ import java.util.HashSet;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class CommsAddrRec {
|
||||
public class CommsAddrRec implements java.io.Serializable {
|
||||
private static final String TAG = CommsAddrRec.class.getSimpleName();
|
||||
|
||||
public enum CommsConnType {
|
||||
|
|
|
@ -51,6 +51,7 @@ public class GameSummary implements Serializable {
|
|||
public static final String EXTRA_REMATCH_RELAY = "rm_relay";
|
||||
public static final String EXTRA_REMATCH_P2P = "rm_p2p";
|
||||
public static final String EXTRA_REMATCH_MQTT = "rm_mqtt";
|
||||
public static final String EXTRA_REMATCH_ADDR = "rm_addr";
|
||||
|
||||
public static final int MSG_FLAGS_NONE = 0;
|
||||
public static final int MSG_FLAGS_TURN = 1;
|
||||
|
@ -538,6 +539,12 @@ public class GameSummary implements Serializable {
|
|||
return found;
|
||||
}
|
||||
|
||||
public boolean hasInviteInfo()
|
||||
{
|
||||
boolean found = null != getStringExtra( EXTRA_REMATCH_ADDR );
|
||||
return found;
|
||||
}
|
||||
|
||||
private static boolean localTurnNextImpl( int flags, int turn )
|
||||
{
|
||||
int flag = 2 << (turn * 2);
|
||||
|
|
|
@ -165,6 +165,12 @@ public class XwJNI {
|
|||
dvc_parseMQTTPacket( getJNI().m_ptrGlobals, buf );
|
||||
}
|
||||
|
||||
public static boolean hasKnownPlayers()
|
||||
{
|
||||
String[] players = kplr_getPlayers();
|
||||
return null != players && 0 < players.length;
|
||||
}
|
||||
|
||||
public static String[] kplr_getPlayers()
|
||||
{
|
||||
return kplr_getPlayers( getJNI().m_ptrGlobals );
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<org.eehouse.android.xw4.NewWithKnowns
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="8dp"
|
||||
>
|
||||
|
||||
<TextView android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Choose your opponent"
|
||||
/>
|
||||
|
||||
<Spinner android:id="@+id/names"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
<TextView android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Name your game"
|
||||
/>
|
||||
|
||||
<EditText android:id="@+id/name_edit"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
</org.eehouse.android.xw4.NewWithKnowns>
|
|
@ -33,6 +33,7 @@ typedef struct _KPState {
|
|||
KnownPlayer* players;
|
||||
XP_U16 nPlayers;
|
||||
XP_Bool dirty;
|
||||
XP_Bool inUse;
|
||||
} KPState;
|
||||
|
||||
/* enum { STREAM_VERSION_KP_1, /\* initial *\/ */
|
||||
|
@ -75,6 +76,8 @@ loadState( XW_DUtilCtxt* dutil, XWEnv xwe )
|
|||
|
||||
stream_destroy( stream, xwe );
|
||||
}
|
||||
XP_ASSERT( !state->inUse );
|
||||
state->inUse = XP_TRUE;
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -95,6 +98,14 @@ saveState( XW_DUtilCtxt* dutil, XWEnv xwe, KPState* state )
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
releaseState( XW_DUtilCtxt* dutil, XWEnv xwe, KPState* state )
|
||||
{
|
||||
XP_ASSERT( state->inUse );
|
||||
saveState( dutil, xwe, state );
|
||||
state->inUse = XP_FALSE;
|
||||
}
|
||||
|
||||
static const XP_UCHAR*
|
||||
figureNameFor( XP_U16 posn, const CurGameInfo* gi )
|
||||
{
|
||||
|
@ -158,7 +169,7 @@ kplr_addAddrs( XW_DUtilCtxt* dutil, XWEnv xwe, const CurGameInfo* gi,
|
|||
XP_LOGFF( "unable to find %dth name", ii );
|
||||
}
|
||||
}
|
||||
saveState( dutil, xwe, state );
|
||||
releaseState( dutil, xwe, state );
|
||||
}
|
||||
|
||||
return canUse;
|
||||
|
@ -169,6 +180,7 @@ kplr_havePlayers( XW_DUtilCtxt* dutil, XWEnv xwe )
|
|||
{
|
||||
KPState* state = loadState( dutil, xwe );
|
||||
XP_Bool result = 0 < state->nPlayers;
|
||||
releaseState( dutil, xwe, state );
|
||||
LOG_RETURNF( "%s", boolToStr(result) );
|
||||
return result;
|
||||
}
|
||||
|
@ -185,6 +197,7 @@ kplr_getPlayers( XW_DUtilCtxt* dutil, XWEnv xwe,
|
|||
}
|
||||
}
|
||||
*nFound = state->nPlayers;
|
||||
releaseState( dutil, xwe, state );
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
|
@ -199,6 +212,7 @@ kplr_getAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name,
|
|||
*addr = kp->addr;
|
||||
}
|
||||
}
|
||||
releaseState( dutil, xwe, state );
|
||||
LOG_RETURNF( "%s", boolToStr(found) );
|
||||
return found;
|
||||
}
|
||||
|
@ -208,6 +222,7 @@ kplr_cleanup( XW_DUtilCtxt* dutil )
|
|||
{
|
||||
KPState** state = (KPState**)&dutil->kpCtxt;
|
||||
if ( !!*state ) {
|
||||
XP_ASSERT( !(*state)->inUse );
|
||||
for ( KnownPlayer* kp = (*state)->players; !!kp; kp = kp->next ) {
|
||||
XP_FREEP( dutil->mpool, &kp->name );
|
||||
XP_FREE( dutil->mpool, kp );
|
||||
|
|
Loading…
Reference in a new issue