mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-08 05:24:39 +01:00
when a move comes in whose hash doesn't match the top of the move
stack, go down the stack looking for a match. If it's found, pop down to that point then apply the move. This fixes stalls in the test engine when undo is enabled, and so I assume that undos and turns are somehow coming in out-of-order. Should be rare that this happens.
This commit is contained in:
parent
dd242c3ff5
commit
02d5d26c60
3 changed files with 63 additions and 4 deletions
|
@ -1,6 +1,6 @@
|
||||||
/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */
|
/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */
|
||||||
/*
|
/*
|
||||||
* Copyright 2000-2011 by Eric House (xwords@eehouse.org). All rights
|
* Copyright 2000-2015 by Eric House (xwords@eehouse.org). All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -342,6 +342,56 @@ model_hashMatches( const ModelCtxt* model, const XP_U32 hash )
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XP_Bool
|
||||||
|
model_revertToHash( ModelCtxt* model, const XP_U32 hash, PoolContext* pool )
|
||||||
|
{
|
||||||
|
XP_U16 nPopped = 0;
|
||||||
|
StackCtxt* stack = model->vol.stack;
|
||||||
|
const XP_U16 nEntries = stack_getNEntries( stack );
|
||||||
|
StackEntry entries[nEntries];
|
||||||
|
#ifdef DEBUG
|
||||||
|
XP_U32 hashes[nEntries];
|
||||||
|
#endif
|
||||||
|
XP_S16 foundAt = -1;
|
||||||
|
|
||||||
|
for ( XP_U16 ii = 0; ii < nEntries; ++ii ) {
|
||||||
|
XP_U32 thisHash =
|
||||||
|
#ifdef DEBUG
|
||||||
|
hashes[ii] =
|
||||||
|
#endif
|
||||||
|
stack_getHash( stack );
|
||||||
|
if ( hash == thisHash ) {
|
||||||
|
foundAt = ii;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( ! stack_popEntry( stack, &entries[ii] ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++nPopped;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( XP_S16 ii = nPopped - 1; ii >= 0; --ii ) {
|
||||||
|
stack_redo( stack, &entries[ii] );
|
||||||
|
/* Assert not needed for long */
|
||||||
|
XP_ASSERT( hashes[ii] = stack_getHash( stack ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
XP_Bool found = -1 != foundAt;
|
||||||
|
if ( found ) {
|
||||||
|
XP_LOGF( "%s: undoing %d turns to match hash %X", __func__,
|
||||||
|
foundAt, hash );
|
||||||
|
#ifdef DEBUG
|
||||||
|
XP_Bool success =
|
||||||
|
#endif
|
||||||
|
model_undoLatestMoves( model, pool, foundAt, NULL, NULL );
|
||||||
|
XP_ASSERT( success );
|
||||||
|
/* Assert not needed for long */
|
||||||
|
XP_ASSERT( hash == stack_getHash( model->vol.stack ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef STREAM_VERS_BIGBOARD
|
#ifdef STREAM_VERS_BIGBOARD
|
||||||
void
|
void
|
||||||
model_setSquareBonuses( ModelCtxt* model, XWBonusType* bonuses, XP_U16 nBonuses )
|
model_setSquareBonuses( ModelCtxt* model, XWBonusType* bonuses, XP_U16 nBonuses )
|
||||||
|
|
|
@ -124,6 +124,9 @@ void model_setSize( ModelCtxt* model, XP_U16 boardSize );
|
||||||
void model_destroy( ModelCtxt* model );
|
void model_destroy( ModelCtxt* model );
|
||||||
XP_U32 model_getHash( const ModelCtxt* model, XP_U16 version );
|
XP_U32 model_getHash( const ModelCtxt* model, XP_U16 version );
|
||||||
XP_Bool model_hashMatches( const ModelCtxt* model, XP_U32 hash );
|
XP_Bool model_hashMatches( const ModelCtxt* model, XP_U32 hash );
|
||||||
|
XP_Bool model_revertToHash( ModelCtxt* model, const XP_U32 hash,
|
||||||
|
PoolContext* pool );
|
||||||
|
|
||||||
void model_setNPlayers( ModelCtxt* model, XP_U16 numPlayers );
|
void model_setNPlayers( ModelCtxt* model, XP_U16 numPlayers );
|
||||||
XP_U16 model_getNPlayers( const ModelCtxt* model );
|
XP_U16 model_getNPlayers( const ModelCtxt* model );
|
||||||
|
|
||||||
|
|
|
@ -2086,11 +2086,17 @@ readMoveInfo( ServerCtxt* server, XWStreamCtxt* stream,
|
||||||
#ifdef STREAM_VERS_BIGBOARD
|
#ifdef STREAM_VERS_BIGBOARD
|
||||||
if ( STREAM_VERS_BIGBOARD <= stream_getVersion( stream ) ) {
|
if ( STREAM_VERS_BIGBOARD <= stream_getVersion( stream ) ) {
|
||||||
XP_U32 hashReceived = stream_getU32( stream );
|
XP_U32 hashReceived = stream_getU32( stream );
|
||||||
success = model_hashMatches( server->vol.model, hashReceived );
|
success = model_hashMatches( server->vol.model, hashReceived )
|
||||||
|
|| model_revertToHash( server->vol.model, hashReceived,
|
||||||
|
server->pool );
|
||||||
// XP_ASSERT( success ); /* I need to understand when this can fail */
|
// XP_ASSERT( success ); /* I need to understand when this can fail */
|
||||||
if ( !success ) {
|
#ifdef DEBUG_HASHING
|
||||||
XP_LOGF( "%s: hash mismatch",__func__);
|
if ( success ) {
|
||||||
|
XP_LOGF( "%s: hash match: %X",__func__, hashReceived );
|
||||||
|
} else {
|
||||||
|
XP_LOGF( "%s: hash mismatch: %X not found",__func__, hashReceived );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
|
|
Loading…
Reference in a new issue