make trade and move confirm non-blocking

Probably breaks curses build, but for gtk and Android
turn move and trade confirmation into a two-step process, making
board_commitTurn() non-interactive when called with a second
parameter. The old blocking util methods now return void and it's up to
the client code to interact (on the main thread) then re-call
board_commitTurn() if appropriate.
This commit is contained in:
Eric House 2017-02-17 08:10:09 -08:00
parent 1f2f4506c4
commit ca6edcfc9a
19 changed files with 199 additions and 194 deletions

View file

@ -269,7 +269,23 @@ public class BoardDelegate extends DelegateBase
dialog = ab.create();
break;
case QUERY_REQUEST_BLK:
case QUERY_TRADE:
case QUERY_MOVE: {
String msg = (String)params[0];
lstnr = new OnClickListener() {
public void onClick( DialogInterface dialog,
int whichButton ) {
handleViaThread( JNICmd.CMD_COMMIT_TRUE );
}
};
dialog = ab.setMessage( msg )
.setTitle( R.string.query_title )
.setPositiveButton( R.string.button_yes, lstnr )
.setNegativeButton( android.R.string.cancel, null )
.create();
}
break;
case DLG_BADWORDS_BLK:
checkBlocking();
case DLG_SCORES: {
@ -285,18 +301,8 @@ public class BoardDelegate extends DelegateBase
m_resultCode = 1;
}
};
ab.setPositiveButton( DlgID.QUERY_REQUEST_BLK == dlgID ?
R.string.button_yes : android.R.string.ok,
lstnr );
if ( DlgID.QUERY_REQUEST_BLK == dlgID ) {
lstnr = new OnClickListener() {
public void onClick( DialogInterface dialog,
int whichButton ) {
m_resultCode = 0;
}
};
ab.setNegativeButton( R.string.button_no, lstnr );
} else if ( DlgID.DLG_SCORES == dlgID ) {
ab.setPositiveButton( android.R.string.ok, lstnr );
if ( DlgID.DLG_SCORES == dlgID ) {
if ( null != m_words && m_words.length > 0 ) {
String buttonTxt;
boolean studyOn = XWPrefs.getStudyEnabled( m_activity );
@ -898,7 +904,7 @@ public class BoardDelegate extends DelegateBase
break;
case R.id.board_menu_trade_commit:
cmd = JNICmd.CMD_COMMIT;
cmd = JNICmd.CMD_COMMIT_FALSE;
break;
case R.id.board_menu_trade_cancel:
cmd = JNICmd.CMD_CANCELTRADE;
@ -1026,7 +1032,7 @@ public class BoardDelegate extends DelegateBase
Utils.launchSettings( m_activity );
break;
case COMMIT_ACTION:
cmd = JNICmd.CMD_COMMIT;
cmd = JNICmd.CMD_COMMIT_FALSE;
break;
case SHOW_EXPL_ACTION:
showToast( m_toastStr );
@ -1221,7 +1227,7 @@ public class BoardDelegate extends DelegateBase
public void onClick( View view )
{
if ( view == m_exchCommmitButton ) {
handleViaThread( JNICmd.CMD_COMMIT );
handleViaThread( JNICmd.CMD_COMMIT_FALSE );
} else if ( view == m_exchCancelButton ) {
handleViaThread( JNICmd.CMD_CANCELTRADE );
}
@ -1831,32 +1837,18 @@ public class BoardDelegate extends DelegateBase
}
@Override
public boolean userQuery( int id, String query )
public void notifyMove( String msg )
{
boolean result;
switch( id ) {
// These *are* blocking dialogs
case UtilCtxt.QUERY_COMMIT_TURN:
result = 0 != waitBlockingDialog( DlgID.QUERY_REQUEST_BLK, 0,
R.string.query_title, query);
break;
default:
Assert.fail();
result = false;
}
return result;
showDialogFragment( DlgID.QUERY_MOVE, msg );
}
@Override
public boolean confirmTrade( String[] tiles )
public void notifyTrade( String[] tiles )
{
String dlgBytes =
getQuantityString( R.plurals.query_trade_fmt, tiles.length,
tiles.length, TextUtils.join( ", ", tiles ));
return 0 != waitBlockingDialog( DlgID.QUERY_REQUEST_BLK, 0,
R.string.info_title, dlgBytes );
showDialogFragment( DlgID.QUERY_TRADE, dlgBytes );
}
@Override
@ -2048,10 +2040,11 @@ public class BoardDelegate extends DelegateBase
waitBlockingDialog( DlgID.DLG_BADWORDS_BLK, 0, R.string.badwords_title,
message + getString( R.string.badwords_lost ) );
} else {
String dlgBytes = message + getString( R.string.badwords_accept );
accept = 0 != waitBlockingDialog( DlgID.QUERY_REQUEST_BLK, 0,
R.string.query_title,
dlgBytes );
Assert.fail();
// String dlgBytes = message + getString( R.string.badwords_accept );
// accept = 0 != waitBlockingDialog( DlgID.QUERY_REQUEST_BLK, 0,
// R.string.query_title,
// dlgBytes );
}
return accept;

View file

@ -58,7 +58,8 @@ public enum DlgID {
, WARN_NODICT_NEW
, WARN_NODICT_SUBST
, DLG_BADWORDS_BLK
, QUERY_REQUEST_BLK
, QUERY_MOVE
, QUERY_TRADE
, PICK_TILE_REQUESTBLANK_BLK
, ASK_PASSWORD
, DLG_RETRY

View file

@ -71,7 +71,8 @@ public class JNIThread extends Thread {
CMD_KEYDOWN,
CMD_KEYUP,
CMD_TIMER_FIRED,
CMD_COMMIT,
CMD_COMMIT_FALSE,
CMD_COMMIT_TRUE,
CMD_JUGGLE,
CMD_FLIP,
CMD_TOGGLE_TRAY,
@ -542,8 +543,11 @@ public class JNIThread extends Thread {
draw = processKeyEvent( elem.m_cmd, (XwJNI.XP_Key)args[0], barr );
break;
case CMD_COMMIT:
draw = XwJNI.board_commitTurn( m_jniGamePtr );
case CMD_COMMIT_FALSE:
draw = XwJNI.board_commitTurn( m_jniGamePtr, false );
break;
case CMD_COMMIT_TRUE:
draw = XwJNI.board_commitTurn( m_jniGamePtr, true );
break;
case CMD_JUGGLE:

View file

@ -103,10 +103,8 @@ public interface UtilCtxt {
String getUserString( int stringCode );
String getUserQuantityString( int stringCode, int quantity );
static final int QUERY_COMMIT_TURN = 0;
boolean userQuery( int id, String query );
boolean confirmTrade( String[] tiles );
void notifyMove( String query );
void notifyTrade( String[] tiles );
// These oughtto be an enum but then I'd have to cons one up in C.
static final int ERR_NONE = 0;

View file

@ -237,16 +237,13 @@ public class UtilCtxtImpl implements UtilCtxt {
return result;
}
public boolean userQuery( int id, String query )
public void notifyMove( String query )
{
subclassOverride( "userQuery" );
return false;
subclassOverride( "notifyMove" );
}
public boolean confirmTrade( String[] tiles )
public void notifyTrade( String[] tiles )
{
subclassOverride( "confirmTrade" );
return false;
subclassOverride( "notifyTrade" );
}
public void userError( int id )

View file

@ -298,7 +298,8 @@ public class XwJNI {
public static native boolean board_hideTray( GamePtr gamePtr );
public static native boolean board_showTray( GamePtr gamePtr );
public static native boolean board_toggle_showValues( GamePtr gamePtr );
public static native boolean board_commitTurn( GamePtr gamePtr );
public static native boolean board_commitTurn( GamePtr gamePtr,
boolean alreadyConfirmed );
public static native boolean board_flip( GamePtr gamePtr );
public static native boolean board_replaceTiles( GamePtr gamePtr );
public static native int board_getSelPlayer( GamePtr gamePtr );

View file

@ -123,33 +123,28 @@ and_util_userError( XW_UtilCtxt* uc, UtilErrID id )
UTIL_CBK_TAIL();
}
static XP_Bool
and_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id, XWStreamCtxt* stream )
static void
and_util_notifyMove( XW_UtilCtxt* uc, XWStreamCtxt* stream )
{
jboolean result = XP_FALSE;
XP_ASSERT( id < QUERY_LAST_COMMON );
UTIL_CBK_HEADER("userQuery", "(ILjava/lang/String;)Z" );
UTIL_CBK_HEADER("notifyMove", "(Ljava/lang/String;)V" );
jstring jstr = NULL;
if ( NULL != stream ) {
jstr = streamToJString( env, stream );
}
result = (*env)->CallBooleanMethod( env, util->jutil, mid, id, jstr );
(*env)->CallVoidMethod( env, util->jutil, mid, jstr );
deleteLocalRef( env, jstr );
UTIL_CBK_TAIL();
return result;
}
static XP_Bool
and_util_confirmTrade( XW_UtilCtxt* uc, const XP_UCHAR** tiles, XP_U16 nTiles )
static void
and_util_notifyTrade( XW_UtilCtxt* uc, const XP_UCHAR** tiles, XP_U16 nTiles )
{
XP_Bool result = XP_FALSE;
UTIL_CBK_HEADER("confirmTrade", "([Ljava/lang/String;)Z" );
UTIL_CBK_HEADER("notifyTrade", "([Ljava/lang/String;)V" );
jobjectArray jtiles = makeStringArray( env, nTiles, tiles );
result = (*env)->CallBooleanMethod( env, util->jutil, mid, jtiles );
(*env)->CallVoidMethod( env, util->jutil, mid, jtiles );
deleteLocalRef( env, jtiles );
UTIL_CBK_TAIL();
return result;
}
static XP_S16
@ -713,8 +708,8 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
#endif
SET_PROC(getSquareBonus);
SET_PROC(userError);
SET_PROC(userQuery);
SET_PROC(confirmTrade);
SET_PROC(notifyMove);
SET_PROC(notifyTrade);
SET_PROC(userPickTileBlank);
SET_PROC(userPickTileTray);
SET_PROC(informNeedPassword);

View file

@ -1270,11 +1270,11 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1toggle_1showValues
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1commitTurn
(JNIEnv* env, jclass C, GamePtrType gamePtr)
(JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean alreadyConfirmed)
{
jboolean result;
XWJNI_START();
result = board_commitTurn( state->game.board );
result = board_commitTurn( state->game.board, alreadyConfirmed );
XWJNI_END();
return result;
}

View file

@ -1010,8 +1010,8 @@ warnBadWords( const XP_UCHAR* word, XP_Bool isLegal,
}
} /* warnBadWords */
static XP_Bool
boardConfirmTrade( BoardCtxt* board, const TrayTileSet* tiles )
static void
boardNotifyTrade( BoardCtxt* board, const TrayTileSet* tiles )
{
const XP_UCHAR* tfaces[MAX_TRAY_TILES];
XP_U16 ii;
@ -1021,11 +1021,11 @@ boardConfirmTrade( BoardCtxt* board, const TrayTileSet* tiles )
tfaces[ii] = dict_getTileString( dict, tiles->tiles[ii] );
}
return util_confirmTrade( board->util, tfaces, tiles->nTiles );
util_notifyTrade( board->util, tfaces, tiles->nTiles );
}
XP_Bool
board_commitTurn( BoardCtxt* board )
board_commitTurn( BoardCtxt* board, XP_Bool alreadyConfirmed )
{
XP_Bool result = XP_FALSE;
const XP_S16 turn = server_getCurrentTurn( board->server, NULL );
@ -1038,7 +1038,7 @@ board_commitTurn( BoardCtxt* board )
} else if ( 0 == model_getNumTilesTotal( board->model, turn ) ) {
/* game's over but still undoable so turn hasn't changed; do
nothing */
} else if ( checkRevealTray( board ) ) {
} else if ( alreadyConfirmed || checkRevealTray( board ) ) {
if ( pti->tradeInProgress ) {
TileBit traySelBits = pti->traySelBits;
result = XP_TRUE; /* there's at least the window to clean up
@ -1049,33 +1049,39 @@ board_commitTurn( BoardCtxt* board )
} else {
TrayTileSet selTiles;
getSelTiles( board, traySelBits, &selTiles );
if ( boardConfirmTrade( board, &selTiles ) ) {
if ( alreadyConfirmed ) {
/* server_commitTrade() changes selPlayer, so board_endTrade
must be called first() */
(void)board_endTrade( board );
(void)server_commitTrade( board->server, &selTiles );
} else {
boardNotifyTrade( board, &selTiles );
}
}
} else {
XP_Bool warn, legal;
WordNotifierInfo info;
XWStreamCtxt* stream =
mem_stream_make( MPPARM(board->mpool)
util_getVTManager(board->util), NULL,
CHANNEL_NONE, (MemStreamCloseCallback)NULL );
const XP_UCHAR* str = util_getUserString(board->util,
STR_COMMIT_CONFIRM);
stream_catString( stream, str );
XWStreamCtxt* stream = NULL;
XP_Bool legal = alreadyConfirmed;
warn = board->util->gameInfo->phoniesAction == PHONIES_WARN;
if ( !legal ) {
WordNotifierInfo info;
XP_Bool warn;
stream = mem_stream_make( MPPARM(board->mpool)
util_getVTManager(board->util), NULL,
CHANNEL_NONE, (MemStreamCloseCallback)NULL );
board->badWordRejected = XP_FALSE;
info.proc = warnBadWords;
info.closure = board;
legal = model_checkMoveLegal( board->model, turn, stream,
const XP_UCHAR* str = util_getUserString(board->util,
STR_COMMIT_CONFIRM);
stream_catString( stream, str );
warn = board->util->gameInfo->phoniesAction == PHONIES_WARN;
board->badWordRejected = XP_FALSE;
info.proc = warnBadWords;
info.closure = board;
legal = model_checkMoveLegal( board->model, turn, stream,
warn? &info:(WordNotifierInfo*)NULL);
}
if ( !legal || board->badWordRejected ) {
result = XP_FALSE;
@ -1083,13 +1089,12 @@ board_commitTurn( BoardCtxt* board )
/* Hide the tray so no peeking. Leave it hidden even if user
cancels as otherwise another player could get around
passwords and peek at tiles. */
if ( gi_countLocalPlayers( board->gi, XP_TRUE ) > 1 ) {
if ( !alreadyConfirmed
&& gi_countLocalPlayers( board->gi, XP_TRUE ) > 1 ) {
result = board_hideTray( board );
}
if ( board->skipCommitConfirm
|| util_userQuery( board->util, QUERY_COMMIT_TURN,
stream ) ) {
if ( board->skipCommitConfirm || alreadyConfirmed ) {
result = server_commitMove( board->server ) || result;
/* invalidate all tiles in case we'll be drawing this tray
again rather than some other -- as is the case in a
@ -1098,9 +1103,14 @@ board_commitTurn( BoardCtxt* board )
showing points-this-turn), but this is easier. */
board_invalTrayTiles( board, ALLTILES );
pti->traySelBits = 0x00;
} else {
util_notifyMove( board->util, stream );
}
}
stream_destroy( stream );
if ( NULL != stream ) {
stream_destroy( stream );
}
if ( result ) {
setArrowVisibleFor( board, turn, XP_FALSE );

View file

@ -174,7 +174,7 @@ void board_hiliteCellAt( BoardCtxt* board, XP_U16 col, XP_U16 row );
void board_resetEngine( BoardCtxt* board );
XP_Bool board_commitTurn( BoardCtxt* board );
XP_Bool board_commitTurn( BoardCtxt* board, XP_Bool alreadyConfirmed );
void board_pushTimerSave( BoardCtxt* board );
void board_popTimerSave( BoardCtxt* board );

View file

@ -460,7 +460,7 @@ handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider )
}
#endif
} else if ( index == -(MAX_TRAY_TILES) ) { /* pending score tile */
result = board_commitTurn( board );
result = board_commitTurn( board, XP_FALSE );
#if defined XWFEATURE_TRAYUNDO_ALL
} else if ( index < 0 ) { /* other empty area */
/* it better be true */

View file

@ -64,12 +64,6 @@ typedef enum {
ERR_RELAY_END = ERR_RELAY_BASE + XWRELAY_ERROR_LASTERR
} UtilErrID;
typedef enum {
QUERY_COMMIT_TURN, /* 0 means cancel; 1 means commit */
QUERY_LAST_COMMON
} UtilQueryID;
#define PICKER_PICKALL -1
#define PICKER_BACKUP -2
@ -104,10 +98,9 @@ typedef struct UtilVtable {
XP_U16 col, XP_U16 row );
void (*m_util_userError)( XW_UtilCtxt* uc, UtilErrID id );
XP_Bool (*m_util_userQuery)( XW_UtilCtxt* uc, UtilQueryID id,
XWStreamCtxt* stream );
XP_Bool (*m_util_confirmTrade)( XW_UtilCtxt* uc, const XP_UCHAR** tiles,
XP_U16 nTiles );
void (*m_util_notifyMove)( XW_UtilCtxt* uc, XWStreamCtxt* stream );
void (*m_util_notifyTrade)( XW_UtilCtxt* uc, const XP_UCHAR** tiles,
XP_U16 nTiles );
/* return of < 0 means computer should pick */
XP_S16 (*m_util_userPickTileBlank)( XW_UtilCtxt* uc, XP_U16 playerNum,
const XP_UCHAR** tileFaces,
@ -235,11 +228,11 @@ struct XW_UtilCtxt {
#define util_userError(uc,err) \
(uc)->vtable->m_util_userError((uc),(err))
#define util_userQuery(uc,qcode,str) \
(uc)->vtable->m_util_userQuery((uc),(qcode),(str))
#define util_notifyMove(uc, str) \
(uc)->vtable->m_util_notifyMove((uc), (str))
#define util_confirmTrade( uc, tx, nt ) \
(uc)->vtable->m_util_confirmTrade((uc),(tx),(nt))
#define util_notifyTrade(uc, tx, nt) \
(uc)->vtable->m_util_notifyTrade((uc), (tx), (nt))
#define util_userPickTileBlank( uc, n, tx, nt ) \
(uc)->vtable->m_util_userPickTileBlank( (uc), (n), (tx), (nt) )

View file

@ -275,48 +275,35 @@ curses_util_userError( XW_UtilCtxt* uc, UtilErrID id )
}
} /* curses_util_userError */
static XP_Bool
curses_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id, XWStreamCtxt* stream )
static void
curses_util_notifyMove( XW_UtilCtxt* uc, XWStreamCtxt* stream )
{
CursesAppGlobals* globals;
CursesAppGlobals* globals = (CursesAppGlobals*)uc->closure;
char* question;
const char* answers[3] = {NULL};
short numAnswers = 0;
XP_Bool freeMe = XP_FALSE;
XP_Bool result;
XP_U16 okIndex = 1;
switch( id ) {
case QUERY_COMMIT_TURN:
question = strFromStream( stream );
freeMe = XP_TRUE;
answers[numAnswers++] = "Cancel";
answers[numAnswers++] = "Ok";
break;
question = strFromStream( stream );
freeMe = XP_TRUE;
answers[numAnswers++] = "Cancel";
answers[numAnswers++] = "Ok";
default:
XP_ASSERT( 0 );
return 0;
}
globals = (CursesAppGlobals*)uc->closure;
result = okIndex == cursesask( globals, question, numAnswers, answers );
// result = okIndex ==
cursesask( globals, question, numAnswers, answers );
if ( freeMe ) {
free( question );
}
return result;
} /* curses_util_userQuery */
static XP_Bool
curses_util_confirmTrade( XW_UtilCtxt* uc, const XP_UCHAR** tiles,
XP_U16 nTiles )
static void
curses_util_notifyTrade( XW_UtilCtxt* uc, const XP_UCHAR** tiles, XP_U16 nTiles )
{
CursesAppGlobals* globals = (CursesAppGlobals*)uc->closure;
char question[256];
formatConfirmTrade( tiles, nTiles, question, sizeof(question) );
const char* buttons[] = { "Cancel", "Ok" };
return 1 == cursesask( globals, question, VSIZE(buttons), buttons );
formatConfirmTrade( &globals->cGlobals, tiles, nTiles );
/* const char* buttons[] = { "Cancel", "Ok" }; */
/* cursesask( globals, question, VSIZE(buttons), buttons ); */
}
static void
@ -632,7 +619,8 @@ handleHint( CursesAppGlobals* globals )
static XP_Bool
handleCommit( CursesAppGlobals* globals )
{
globals->doDraw = board_commitTurn( globals->cGlobals.game.board );
globals->doDraw = board_commitTurn( globals->cGlobals.game.board,
XP_FALSE );
return XP_TRUE;
} /* handleCommit */
@ -1466,8 +1454,8 @@ setupCursesUtilCallbacks( CursesAppGlobals* globals, XW_UtilCtxt* util )
util->vtable->m_util_showChat = curses_util_showChat;
#endif
util->vtable->m_util_userQuery = curses_util_userQuery;
util->vtable->m_util_confirmTrade = curses_util_confirmTrade;
util->vtable->m_util_notifyMove = curses_util_notifyMove;
util->vtable->m_util_notifyTrade = curses_util_notifyTrade;
util->vtable->m_util_userPickTileBlank = curses_util_userPickTileBlank;
util->vtable->m_util_userPickTileTray = curses_util_userPickTileTray;
util->vtable->m_util_trayHiddenChange = curses_util_trayHiddenChange;

View file

@ -1445,7 +1445,7 @@ handle_trade_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
static void
handle_done_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
{
if ( board_commitTurn( globals->cGlobals.game.board ) ) {
if ( board_commitTurn( globals->cGlobals.game.board, XP_FALSE ) ) {
board_draw( globals->cGlobals.game.board );
disenable_buttons( globals );
}
@ -1543,7 +1543,7 @@ handle_hide_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
static void
handle_commit_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
{
if ( board_commitTurn( globals->cGlobals.game.board ) ) {
if ( board_commitTurn( globals->cGlobals.game.board, XP_FALSE ) ) {
board_draw( globals->cGlobals.game.board );
}
} /* handle_commit_button */
@ -1713,12 +1713,12 @@ static gint
ask_password( gpointer data )
{
GtkGameGlobals* globals = (GtkGameGlobals*)data;
CommonGlobals* cGlobals = &globals->cGlobals;
XP_UCHAR buf[32];
XP_U16 len = VSIZE(buf);
if ( gtkpasswdask( globals->askPassName, buf, &len ) ) {
BoardCtxt* board = globals->cGlobals.game.board;
if ( board_passwordProvided( board, globals->askPassPlayer, buf ) ) {
if ( gtkpasswdask( cGlobals->askPassName, buf, &len ) ) {
BoardCtxt* board = cGlobals->game.board;
if ( board_passwordProvided( board, cGlobals->selPlayer, buf ) ) {
board_draw( board );
}
}
@ -1729,8 +1729,9 @@ static void
gtk_util_informNeedPassword( XW_UtilCtxt* uc, XP_U16 player, const XP_UCHAR* name )
{
GtkGameGlobals* globals = (GtkGameGlobals*)uc->closure;
globals->askPassName = name;
globals->askPassPlayer = player;
CommonGlobals* cGlobals = &globals->cGlobals;
cGlobals->askPassName = name;
cGlobals->selPlayer = player;
(void)g_idle_add( ask_password, globals );
} /* gtk_util_askPassword */
@ -2237,46 +2238,68 @@ gtk_util_userError( XW_UtilCtxt* uc, UtilErrID id )
}
} /* gtk_util_userError */
static XP_Bool
gtk_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id,
XWStreamCtxt* stream )
static gint
ask_move( gpointer data )
{
GtkGameGlobals* globals = (GtkGameGlobals*)data;
CommonGlobals* cGlobals = &globals->cGlobals;
GtkButtonsType buttons = GTK_BUTTONS_YES_NO;
gint chosen = gtkask( globals->window, cGlobals->question, buttons, NULL );
if ( GTK_RESPONSE_OK == chosen || chosen == GTK_RESPONSE_YES ) {
BoardCtxt* board = cGlobals->game.board;
if ( board_commitTurn( board, XP_TRUE ) ) {
board_draw( board );
}
}
return 0;
}
static void
gtk_util_notifyMove( XW_UtilCtxt* uc, XWStreamCtxt* stream )
{
GtkGameGlobals* globals = (GtkGameGlobals*)uc->closure;
XP_Bool result;
char* question;
XP_Bool freeMe = XP_FALSE;
GtkButtonsType buttons = GTK_BUTTONS_YES_NO;
CommonGlobals* cGlobals = &globals->cGlobals;
/* char* question; */
/* XP_Bool freeMe = XP_FALSE; */
switch( id ) {
case QUERY_COMMIT_TURN:
question = strFromStream( stream );
freeMe = XP_TRUE;
break;
XP_U16 len = stream_getSize( stream );
XP_ASSERT( len <= VSIZE(cGlobals->question) );
stream_getBytes( stream, cGlobals->question, len );
(void)g_idle_add( ask_move, globals );
default:
XP_ASSERT( 0 );
return XP_FALSE;
}
gint chosen = gtkask( globals->window, question, buttons, NULL );
result = GTK_RESPONSE_OK == chosen || chosen == GTK_RESPONSE_YES;
/* question = strFromStream( stream ); */
/* strcpy( cGlobals->question, question ); */
/* free( question ); */
if ( freeMe ) {
free( question );
}
/* /\*gint chosen = *\/gtkask( globals->window, question, buttons, NULL ); */
// result = GTK_RESPONSE_OK == chosen || chosen == GTK_RESPONSE_YES;
return result;
} /* gtk_util_userQuery */
static XP_Bool
gtk_util_confirmTrade( XW_UtilCtxt* uc,
const XP_UCHAR** tiles, XP_U16 nTiles )
static gint
ask_trade( gpointer data )
{
GtkGameGlobals* globals = (GtkGameGlobals*)data;
CommonGlobals* cGlobals = &globals->cGlobals;
if ( GTK_RESPONSE_YES == gtkask( globals->window,
cGlobals->question,
GTK_BUTTONS_YES_NO, NULL ) ) {
BoardCtxt* board = cGlobals->game.board;
if ( board_commitTurn( board, XP_TRUE ) ) {
board_draw( board );
}
}
return 0;
}
static void
gtk_util_notifyTrade( XW_UtilCtxt* uc, const XP_UCHAR** tiles, XP_U16 nTiles )
{
GtkGameGlobals* globals = (GtkGameGlobals*)uc->closure;
char question[256];
formatConfirmTrade( tiles, nTiles, question, sizeof(question) );
return GTK_RESPONSE_YES == gtkask( globals->window, question,
GTK_BUTTONS_YES_NO, NULL );
formatConfirmTrade( &globals->cGlobals, tiles, nTiles );
(void)g_idle_add( ask_trade, globals );
}
static GtkWidget*
@ -2411,8 +2434,8 @@ static void
setupGtkUtilCallbacks( GtkGameGlobals* globals, XW_UtilCtxt* util )
{
util->vtable->m_util_userError = gtk_util_userError;
util->vtable->m_util_userQuery = gtk_util_userQuery;
util->vtable->m_util_confirmTrade = gtk_util_confirmTrade;
util->vtable->m_util_notifyMove = gtk_util_notifyMove;
util->vtable->m_util_notifyTrade = gtk_util_notifyTrade;
util->vtable->m_util_getVTManager = gtk_util_getVTManager;
util->vtable->m_util_userPickTileBlank = gtk_util_userPickTileBlank;
util->vtable->m_util_userPickTileTray = gtk_util_userPickTileTray;

View file

@ -134,10 +134,6 @@ typedef struct GtkGameGlobals {
DropTypeData dropData[COMMS_CONN_NTYPES];
// tmp state for while asking password
const XP_UCHAR* askPassName;
XP_U16 askPassPlayer;
XP_Bool gridOn;
XP_Bool mouseDown;
XP_Bool altKeyDown;

View file

@ -608,11 +608,11 @@ formatLMI( const LastMoveInfo* lmi, XP_UCHAR* buf, XP_U16 len )
}
void
formatConfirmTrade( const XP_UCHAR** tiles, XP_U16 nTiles,
char* buf, XP_U16 buflen )
formatConfirmTrade( CommonGlobals* cGlobals, const XP_UCHAR** tiles,
XP_U16 nTiles )
{
char tileBuf[128];
int offset = 0;
char tileBuf[128];
int ii;
XP_ASSERT( nTiles > 0 );
@ -623,7 +623,7 @@ formatConfirmTrade( const XP_UCHAR** tiles, XP_U16 nTiles,
}
tileBuf[offset-2] = '\0';
snprintf( buf, buflen,
snprintf( cGlobals->question, VSIZE(cGlobals->question),
"Are you sure you want to trade the selected tiles (%s)?",
tileBuf );
}

View file

@ -39,8 +39,9 @@ void linux_util_vt_destroy( XW_UtilCtxt* util );
const XP_UCHAR* linux_getErrString( UtilErrID id, XP_Bool* silent );
void formatConfirmTrade( const XP_UCHAR** tiles, XP_U16 nTiles, char* buf,
XP_U16 buflen );
void formatConfirmTrade( CommonGlobals* cGlobals, const XP_UCHAR** tiles,
XP_U16 nTiles );
void formatLMI( const LastMoveInfo* lmi, XP_UCHAR* buf, XP_U16 len );
void initNoConnStorage( CommonGlobals* cGlobals );

View file

@ -215,6 +215,11 @@ struct CommonGlobals {
/* hash by relayID of lists of messages */
GHashTable* noConnMsgs;
/* Saved state from util method to response method */
XP_U16 selPlayer;
char question[256*4];
const XP_UCHAR* askPassName;
#ifdef XWFEATURE_RELAY
int relaySocket; /* tcp connection to relay */
void* storage;

View file

@ -1634,7 +1634,7 @@ handleHidetrayCmd( CEAppGlobals* globals )
static XP_Bool
handleDoneCmd( CEAppGlobals* globals)
{
return board_commitTurn( globals->game.board );
return board_commitTurn( globals->game.board, XP_FALSE );
} /* handleDoneCmd */
static void