mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-14 08:01:38 +01:00
improving lookup words experience: replace
util_userQuery(QUERY_ROBOT_MOVE) with new util_informMove(), into which the number of words formed and the words themselves are passed. The process of consing up the score explanation was already passing over the model, so storing the words is very little effort, and will save a call back into the model where the user actually wants to do the lookup.
This commit is contained in:
parent
b7691d2997
commit
77b9fa11a5
7 changed files with 69 additions and 19 deletions
|
@ -2033,11 +2033,6 @@ model_recentPassCountOk( ModelCtxt* model )
|
||||||
return count < okCount;
|
return count < okCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _RecordWordsInfo {
|
|
||||||
XWStreamCtxt* stream;
|
|
||||||
XP_U16 nWords;
|
|
||||||
} RecordWordsInfo;
|
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
recordWord( const XP_UCHAR* word, XP_Bool isLegal, void* closure )
|
recordWord( const XP_UCHAR* word, XP_Bool isLegal, void* closure )
|
||||||
{
|
{
|
||||||
|
@ -2049,9 +2044,23 @@ recordWord( const XP_UCHAR* word, XP_Bool isLegal, void* closure )
|
||||||
stream_putU8( stream, '\n' );
|
stream_putU8( stream, '\n' );
|
||||||
}
|
}
|
||||||
stream_catString( stream, word );
|
stream_catString( stream, word );
|
||||||
|
if ( NULL != info->nWordsP ) {
|
||||||
|
*info->nWordsP = info->nWords;
|
||||||
|
}
|
||||||
return XP_TRUE;
|
return XP_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WordNotifierInfo*
|
||||||
|
model_initWordCounter( ModelCtxt* model, XWStreamCtxt* stream, XP_U16* nWords )
|
||||||
|
{
|
||||||
|
model->vol.wni.proc = recordWord;
|
||||||
|
model->vol.wni.closure = &model->vol.rwi;
|
||||||
|
model->vol.rwi.stream = stream;
|
||||||
|
model->vol.rwi.nWordsP = nWords;
|
||||||
|
model->vol.rwi.nWords = 0;
|
||||||
|
return &model->vol.wni;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
model_getWordsPlayed( ModelCtxt* model, XP_U16 nTurns, XWStreamCtxt* stream )
|
model_getWordsPlayed( ModelCtxt* model, XP_U16 nTurns, XWStreamCtxt* stream )
|
||||||
{
|
{
|
||||||
|
@ -2067,19 +2076,14 @@ model_getWordsPlayed( ModelCtxt* model, XP_U16 nTurns, XWStreamCtxt* stream )
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( model_undoLatestMoves( model, NULL, nTurns, NULL, NULL ) ) {
|
if ( model_undoLatestMoves( model, NULL, nTurns, NULL, NULL ) ) {
|
||||||
RecordWordsInfo info = { .stream = stream, .nWords = 0 };
|
WordNotifierInfo* ni = model_initWordCounter( model, stream, NULL );
|
||||||
WordNotifierInfo notifyInfo = { .proc = recordWord,
|
|
||||||
.closure = &info,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Now push the undone moves back into the model one at a time.
|
/* Now push the undone moves back into the model one at a time.
|
||||||
recordWord() will add each played word to the stream as it's
|
recordWord() will add each played word to the stream as it's
|
||||||
scored */
|
scored */
|
||||||
buildModelFromStack( model, tmpStack, XP_TRUE,
|
buildModelFromStack( model, tmpStack, XP_TRUE,
|
||||||
nEntries - nTurns + nPlayers,/* skip assignments */
|
nEntries - nTurns + nPlayers,/* skip assignments */
|
||||||
(XWStreamCtxt*)NULL, ¬ifyInfo,
|
(XWStreamCtxt*)NULL, ni, (MovePrintFuncPre)NULL,
|
||||||
(MovePrintFuncPre)NULL, (MovePrintFuncPost)NULL,
|
(MovePrintFuncPost)NULL, NULL );
|
||||||
NULL );
|
|
||||||
}
|
}
|
||||||
stack_destroy( tmpStack );
|
stack_destroy( tmpStack );
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,6 +271,10 @@ XP_U16 figureMoveScore( const ModelCtxt* model, XP_U16 turn, MoveInfo* mvInfo,
|
||||||
EngineCtxt* engine, XWStreamCtxt* stream,
|
EngineCtxt* engine, XWStreamCtxt* stream,
|
||||||
WordNotifierInfo* notifyInfo );
|
WordNotifierInfo* notifyInfo );
|
||||||
|
|
||||||
|
/* tap into internal WordNotifierInfo */
|
||||||
|
WordNotifierInfo* model_initWordCounter( ModelCtxt* model, XWStreamCtxt* stream,
|
||||||
|
XP_U16* nWords );
|
||||||
|
|
||||||
/********************* persistence ********************/
|
/********************* persistence ********************/
|
||||||
#ifdef INCLUDE_IO_SUPPORT
|
#ifdef INCLUDE_IO_SUPPORT
|
||||||
void model_load( ModelCtxt* model, XP_Stream* inStream );
|
void model_load( ModelCtxt* model, XP_Stream* inStream );
|
||||||
|
|
|
@ -43,6 +43,12 @@ typedef struct PlayerCtxt {
|
||||||
PendingTile pendingTiles[MAX_TRAY_TILES];
|
PendingTile pendingTiles[MAX_TRAY_TILES];
|
||||||
} PlayerCtxt;
|
} PlayerCtxt;
|
||||||
|
|
||||||
|
typedef struct _RecordWordsInfo {
|
||||||
|
XWStreamCtxt* stream;
|
||||||
|
XP_U16* nWordsP;
|
||||||
|
XP_U16 nWords;
|
||||||
|
} RecordWordsInfo;
|
||||||
|
|
||||||
typedef struct ModelVolatiles {
|
typedef struct ModelVolatiles {
|
||||||
XW_UtilCtxt* util;
|
XW_UtilCtxt* util;
|
||||||
struct CurGameInfo* gi;
|
struct CurGameInfo* gi;
|
||||||
|
@ -55,6 +61,8 @@ typedef struct ModelVolatiles {
|
||||||
void* trayListenerData;
|
void* trayListenerData;
|
||||||
DictListener dictListenerFunc;
|
DictListener dictListenerFunc;
|
||||||
void* dictListenerData;
|
void* dictListenerData;
|
||||||
|
RecordWordsInfo rwi;
|
||||||
|
WordNotifierInfo wni;
|
||||||
XP_U16 nTilesOnBoard;
|
XP_U16 nTilesOnBoard;
|
||||||
MPSLOT
|
MPSLOT
|
||||||
} ModelVolatiles;
|
} ModelVolatiles;
|
||||||
|
|
|
@ -92,6 +92,8 @@ typedef struct ServerNonvolatiles {
|
||||||
|
|
||||||
RemoteAddress addresses[MAX_NUM_PLAYERS];
|
RemoteAddress addresses[MAX_NUM_PLAYERS];
|
||||||
XWStreamCtxt* prevMoveStream; /* save it to print later */
|
XWStreamCtxt* prevMoveStream; /* save it to print later */
|
||||||
|
XWStreamCtxt* prevWordsStream;
|
||||||
|
XP_U16 prevWordCount;
|
||||||
} ServerNonvolatiles;
|
} ServerNonvolatiles;
|
||||||
|
|
||||||
struct ServerCtxt {
|
struct ServerCtxt {
|
||||||
|
@ -174,7 +176,8 @@ getStateStr( XW_State st )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
|
//def DEBUG
|
||||||
static void
|
static void
|
||||||
logNewState( XW_State old, XW_State newst )
|
logNewState( XW_State old, XW_State newst )
|
||||||
{
|
{
|
||||||
|
@ -739,9 +742,14 @@ makeRobotMove( ServerCtxt* server )
|
||||||
model_makeTurnFromMoveInfo( model, turn, &newMove );
|
model_makeTurnFromMoveInfo( model, turn, &newMove );
|
||||||
|
|
||||||
if ( !!stream ) {
|
if ( !!stream ) {
|
||||||
(void)model_checkMoveLegal( model, turn, stream, NULL );
|
XWStreamCtxt* wordsStream = mkServerStream( server );
|
||||||
|
WordNotifierInfo* ni =
|
||||||
|
model_initWordCounter( model, wordsStream,
|
||||||
|
&server->nv.prevWordCount );
|
||||||
|
(void)model_checkMoveLegal( model, turn, stream, ni );
|
||||||
XP_ASSERT( !server->nv.prevMoveStream );
|
XP_ASSERT( !server->nv.prevMoveStream );
|
||||||
server->nv.prevMoveStream = stream;
|
server->nv.prevMoveStream = stream;
|
||||||
|
server->nv.prevWordsStream = wordsStream;
|
||||||
}
|
}
|
||||||
result = server_commitMove( server );
|
result = server_commitMove( server );
|
||||||
} else {
|
} else {
|
||||||
|
@ -848,8 +856,10 @@ showPrevScore( ServerCtxt* server )
|
||||||
stream_destroy( prevStream );
|
stream_destroy( prevStream );
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)util_userQuery( util, QUERY_ROBOT_MOVE, stream );
|
util_informMove( util, stream, server->nv.prevWordsStream,
|
||||||
|
server->nv.prevWordCount );
|
||||||
stream_destroy( stream );
|
stream_destroy( stream );
|
||||||
|
stream_destroy( server->nv.prevWordsStream );
|
||||||
}
|
}
|
||||||
SETSTATE( server, server->nv.stateAfterShow );
|
SETSTATE( server, server->nv.stateAfterShow );
|
||||||
} /* showPrevScore */
|
} /* showPrevScore */
|
||||||
|
|
|
@ -66,7 +66,6 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
QUERY_COMMIT_TURN, /* 0 means cancel; 1 means commit */
|
QUERY_COMMIT_TURN, /* 0 means cancel; 1 means commit */
|
||||||
QUERY_COMMIT_TRADE,
|
QUERY_COMMIT_TRADE,
|
||||||
QUERY_ROBOT_MOVE,
|
|
||||||
QUERY_ROBOT_TRADE,
|
QUERY_ROBOT_TRADE,
|
||||||
|
|
||||||
QUERY_LAST_COMMON
|
QUERY_LAST_COMMON
|
||||||
|
@ -131,6 +130,8 @@ typedef struct UtilVtable {
|
||||||
#ifdef XWFEATURE_TURNCHANGENOTIFY
|
#ifdef XWFEATURE_TURNCHANGENOTIFY
|
||||||
void (*m_util_turnChanged)(XW_UtilCtxt* uc);
|
void (*m_util_turnChanged)(XW_UtilCtxt* uc);
|
||||||
#endif
|
#endif
|
||||||
|
void (*m_util_informMove)( XW_UtilCtxt* uc, XWStreamCtxt* expl,
|
||||||
|
XWStreamCtxt* words, XP_U16 wordCount );
|
||||||
void (*m_util_notifyGameOver)( XW_UtilCtxt* uc );
|
void (*m_util_notifyGameOver)( XW_UtilCtxt* uc );
|
||||||
|
|
||||||
XP_Bool (*m_util_hiliteCell)( XW_UtilCtxt* uc, XP_U16 col, XP_U16 row );
|
XP_Bool (*m_util_hiliteCell)( XW_UtilCtxt* uc, XP_U16 col, XP_U16 row );
|
||||||
|
@ -227,6 +228,8 @@ struct XW_UtilCtxt {
|
||||||
# define util_turnChanged( uc )
|
# define util_turnChanged( uc )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define util_informMove(uc,e,w,wc) \
|
||||||
|
(uc)->vtable->m_util_informMove( (uc),(e),(w),(wc) )
|
||||||
#define util_notifyGameOver( uc ) \
|
#define util_notifyGameOver( uc ) \
|
||||||
(uc)->vtable->m_util_notifyGameOver((uc))
|
(uc)->vtable->m_util_notifyGameOver((uc))
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,6 @@ curses_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id, XWStreamCtxt* stream )
|
||||||
answers[numAnswers++] = "Cancel";
|
answers[numAnswers++] = "Cancel";
|
||||||
answers[numAnswers++] = "Ok";
|
answers[numAnswers++] = "Ok";
|
||||||
break;
|
break;
|
||||||
case QUERY_ROBOT_MOVE:
|
|
||||||
case QUERY_ROBOT_TRADE:
|
case QUERY_ROBOT_TRADE:
|
||||||
question = strFromStream( stream );
|
question = strFromStream( stream );
|
||||||
freeMe = XP_TRUE;
|
freeMe = XP_TRUE;
|
||||||
|
@ -332,6 +331,17 @@ cursesShowFinalScores( CursesAppGlobals* globals )
|
||||||
stream_destroy( stream );
|
stream_destroy( stream );
|
||||||
} /* cursesShowFinalScores */
|
} /* cursesShowFinalScores */
|
||||||
|
|
||||||
|
static void
|
||||||
|
curses_util_informMove( XW_UtilCtxt* uc, XWStreamCtxt* expl,
|
||||||
|
XWStreamCtxt* XP_UNUSED(words),
|
||||||
|
XP_U16 XP_UNUSED(wordCount) )
|
||||||
|
{
|
||||||
|
CursesAppGlobals* globals = (CursesAppGlobals*)uc->closure;
|
||||||
|
char* question = strFromStream( expl );
|
||||||
|
(void)cursesask( globals, question, 1, "Ok" );
|
||||||
|
free( question );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
curses_util_notifyGameOver( XW_UtilCtxt* uc )
|
curses_util_notifyGameOver( XW_UtilCtxt* uc )
|
||||||
{
|
{
|
||||||
|
@ -1465,6 +1475,7 @@ setupCursesUtilCallbacks( CursesAppGlobals* globals, XW_UtilCtxt* util )
|
||||||
util->vtable->m_util_userQuery = curses_util_userQuery;
|
util->vtable->m_util_userQuery = curses_util_userQuery;
|
||||||
util->vtable->m_util_userPickTile = curses_util_userPickTile;
|
util->vtable->m_util_userPickTile = curses_util_userPickTile;
|
||||||
util->vtable->m_util_trayHiddenChange = curses_util_trayHiddenChange;
|
util->vtable->m_util_trayHiddenChange = curses_util_trayHiddenChange;
|
||||||
|
util->vtable->m_util_informMove = curses_util_informMove;
|
||||||
util->vtable->m_util_notifyGameOver = curses_util_notifyGameOver;
|
util->vtable->m_util_notifyGameOver = curses_util_notifyGameOver;
|
||||||
util->vtable->m_util_hiliteCell = curses_util_hiliteCell;
|
util->vtable->m_util_hiliteCell = curses_util_hiliteCell;
|
||||||
util->vtable->m_util_engineProgressCallback =
|
util->vtable->m_util_engineProgressCallback =
|
||||||
|
|
|
@ -1386,6 +1386,16 @@ gtkShowFinalScores( const CommonGlobals* cGlobals )
|
||||||
free( text );
|
free( text );
|
||||||
} /* gtkShowFinalScores */
|
} /* gtkShowFinalScores */
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_util_informMove( XW_UtilCtxt* XP_UNUSED(uc), XWStreamCtxt* XP_UNUSED(expl),
|
||||||
|
XWStreamCtxt* words, XP_U16 wordCount )
|
||||||
|
{
|
||||||
|
XP_LOGF( "%s(wordCount=%d)", __func__, wordCount );
|
||||||
|
char* question = strFromStream( words/*expl*/ );
|
||||||
|
(void)gtkask( question, GTK_BUTTONS_OK );
|
||||||
|
free( question );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_util_notifyGameOver( XW_UtilCtxt* uc )
|
gtk_util_notifyGameOver( XW_UtilCtxt* uc )
|
||||||
{
|
{
|
||||||
|
@ -1763,7 +1773,6 @@ gtk_util_userQuery( XW_UtilCtxt* XP_UNUSED(uc), UtilQueryID id,
|
||||||
case QUERY_COMMIT_TRADE:
|
case QUERY_COMMIT_TRADE:
|
||||||
question = "Are you sure you want to trade the selected tiles?";
|
question = "Are you sure you want to trade the selected tiles?";
|
||||||
break;
|
break;
|
||||||
case QUERY_ROBOT_MOVE:
|
|
||||||
case QUERY_ROBOT_TRADE:
|
case QUERY_ROBOT_TRADE:
|
||||||
question = strFromStream( stream );
|
question = strFromStream( stream );
|
||||||
freeMe = XP_TRUE;
|
freeMe = XP_TRUE;
|
||||||
|
@ -1927,6 +1936,7 @@ setupGtkUtilCallbacks( GtkAppGlobals* globals, XW_UtilCtxt* util )
|
||||||
util->vtable->m_util_askPassword = gtk_util_askPassword;
|
util->vtable->m_util_askPassword = gtk_util_askPassword;
|
||||||
util->vtable->m_util_trayHiddenChange = gtk_util_trayHiddenChange;
|
util->vtable->m_util_trayHiddenChange = gtk_util_trayHiddenChange;
|
||||||
util->vtable->m_util_yOffsetChange = gtk_util_yOffsetChange;
|
util->vtable->m_util_yOffsetChange = gtk_util_yOffsetChange;
|
||||||
|
util->vtable->m_util_informMove = gtk_util_informMove;
|
||||||
util->vtable->m_util_notifyGameOver = gtk_util_notifyGameOver;
|
util->vtable->m_util_notifyGameOver = gtk_util_notifyGameOver;
|
||||||
util->vtable->m_util_hiliteCell = gtk_util_hiliteCell;
|
util->vtable->m_util_hiliteCell = gtk_util_hiliteCell;
|
||||||
util->vtable->m_util_altKeyDown = gtk_util_altKeyDown;
|
util->vtable->m_util_altKeyDown = gtk_util_altKeyDown;
|
||||||
|
|
Loading…
Reference in a new issue