mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-04 23:02:02 +01:00
make bad phonies alert non-blocking
Continue conversion of alerts that required blocking the JNI thread. Now board_commitTurn() takes a second boolean indicating whether phonies found have been approved by user. Common code informs user, and if he approves client code calls board_commitTurn() again. In case where turn's lost there's no call to make back, but there's the undesirable change that if a robot moves next its move will be reported on top of the turn-lost alert. Ideally new alerts would appear under, not on top of, those that have not yet been dismissed.
This commit is contained in:
parent
42aef7b85c
commit
c271202faa
17 changed files with 133 additions and 129 deletions
|
@ -275,7 +275,7 @@ public class BoardDelegate extends DelegateBase
|
||||||
lstnr = new OnClickListener() {
|
lstnr = new OnClickListener() {
|
||||||
public void onClick( DialogInterface dialog,
|
public void onClick( DialogInterface dialog,
|
||||||
int whichButton ) {
|
int whichButton ) {
|
||||||
handleViaThread( JNICmd.CMD_COMMIT_TRUE );
|
handleViaThread( JNICmd.CMD_COMMIT, true, true );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
dialog = ab.setMessage( msg )
|
dialog = ab.setMessage( msg )
|
||||||
|
@ -286,8 +286,21 @@ public class BoardDelegate extends DelegateBase
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLG_BADWORDS_BLK:
|
case NOTIFY_BADWORDS: {
|
||||||
checkBlocking();
|
lstnr = new OnClickListener() {
|
||||||
|
public void onClick( DialogInterface dlg, int bx ) {
|
||||||
|
handleViaThread( JNICmd.CMD_COMMIT, true, false );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dialog = ab.setTitle( R.string.phonies_found_title )
|
||||||
|
.setMessage( (String)params[0] )
|
||||||
|
.setPositiveButton( R.string.button_yes, lstnr )
|
||||||
|
.setNegativeButton( android.R.string.cancel, null )
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLG_BADWORDS:
|
||||||
case DLG_SCORES: {
|
case DLG_SCORES: {
|
||||||
int title = (Integer)params[0];
|
int title = (Integer)params[0];
|
||||||
String msg = (String)params[1];
|
String msg = (String)params[1];
|
||||||
|
@ -917,7 +930,7 @@ public class BoardDelegate extends DelegateBase
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R.id.board_menu_trade_commit:
|
case R.id.board_menu_trade_commit:
|
||||||
cmd = JNICmd.CMD_COMMIT_FALSE;
|
cmd = JNICmd.CMD_COMMIT;
|
||||||
break;
|
break;
|
||||||
case R.id.board_menu_trade_cancel:
|
case R.id.board_menu_trade_cancel:
|
||||||
cmd = JNICmd.CMD_CANCELTRADE;
|
cmd = JNICmd.CMD_CANCELTRADE;
|
||||||
|
@ -1045,7 +1058,7 @@ public class BoardDelegate extends DelegateBase
|
||||||
Utils.launchSettings( m_activity );
|
Utils.launchSettings( m_activity );
|
||||||
break;
|
break;
|
||||||
case COMMIT_ACTION:
|
case COMMIT_ACTION:
|
||||||
cmd = JNICmd.CMD_COMMIT_FALSE;
|
cmd = JNICmd.CMD_COMMIT;
|
||||||
break;
|
break;
|
||||||
case SHOW_EXPL_ACTION:
|
case SHOW_EXPL_ACTION:
|
||||||
showToast( m_toastStr );
|
showToast( m_toastStr );
|
||||||
|
@ -1240,7 +1253,7 @@ public class BoardDelegate extends DelegateBase
|
||||||
public void onClick( View view )
|
public void onClick( View view )
|
||||||
{
|
{
|
||||||
if ( view == m_exchCommmitButton ) {
|
if ( view == m_exchCommmitButton ) {
|
||||||
handleViaThread( JNICmd.CMD_COMMIT_FALSE );
|
handleViaThread( JNICmd.CMD_COMMIT );
|
||||||
} else if ( view == m_exchCancelButton ) {
|
} else if ( view == m_exchCancelButton ) {
|
||||||
handleViaThread( JNICmd.CMD_CANCELTRADE );
|
handleViaThread( JNICmd.CMD_CANCELTRADE );
|
||||||
}
|
}
|
||||||
|
@ -2034,33 +2047,21 @@ public class BoardDelegate extends DelegateBase
|
||||||
handleViaThread( JNICmd.CMD_POST_OVER );
|
handleViaThread( JNICmd.CMD_POST_OVER );
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void yOffsetChange( int maxOffset, int oldOffset, int newOffset )
|
|
||||||
// {
|
|
||||||
// DbgUtils.logf( "yOffsetChange(maxOffset=%d)", maxOffset );
|
|
||||||
// m_view.setVerticalScrollBarEnabled( maxOffset > 0 );
|
|
||||||
// }
|
|
||||||
@Override
|
@Override
|
||||||
public boolean warnIllegalWord( String dict, String[] words, int turn,
|
public void notifyIllegalWords( String dict, String[] words, int turn,
|
||||||
boolean turnLost )
|
boolean turnLost )
|
||||||
{
|
{
|
||||||
boolean accept = turnLost;
|
|
||||||
|
|
||||||
String wordsString = TextUtils.join( ", ", words );
|
String wordsString = TextUtils.join( ", ", words );
|
||||||
String message =
|
String message =
|
||||||
getString( R.string.ids_badwords_fmt, wordsString, dict );
|
getString( R.string.ids_badwords_fmt, wordsString, dict );
|
||||||
|
|
||||||
if ( turnLost ) {
|
if ( turnLost ) {
|
||||||
waitBlockingDialog( DlgID.DLG_BADWORDS_BLK, 0, R.string.badwords_title,
|
showDialogFragment( DlgID.DLG_BADWORDS, R.string.badwords_title,
|
||||||
message + getString( R.string.badwords_lost ) );
|
message + getString( R.string.badwords_lost ) );
|
||||||
} else {
|
} else {
|
||||||
Assert.fail();
|
String msg = message + getString( R.string.badwords_accept );
|
||||||
// String dlgBytes = message + getString( R.string.badwords_accept );
|
showDialogFragment( DlgID.NOTIFY_BADWORDS, msg );
|
||||||
// accept = 0 != waitBlockingDialog( DlgID.QUERY_REQUEST_BLK, 0,
|
|
||||||
// R.string.query_title,
|
|
||||||
// dlgBytes );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return accept;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's have this block in case there are multiple messages. If
|
// Let's have this block in case there are multiple messages. If
|
||||||
|
|
|
@ -57,7 +57,8 @@ public enum DlgID {
|
||||||
, WARN_NODICT
|
, WARN_NODICT
|
||||||
, WARN_NODICT_NEW
|
, WARN_NODICT_NEW
|
||||||
, WARN_NODICT_SUBST
|
, WARN_NODICT_SUBST
|
||||||
, DLG_BADWORDS_BLK
|
, DLG_BADWORDS
|
||||||
|
, NOTIFY_BADWORDS
|
||||||
, QUERY_MOVE
|
, QUERY_MOVE
|
||||||
, QUERY_TRADE
|
, QUERY_TRADE
|
||||||
, PICK_TILE_REQUESTBLANK
|
, PICK_TILE_REQUESTBLANK
|
||||||
|
|
|
@ -71,8 +71,7 @@ public class JNIThread extends Thread {
|
||||||
CMD_KEYDOWN,
|
CMD_KEYDOWN,
|
||||||
CMD_KEYUP,
|
CMD_KEYUP,
|
||||||
CMD_TIMER_FIRED,
|
CMD_TIMER_FIRED,
|
||||||
CMD_COMMIT_FALSE,
|
CMD_COMMIT,
|
||||||
CMD_COMMIT_TRUE,
|
|
||||||
CMD_JUGGLE,
|
CMD_JUGGLE,
|
||||||
CMD_FLIP,
|
CMD_FLIP,
|
||||||
CMD_TOGGLE_TRAY,
|
CMD_TOGGLE_TRAY,
|
||||||
|
@ -544,13 +543,14 @@ public class JNIThread extends Thread {
|
||||||
draw = processKeyEvent( elem.m_cmd, (XwJNI.XP_Key)args[0], barr );
|
draw = processKeyEvent( elem.m_cmd, (XwJNI.XP_Key)args[0], barr );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_COMMIT_FALSE:
|
case CMD_COMMIT:
|
||||||
draw = XwJNI.board_commitTurn( m_jniGamePtr, false );
|
boolean phoniesConfirmed = args.length < 1
|
||||||
|
? false : (Boolean)args[0];
|
||||||
|
boolean turnConfirmed = args.length < 2
|
||||||
|
? false : (Boolean)args[1];
|
||||||
|
draw = XwJNI.board_commitTurn( m_jniGamePtr, phoniesConfirmed,
|
||||||
|
turnConfirmed );
|
||||||
break;
|
break;
|
||||||
case CMD_COMMIT_TRUE:
|
|
||||||
draw = XwJNI.board_commitTurn( m_jniGamePtr, true );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CMD_JUGGLE:
|
case CMD_JUGGLE:
|
||||||
draw = XwJNI.board_juggleTray( m_jniGamePtr );
|
draw = XwJNI.board_juggleTray( m_jniGamePtr );
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -141,7 +141,7 @@ public interface UtilCtxt {
|
||||||
// Don't need this unless we have a scroll thumb to indicate position
|
// Don't need this unless we have a scroll thumb to indicate position
|
||||||
//void yOffsetChange( int maxOffset, int oldOffset, int newOffset );
|
//void yOffsetChange( int maxOffset, int oldOffset, int newOffset );
|
||||||
|
|
||||||
boolean warnIllegalWord( String dict, String[] words, int turn,
|
void notifyIllegalWords( String dict, String[] words, int turn,
|
||||||
boolean turnLost );
|
boolean turnLost );
|
||||||
|
|
||||||
void showChat( String msg, int fromIndx, String fromName );
|
void showChat( String msg, int fromIndx, String fromName );
|
||||||
|
|
|
@ -282,11 +282,10 @@ public class UtilCtxtImpl implements UtilCtxt {
|
||||||
subclassOverride( "notifyGameOver" );
|
subclassOverride( "notifyGameOver" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean warnIllegalWord( String dict, String[] words, int turn,
|
public void notifyIllegalWords( String dict, String[] words, int turn,
|
||||||
boolean turnLost )
|
boolean turnLost )
|
||||||
{
|
{
|
||||||
subclassOverride( "warnIllegalWord" );
|
subclassOverride( "notifyIllegalWords" );
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These need to go into some sort of chat DB, not dropped.
|
// These need to go into some sort of chat DB, not dropped.
|
||||||
|
|
|
@ -299,7 +299,9 @@ public class XwJNI {
|
||||||
public static native boolean board_showTray( GamePtr gamePtr );
|
public static native boolean board_showTray( GamePtr gamePtr );
|
||||||
public static native boolean board_toggle_showValues( 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 );
|
boolean phoniesConfirmed,
|
||||||
|
boolean turnConfirmed );
|
||||||
|
|
||||||
public static native boolean board_flip( GamePtr gamePtr );
|
public static native boolean board_flip( GamePtr gamePtr );
|
||||||
public static native boolean board_replaceTiles( GamePtr gamePtr );
|
public static native boolean board_replaceTiles( GamePtr gamePtr );
|
||||||
public static native int board_getSelPlayer( GamePtr gamePtr );
|
public static native int board_getSelPlayer( GamePtr gamePtr );
|
||||||
|
|
|
@ -897,6 +897,8 @@
|
||||||
found in the word list) -->
|
found in the word list) -->
|
||||||
<string name="default_phonies">Handle phonies</string>
|
<string name="default_phonies">Handle phonies</string>
|
||||||
|
|
||||||
|
<string name="phonies_found_title">Phonies found</string>
|
||||||
|
|
||||||
<!-- default number of minutes on timer for new games -->
|
<!-- default number of minutes on timer for new games -->
|
||||||
<string name="initial_player_minutes">Timer minutes per player</string>
|
<string name="initial_player_minutes">Timer minutes per player</string>
|
||||||
|
|
||||||
|
|
|
@ -454,25 +454,23 @@ and_util_getUserQuantityString( XW_UtilCtxt* uc, XP_U16 stringCode, XP_U16 quant
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XP_Bool
|
static void
|
||||||
and_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi,
|
and_util_notifyIllegalWords( XW_UtilCtxt* uc, BadWordInfo* bwi,
|
||||||
XP_U16 turn, XP_Bool turnLost )
|
XP_U16 turn, XP_Bool turnLost )
|
||||||
{
|
{
|
||||||
jboolean result = XP_FALSE;
|
UTIL_CBK_HEADER("notifyIllegalWords",
|
||||||
UTIL_CBK_HEADER("warnIllegalWord",
|
"(Ljava/lang/String;[Ljava/lang/String;IZ)V" );
|
||||||
"(Ljava/lang/String;[Ljava/lang/String;IZ)Z" );
|
|
||||||
XP_ASSERT( bwi->nWords > 0 );
|
XP_ASSERT( bwi->nWords > 0 );
|
||||||
if ( bwi->nWords > 0 ) {
|
if ( bwi->nWords > 0 ) {
|
||||||
jobjectArray jwords = makeStringArray( env, bwi->nWords,
|
jobjectArray jwords = makeStringArray( env, bwi->nWords,
|
||||||
(const XP_UCHAR**)bwi->words );
|
(const XP_UCHAR**)bwi->words );
|
||||||
XP_ASSERT( !!bwi->dictName );
|
XP_ASSERT( !!bwi->dictName );
|
||||||
jstring jname = (*env)->NewStringUTF( env, bwi->dictName );
|
jstring jname = (*env)->NewStringUTF( env, bwi->dictName );
|
||||||
result = (*env)->CallBooleanMethod( env, util->jutil, mid,
|
(*env)->CallVoidMethod( env, util->jutil, mid,
|
||||||
jname, jwords, turn, turnLost );
|
jname, jwords, turn, turnLost );
|
||||||
deleteLocalRefs( env, jwords, jname, DELETE_NO_REF );
|
deleteLocalRefs( env, jwords, jname, DELETE_NO_REF );
|
||||||
}
|
}
|
||||||
UTIL_CBK_TAIL();
|
UTIL_CBK_TAIL();
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XWFEATURE_CHAT
|
#ifdef XWFEATURE_CHAT
|
||||||
|
@ -732,7 +730,7 @@ makeUtil( MPFORMAL EnvThreadInfo* ti, jobject jutil, CurGameInfo* gi,
|
||||||
SET_PROC(makeEmptyDict);
|
SET_PROC(makeEmptyDict);
|
||||||
SET_PROC(getUserString);
|
SET_PROC(getUserString);
|
||||||
SET_PROC(getUserQuantityString);
|
SET_PROC(getUserQuantityString);
|
||||||
SET_PROC(warnIllegalWord);
|
SET_PROC(notifyIllegalWords);
|
||||||
#ifdef XWFEATURE_CHAT
|
#ifdef XWFEATURE_CHAT
|
||||||
SET_PROC(showChat);
|
SET_PROC(showChat);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1282,11 +1282,13 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1toggle_1showValues
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_org_eehouse_android_xw4_jni_XwJNI_board_1commitTurn
|
Java_org_eehouse_android_xw4_jni_XwJNI_board_1commitTurn
|
||||||
(JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean alreadyConfirmed)
|
(JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean phoniesConfirmed,
|
||||||
|
jboolean turnConfirmed)
|
||||||
{
|
{
|
||||||
jboolean result;
|
jboolean result;
|
||||||
XWJNI_START();
|
XWJNI_START();
|
||||||
result = board_commitTurn( state->game.board, alreadyConfirmed );
|
result = board_commitTurn( state->game.board, phoniesConfirmed,
|
||||||
|
turnConfirmed );
|
||||||
XWJNI_END();
|
XWJNI_END();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -984,8 +984,14 @@ hideMiniWindow( BoardCtxt* board, XP_Bool destroy, MiniWindowType winType )
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct _BadWordList {
|
||||||
|
BadWordInfo bwi;
|
||||||
|
XP_UCHAR buf[256];
|
||||||
|
XP_U16 index;
|
||||||
|
} BadWordList;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
warnBadWords( const XP_UCHAR* word, XP_Bool isLegal,
|
saveBadWords( const XP_UCHAR* word, XP_Bool isLegal,
|
||||||
const DictionaryCtxt* XP_UNUSED(dict),
|
const DictionaryCtxt* XP_UNUSED(dict),
|
||||||
#ifdef XWFEATURE_BOARDWORDS
|
#ifdef XWFEATURE_BOARDWORDS
|
||||||
const MoveInfo* XP_UNUSED(movei),
|
const MoveInfo* XP_UNUSED(movei),
|
||||||
|
@ -993,22 +999,14 @@ warnBadWords( const XP_UCHAR* word, XP_Bool isLegal,
|
||||||
#endif
|
#endif
|
||||||
void* closure )
|
void* closure )
|
||||||
{
|
{
|
||||||
XP_Bool ok = XP_TRUE;
|
|
||||||
if ( !isLegal ) {
|
if ( !isLegal ) {
|
||||||
BadWordInfo bwi = {0};
|
BadWordList* bwlp = (BadWordList*)closure;
|
||||||
BoardCtxt* board = (BoardCtxt*)closure;
|
bwlp->bwi.words[bwlp->bwi.nWords] = &bwlp->buf[bwlp->index];
|
||||||
XP_S16 turn = server_getCurrentTurn( board->server, NULL );
|
XP_STRCAT( &bwlp->buf[bwlp->index], word );
|
||||||
|
bwlp->index += XP_STRLEN(word) + 1;
|
||||||
bwi.nWords = 1;
|
++bwlp->bwi.nWords;
|
||||||
bwi.words[0] = word;
|
|
||||||
bwi.dictName =
|
|
||||||
dict_getShortName( model_getPlayerDict( board->model, turn ) );
|
|
||||||
|
|
||||||
ok = !board->badWordRejected
|
|
||||||
&& util_warnIllegalWord( board->util, &bwi, turn, XP_FALSE );
|
|
||||||
board->badWordRejected = !ok || board->badWordRejected;
|
|
||||||
}
|
}
|
||||||
} /* warnBadWords */
|
} /* saveBadWords */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
boardNotifyTrade( BoardCtxt* board, const TrayTileSet* tiles )
|
boardNotifyTrade( BoardCtxt* board, const TrayTileSet* tiles )
|
||||||
|
@ -1025,7 +1023,8 @@ boardNotifyTrade( BoardCtxt* board, const TrayTileSet* tiles )
|
||||||
}
|
}
|
||||||
|
|
||||||
XP_Bool
|
XP_Bool
|
||||||
board_commitTurn( BoardCtxt* board, XP_Bool alreadyConfirmed )
|
board_commitTurn( BoardCtxt* board, XP_Bool phoniesConfirmed,
|
||||||
|
XP_Bool turnConfirmed /* includes trade */ )
|
||||||
{
|
{
|
||||||
XP_Bool result = XP_FALSE;
|
XP_Bool result = XP_FALSE;
|
||||||
const XP_S16 turn = server_getCurrentTurn( board->server, NULL );
|
const XP_S16 turn = server_getCurrentTurn( board->server, NULL );
|
||||||
|
@ -1038,7 +1037,7 @@ board_commitTurn( BoardCtxt* board, XP_Bool alreadyConfirmed )
|
||||||
} else if ( 0 == model_getNumTilesTotal( board->model, turn ) ) {
|
} else if ( 0 == model_getNumTilesTotal( board->model, turn ) ) {
|
||||||
/* game's over but still undoable so turn hasn't changed; do
|
/* game's over but still undoable so turn hasn't changed; do
|
||||||
nothing */
|
nothing */
|
||||||
} else if ( alreadyConfirmed || checkRevealTray( board ) ) {
|
} else if ( phoniesConfirmed || turnConfirmed || checkRevealTray( board ) ) {
|
||||||
if ( pti->tradeInProgress ) {
|
if ( pti->tradeInProgress ) {
|
||||||
TileBit traySelBits = pti->traySelBits;
|
TileBit traySelBits = pti->traySelBits;
|
||||||
result = XP_TRUE; /* there's at least the window to clean up
|
result = XP_TRUE; /* there's at least the window to clean up
|
||||||
|
@ -1049,7 +1048,7 @@ board_commitTurn( BoardCtxt* board, XP_Bool alreadyConfirmed )
|
||||||
} else {
|
} else {
|
||||||
TrayTileSet selTiles;
|
TrayTileSet selTiles;
|
||||||
getSelTiles( board, traySelBits, &selTiles );
|
getSelTiles( board, traySelBits, &selTiles );
|
||||||
if ( alreadyConfirmed ) {
|
if ( turnConfirmed ) {
|
||||||
/* server_commitTrade() changes selPlayer, so board_endTrade
|
/* server_commitTrade() changes selPlayer, so board_endTrade
|
||||||
must be called first() */
|
must be called first() */
|
||||||
(void)board_endTrade( board );
|
(void)board_endTrade( board );
|
||||||
|
@ -1061,11 +1060,10 @@ board_commitTurn( BoardCtxt* board, XP_Bool alreadyConfirmed )
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XWStreamCtxt* stream = NULL;
|
XWStreamCtxt* stream = NULL;
|
||||||
XP_Bool legal = alreadyConfirmed;
|
XP_Bool legal = turnConfirmed;
|
||||||
|
BadWordList bwl = {0};
|
||||||
|
|
||||||
if ( !legal ) {
|
if ( !legal ) {
|
||||||
WordNotifierInfo info;
|
|
||||||
XP_Bool warn;
|
|
||||||
stream = mem_stream_make( MPPARM(board->mpool)
|
stream = mem_stream_make( MPPARM(board->mpool)
|
||||||
util_getVTManager(board->util), NULL,
|
util_getVTManager(board->util), NULL,
|
||||||
CHANNEL_NONE, (MemStreamCloseCallback)NULL );
|
CHANNEL_NONE, (MemStreamCloseCallback)NULL );
|
||||||
|
@ -1074,27 +1072,30 @@ board_commitTurn( BoardCtxt* board, XP_Bool alreadyConfirmed )
|
||||||
STR_COMMIT_CONFIRM);
|
STR_COMMIT_CONFIRM);
|
||||||
stream_catString( stream, str );
|
stream_catString( stream, str );
|
||||||
|
|
||||||
warn = board->util->gameInfo->phoniesAction == PHONIES_WARN;
|
XP_Bool warn = board->util->gameInfo->phoniesAction == PHONIES_WARN;
|
||||||
|
WordNotifierInfo info;
|
||||||
board->badWordRejected = XP_FALSE;
|
if ( warn ) {
|
||||||
info.proc = warnBadWords;
|
info.proc = saveBadWords;
|
||||||
info.closure = board;
|
info.closure = &bwl;
|
||||||
|
}
|
||||||
legal = model_checkMoveLegal( board->model, turn, stream,
|
legal = model_checkMoveLegal( board->model, turn, stream,
|
||||||
warn? &info:(WordNotifierInfo*)NULL);
|
warn? &info:(WordNotifierInfo*)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !legal || board->badWordRejected ) {
|
if ( 0 < bwl.bwi.nWords && !phoniesConfirmed ) {
|
||||||
result = XP_FALSE;
|
bwl.bwi.dictName =
|
||||||
|
dict_getShortName( model_getPlayerDict( board->model, turn ) );
|
||||||
|
util_notifyIllegalWords( board->util, &bwl.bwi, turn, XP_FALSE );
|
||||||
} else {
|
} else {
|
||||||
/* Hide the tray so no peeking. Leave it hidden even if user
|
/* Hide the tray so no peeking. Leave it hidden even if user
|
||||||
cancels as otherwise another player could get around
|
cancels as otherwise another player could get around
|
||||||
passwords and peek at tiles. */
|
passwords and peek at tiles. */
|
||||||
if ( !alreadyConfirmed
|
if ( !turnConfirmed
|
||||||
&& gi_countLocalPlayers( board->gi, XP_TRUE ) > 1 ) {
|
&& gi_countLocalPlayers( board->gi, XP_TRUE ) > 1 ) {
|
||||||
result = board_hideTray( board );
|
result = board_hideTray( board );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( board->skipCommitConfirm || alreadyConfirmed ) {
|
if ( board->skipCommitConfirm || turnConfirmed ) {
|
||||||
result = server_commitMove( board->server ) || result;
|
result = server_commitMove( board->server ) || result;
|
||||||
/* invalidate all tiles in case we'll be drawing this tray
|
/* invalidate all tiles in case we'll be drawing this tray
|
||||||
again rather than some other -- as is the case in a
|
again rather than some other -- as is the case in a
|
||||||
|
|
|
@ -176,7 +176,8 @@ XP_Bool board_setBlankValue( BoardCtxt* board, XP_U16 XP_UNUSED(player),
|
||||||
|
|
||||||
void board_resetEngine( BoardCtxt* board );
|
void board_resetEngine( BoardCtxt* board );
|
||||||
|
|
||||||
XP_Bool board_commitTurn( BoardCtxt* board, XP_Bool alreadyConfirmed );
|
XP_Bool board_commitTurn( BoardCtxt* board, XP_Bool phoniesConfirmed,
|
||||||
|
XP_Bool turnConfirmed );
|
||||||
|
|
||||||
void board_pushTimerSave( BoardCtxt* board );
|
void board_pushTimerSave( BoardCtxt* board );
|
||||||
void board_popTimerSave( BoardCtxt* board );
|
void board_popTimerSave( BoardCtxt* board );
|
||||||
|
|
|
@ -169,7 +169,6 @@ struct BoardCtxt {
|
||||||
XP_Bool showGrid;
|
XP_Bool showGrid;
|
||||||
XP_Bool gameOver;
|
XP_Bool gameOver;
|
||||||
XP_Bool leftHanded;
|
XP_Bool leftHanded;
|
||||||
XP_Bool badWordRejected;
|
|
||||||
XP_Bool timerPending;
|
XP_Bool timerPending;
|
||||||
XP_Bool disableArrow;
|
XP_Bool disableArrow;
|
||||||
XP_Bool hideValsInTray;
|
XP_Bool hideValsInTray;
|
||||||
|
|
|
@ -1618,7 +1618,7 @@ badWordMoveUndoAndTellUser( ServerCtxt* server, BadWordInfo* bwi )
|
||||||
|
|
||||||
model_rejectPreviousMove( model, server->pool, &turn );
|
model_rejectPreviousMove( model, server->pool, &turn );
|
||||||
|
|
||||||
util_warnIllegalWord( server->vol.util, bwi, turn, XP_TRUE );
|
util_notifyIllegalWords( server->vol.util, bwi, turn, XP_TRUE );
|
||||||
} /* badWordMoveUndoAndTellUser */
|
} /* badWordMoveUndoAndTellUser */
|
||||||
|
|
||||||
EngineCtxt*
|
EngineCtxt*
|
||||||
|
|
|
@ -460,7 +460,7 @@ handleActionInTray( BoardCtxt* board, XP_S16 index, XP_Bool onDivider )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if ( index == -(MAX_TRAY_TILES) ) { /* pending score tile */
|
} else if ( index == -(MAX_TRAY_TILES) ) { /* pending score tile */
|
||||||
result = board_commitTurn( board, XP_FALSE );
|
result = board_commitTurn( board, XP_FALSE, XP_FALSE );
|
||||||
#if defined XWFEATURE_TRAYUNDO_ALL
|
#if defined XWFEATURE_TRAYUNDO_ALL
|
||||||
} else if ( index < 0 ) { /* other empty area */
|
} else if ( index < 0 ) { /* other empty area */
|
||||||
/* it better be true */
|
/* it better be true */
|
||||||
|
|
|
@ -159,7 +159,7 @@ typedef struct UtilVtable {
|
||||||
XP_U16 stringCode,
|
XP_U16 stringCode,
|
||||||
XP_U16 quantity );
|
XP_U16 quantity );
|
||||||
|
|
||||||
XP_Bool (*m_util_warnIllegalWord)( XW_UtilCtxt* uc, BadWordInfo* bwi,
|
void (*m_util_notifyIllegalWords)( XW_UtilCtxt* uc, BadWordInfo* bwi,
|
||||||
XP_U16 turn, XP_Bool turnLost );
|
XP_U16 turn, XP_Bool turnLost );
|
||||||
|
|
||||||
void (*m_util_remSelected)(XW_UtilCtxt* uc);
|
void (*m_util_remSelected)(XW_UtilCtxt* uc);
|
||||||
|
@ -302,8 +302,8 @@ struct XW_UtilCtxt {
|
||||||
#define util_getUserQuantityString( uc, c, q ) \
|
#define util_getUserQuantityString( uc, c, q ) \
|
||||||
(uc)->vtable->m_util_getUserQuantityString((uc),(c),(q))
|
(uc)->vtable->m_util_getUserQuantityString((uc),(c),(q))
|
||||||
|
|
||||||
#define util_warnIllegalWord( uc, w, p, b ) \
|
#define util_notifyIllegalWords( uc, w, p, b ) \
|
||||||
(uc)->vtable->m_util_warnIllegalWord((uc),(w),(p),(b))
|
(uc)->vtable->m_util_notifyIllegalWords((uc),(w),(p),(b))
|
||||||
|
|
||||||
#define util_remSelected( uc ) \
|
#define util_remSelected( uc ) \
|
||||||
(uc)->vtable->m_util_remSelected((uc))
|
(uc)->vtable->m_util_remSelected((uc))
|
||||||
|
|
|
@ -620,7 +620,7 @@ static XP_Bool
|
||||||
handleCommit( CursesAppGlobals* globals )
|
handleCommit( CursesAppGlobals* globals )
|
||||||
{
|
{
|
||||||
globals->doDraw = board_commitTurn( globals->cGlobals.game.board,
|
globals->doDraw = board_commitTurn( globals->cGlobals.game.board,
|
||||||
XP_FALSE );
|
XP_FALSE, XP_FALSE );
|
||||||
return XP_TRUE;
|
return XP_TRUE;
|
||||||
} /* handleCommit */
|
} /* handleCommit */
|
||||||
|
|
||||||
|
@ -1371,15 +1371,14 @@ curses_util_turnChanged( XW_UtilCtxt* XP_UNUSED(uc), XP_S16 newTurn )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static XP_Bool
|
static void
|
||||||
curses_util_warnIllegalWord( XW_UtilCtxt* XP_UNUSED(uc),
|
curses_util_notifyIllegalWords( XW_UtilCtxt* XP_UNUSED(uc),
|
||||||
BadWordInfo* XP_UNUSED(bwi),
|
BadWordInfo* XP_UNUSED(bwi),
|
||||||
XP_U16 XP_UNUSED(player),
|
XP_U16 XP_UNUSED(player),
|
||||||
XP_Bool XP_UNUSED(turnLost) )
|
XP_Bool XP_UNUSED(turnLost) )
|
||||||
{
|
{
|
||||||
XP_WARNF( "curses_util_warnIllegalWord not implemented" );
|
XP_WARNF( "curses_util_notifyIllegalWords not implemented" );
|
||||||
return XP_FALSE;
|
} /* curses_util_notifyIllegalWord */
|
||||||
} /* curses_util_warnIllegalWord */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
curses_util_remSelected( XW_UtilCtxt* uc )
|
curses_util_remSelected( XW_UtilCtxt* uc )
|
||||||
|
@ -1445,7 +1444,7 @@ setupCursesUtilCallbacks( CursesAppGlobals* globals, XW_UtilCtxt* util )
|
||||||
#ifdef XWFEATURE_TURNCHANGENOTIFY
|
#ifdef XWFEATURE_TURNCHANGENOTIFY
|
||||||
util->vtable->m_util_turnChanged = curses_util_turnChanged;
|
util->vtable->m_util_turnChanged = curses_util_turnChanged;
|
||||||
#endif
|
#endif
|
||||||
util->vtable->m_util_warnIllegalWord = curses_util_warnIllegalWord;
|
util->vtable->m_util_notifyIllegalWords = curses_util_notifyIllegalWords;
|
||||||
util->vtable->m_util_remSelected = curses_util_remSelected;
|
util->vtable->m_util_remSelected = curses_util_remSelected;
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
util->vtable->m_util_makeStreamFromAddr = curses_util_makeStreamFromAddr;
|
util->vtable->m_util_makeStreamFromAddr = curses_util_makeStreamFromAddr;
|
||||||
|
|
|
@ -1445,7 +1445,7 @@ handle_trade_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
||||||
static void
|
static void
|
||||||
handle_done_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
handle_done_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
||||||
{
|
{
|
||||||
if ( board_commitTurn( globals->cGlobals.game.board, XP_FALSE ) ) {
|
if ( board_commitTurn( globals->cGlobals.game.board, XP_FALSE, XP_FALSE ) ) {
|
||||||
board_draw( globals->cGlobals.game.board );
|
board_draw( globals->cGlobals.game.board );
|
||||||
disenable_buttons( globals );
|
disenable_buttons( globals );
|
||||||
}
|
}
|
||||||
|
@ -1543,7 +1543,7 @@ handle_hide_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
||||||
static void
|
static void
|
||||||
handle_commit_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
handle_commit_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
||||||
{
|
{
|
||||||
if ( board_commitTurn( globals->cGlobals.game.board, XP_FALSE ) ) {
|
if ( board_commitTurn( globals->cGlobals.game.board, XP_FALSE, XP_FALSE ) ) {
|
||||||
board_draw( globals->cGlobals.game.board );
|
board_draw( globals->cGlobals.game.board );
|
||||||
}
|
}
|
||||||
} /* handle_commit_button */
|
} /* handle_commit_button */
|
||||||
|
@ -2117,49 +2117,48 @@ gtk_util_requestTime( XW_UtilCtxt* uc )
|
||||||
globals->idleID = g_idle_add( idle_func, globals );
|
globals->idleID = g_idle_add( idle_func, globals );
|
||||||
} /* gtk_util_requestTime */
|
} /* gtk_util_requestTime */
|
||||||
|
|
||||||
static XP_Bool
|
static gint
|
||||||
gtk_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi, XP_U16 player,
|
ask_bad_words( gpointer data )
|
||||||
XP_Bool turnLost )
|
{
|
||||||
|
GtkGameGlobals* globals = (GtkGameGlobals*)data;
|
||||||
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
|
|
||||||
|
if ( GTK_RESPONSE_YES == gtkask( globals->window, cGlobals->question,
|
||||||
|
GTK_BUTTONS_YES_NO, NULL ) ) {
|
||||||
|
board_commitTurn( cGlobals->game.board, XP_TRUE, XP_FALSE );
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_util_notifyIllegalWords( XW_UtilCtxt* uc, BadWordInfo* bwi, XP_U16 player,
|
||||||
|
XP_Bool turnLost )
|
||||||
{
|
{
|
||||||
XP_Bool result;
|
|
||||||
GtkGameGlobals* globals = (GtkGameGlobals*)uc->closure;
|
GtkGameGlobals* globals = (GtkGameGlobals*)uc->closure;
|
||||||
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
char buf[300];
|
char buf[300];
|
||||||
|
gchar* strs = g_strjoinv( "\", \"", (gchar**)bwi->words );
|
||||||
|
|
||||||
if ( turnLost ) {
|
if ( turnLost ) {
|
||||||
char wordsBuf[256];
|
XP_UCHAR* name = cGlobals->gi->players[player].name;
|
||||||
XP_U16 i;
|
|
||||||
XP_UCHAR* name = globals->cGlobals.gi->players[player].name;
|
|
||||||
XP_ASSERT( !!name );
|
XP_ASSERT( !!name );
|
||||||
|
|
||||||
for ( i = 0, wordsBuf[0] = '\0'; ; ) {
|
|
||||||
char wordBuf[18];
|
|
||||||
sprintf( wordBuf, "\"%s\"", bwi->words[i] );
|
|
||||||
strcat( wordsBuf, wordBuf );
|
|
||||||
if ( ++i == bwi->nWords ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
strcat( wordsBuf, ", " );
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf( buf, "Player %d (%s) played illegal word[s] %s; loses turn.",
|
sprintf( buf, "Player %d (%s) played illegal word[s] %s; loses turn.",
|
||||||
player+1, name, wordsBuf );
|
player+1, name, strs );
|
||||||
|
|
||||||
if ( globals->cGlobals.params->skipWarnings ) {
|
if ( cGlobals->params->skipWarnings ) {
|
||||||
XP_LOGF( "%s", buf );
|
XP_LOGF( "%s", buf );
|
||||||
} else {
|
} else {
|
||||||
gtkUserError( globals, buf );
|
gtkUserError( globals, buf );
|
||||||
}
|
}
|
||||||
result = XP_TRUE;
|
|
||||||
} else {
|
} else {
|
||||||
XP_ASSERT( bwi->nWords == 1 );
|
sprintf( cGlobals->question, "Word[s] \"%s\" not in the current dictionary (%s). "
|
||||||
sprintf( buf, "Word \"%s\" not in the current dictionary (%s). "
|
"Use anyway?", strs, bwi->dictName );
|
||||||
"Use it anyway?", bwi->words[0], bwi->dictName );
|
|
||||||
result = GTK_RESPONSE_YES == gtkask( globals->window, buf,
|
|
||||||
GTK_BUTTONS_YES_NO, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
(void)g_idle_add( ask_bad_words, globals );
|
||||||
} /* gtk_util_warnIllegalWord */
|
}
|
||||||
|
g_free( strs );
|
||||||
|
} /* gtk_util_notifyIllegalWords */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_util_remSelected( XW_UtilCtxt* uc )
|
gtk_util_remSelected( XW_UtilCtxt* uc )
|
||||||
|
@ -2276,7 +2275,7 @@ ask_move( gpointer data )
|
||||||
gint chosen = gtkask( globals->window, cGlobals->question, buttons, NULL );
|
gint chosen = gtkask( globals->window, cGlobals->question, buttons, NULL );
|
||||||
if ( GTK_RESPONSE_OK == chosen || chosen == GTK_RESPONSE_YES ) {
|
if ( GTK_RESPONSE_OK == chosen || chosen == GTK_RESPONSE_YES ) {
|
||||||
BoardCtxt* board = cGlobals->game.board;
|
BoardCtxt* board = cGlobals->game.board;
|
||||||
if ( board_commitTurn( board, XP_TRUE ) ) {
|
if ( board_commitTurn( board, XP_TRUE, XP_TRUE ) ) {
|
||||||
board_draw( board );
|
board_draw( board );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2315,7 +2314,7 @@ ask_trade( gpointer data )
|
||||||
cGlobals->question,
|
cGlobals->question,
|
||||||
GTK_BUTTONS_YES_NO, NULL ) ) {
|
GTK_BUTTONS_YES_NO, NULL ) ) {
|
||||||
BoardCtxt* board = cGlobals->game.board;
|
BoardCtxt* board = cGlobals->game.board;
|
||||||
if ( board_commitTurn( board, XP_TRUE ) ) {
|
if ( board_commitTurn( board, XP_TRUE, XP_TRUE ) ) {
|
||||||
board_draw( board );
|
board_draw( board );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2488,7 +2487,7 @@ setupGtkUtilCallbacks( GtkGameGlobals* globals, XW_UtilCtxt* util )
|
||||||
util->vtable->m_util_setTimer = gtk_util_setTimer;
|
util->vtable->m_util_setTimer = gtk_util_setTimer;
|
||||||
util->vtable->m_util_clearTimer = gtk_util_clearTimer;
|
util->vtable->m_util_clearTimer = gtk_util_clearTimer;
|
||||||
util->vtable->m_util_requestTime = gtk_util_requestTime;
|
util->vtable->m_util_requestTime = gtk_util_requestTime;
|
||||||
util->vtable->m_util_warnIllegalWord = gtk_util_warnIllegalWord;
|
util->vtable->m_util_notifyIllegalWords = gtk_util_notifyIllegalWords;
|
||||||
util->vtable->m_util_remSelected = gtk_util_remSelected;
|
util->vtable->m_util_remSelected = gtk_util_remSelected;
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
util->vtable->m_util_makeStreamFromAddr = gtk_util_makeStreamFromAddr;
|
util->vtable->m_util_makeStreamFromAddr = gtk_util_makeStreamFromAddr;
|
||||||
|
|
Loading…
Reference in a new issue