mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-15 15:41:24 +01:00
Fix nasty crashers: restore previous game when unable to open new,
e.g. because it was created with a dict that's no longer available (in which case warn to that effect.)
This commit is contained in:
parent
a72e4d0c13
commit
d2afc68ba8
1 changed files with 56 additions and 26 deletions
|
@ -148,7 +148,7 @@ static XP_Bool ceSaveCurGame( CEAppGlobals* globals, XP_Bool autoSave );
|
||||||
static void closeGame( CEAppGlobals* globals );
|
static void closeGame( CEAppGlobals* globals );
|
||||||
static void ceInitPrefs( CEAppGlobals* globals, CEAppPrefs* prefs );
|
static void ceInitPrefs( CEAppGlobals* globals, CEAppPrefs* prefs );
|
||||||
static void updateForColors( CEAppGlobals* globals );
|
static void updateForColors( CEAppGlobals* globals );
|
||||||
static XWStreamCtxt* make_generic_stream( CEAppGlobals* globals );
|
static XWStreamCtxt* make_generic_stream( const CEAppGlobals* globals );
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
static void ce_send_on_close( XWStreamCtxt* stream, void* closure );
|
static void ce_send_on_close( XWStreamCtxt* stream, void* closure );
|
||||||
#endif
|
#endif
|
||||||
|
@ -919,14 +919,14 @@ ceLoadPrefs( CEAppGlobals* globals )
|
||||||
} /* ceLoadPrefs */
|
} /* ceLoadPrefs */
|
||||||
|
|
||||||
static XWStreamCtxt*
|
static XWStreamCtxt*
|
||||||
make_generic_stream( CEAppGlobals* globals )
|
make_generic_stream( const CEAppGlobals* globals )
|
||||||
{
|
{
|
||||||
return mem_stream_make( MPPARM(globals->mpool) globals->vtMgr,
|
return mem_stream_make( MPPARM(globals->mpool) globals->vtMgr,
|
||||||
globals, 0, NULL );
|
(void*)globals, 0, NULL );
|
||||||
} /* make_generic_stream */
|
} /* make_generic_stream */
|
||||||
|
|
||||||
static XWStreamCtxt*
|
static XWStreamCtxt*
|
||||||
fileToStream( CEAppGlobals* globals, const XP_UCHAR* path )
|
fileToStream( const CEAppGlobals* globals, const XP_UCHAR* path )
|
||||||
{
|
{
|
||||||
XWStreamCtxt* stream = NULL;
|
XWStreamCtxt* stream = NULL;
|
||||||
HANDLE fileH;
|
HANDLE fileH;
|
||||||
|
@ -982,31 +982,42 @@ ceLoadSavedGame( CEAppGlobals* globals )
|
||||||
#ifdef STUBBED_DICT
|
#ifdef STUBBED_DICT
|
||||||
XP_ASSERT(0); /* just don't do this!!!! */
|
XP_ASSERT(0); /* just don't do this!!!! */
|
||||||
#else
|
#else
|
||||||
XP_UCHAR* name = stringFromStream( globals->mpool, stream );
|
XP_UCHAR* dictName = stringFromStream( globals->mpool, stream );
|
||||||
dict = ce_dictionary_make( globals, name );
|
dict = ce_dictionary_make( globals, dictName );
|
||||||
XP_FREE( globals->mpool, name );
|
|
||||||
success = dict != NULL;
|
success = dict != NULL;
|
||||||
|
if ( !success ) {
|
||||||
|
XP_UCHAR buf[128];
|
||||||
|
snprintf( buf, VSIZE(buf), "Unable to open dictionary: %s",
|
||||||
|
dictName );
|
||||||
|
buf[VSIZE(buf)-1] = '\0';
|
||||||
|
messageBoxChar( globals, buf, L"Oops!", MB_OK );
|
||||||
|
}
|
||||||
|
XP_FREE( globals->mpool, dictName );
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
dict = NULL;
|
dict = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flags >= CE_GAMEFILE_VERSION ) {
|
|
||||||
ce_draw_fromStream( globals->draw, stream );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
|
if ( flags >= CE_GAMEFILE_VERSION ) {
|
||||||
|
ce_draw_fromStream( globals->draw, stream );
|
||||||
|
}
|
||||||
|
|
||||||
XP_DEBUGF( "calling game_makeFromStream" );
|
XP_DEBUGF( "calling game_makeFromStream" );
|
||||||
game_makeFromStream( MEMPOOL stream, &globals->game,
|
success = game_makeFromStream( MEMPOOL stream, &globals->game,
|
||||||
&globals->gameInfo,
|
&globals->gameInfo, dict,
|
||||||
dict, &globals->util, (DrawCtx*)globals->draw,
|
&globals->util,
|
||||||
&globals->appPrefs.cp, CE_SEND_PROC,
|
(DrawCtx*)globals->draw,
|
||||||
CE_RESET_PROC globals );
|
&globals->appPrefs.cp, CE_SEND_PROC,
|
||||||
|
CE_RESET_PROC globals );
|
||||||
|
if ( success ) {
|
||||||
|
ceSetTitleFromName( globals );
|
||||||
|
} else if ( !!dict ) {
|
||||||
|
dict_destroy( dict );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_destroy( stream );
|
stream_destroy( stream );
|
||||||
|
|
||||||
ceSetTitleFromName( globals );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
@ -1470,13 +1481,16 @@ static void
|
||||||
ceChooseAndOpen( CEAppGlobals* globals )
|
ceChooseAndOpen( CEAppGlobals* globals )
|
||||||
{
|
{
|
||||||
// Save in case we'll be duplicating it
|
// Save in case we'll be duplicating it
|
||||||
if ( ceSaveCurGame( globals, XP_FALSE ) ) {
|
if ( ceSaveCurGame( globals, XP_FALSE )
|
||||||
|
|| queryBoxChar( globals, "Do you really want to "
|
||||||
|
"overwrite the current game?" ) ) {
|
||||||
wchar_t path[256];
|
wchar_t path[256];
|
||||||
path[0] = 0;
|
path[0] = 0;
|
||||||
|
|
||||||
ceSetTitleFromName( globals ); /* in case we named it above */
|
ceSetTitleFromName( globals ); /* in case we named it above */
|
||||||
|
|
||||||
if ( ceSavedGamesDlg( globals, globals->curGameName, path, VSIZE(path) )) {
|
if ( ceSavedGamesDlg( globals, globals->curGameName,
|
||||||
|
path, VSIZE(path) )) {
|
||||||
XP_UCHAR* name;
|
XP_UCHAR* name;
|
||||||
XP_U16 len;
|
XP_U16 len;
|
||||||
|
|
||||||
|
@ -1487,19 +1501,35 @@ ceChooseAndOpen( CEAppGlobals* globals )
|
||||||
name, len + 1, NULL, NULL );
|
name, len + 1, NULL, NULL );
|
||||||
|
|
||||||
if ( globals->curGameName != NULL
|
if ( globals->curGameName != NULL
|
||||||
&& 0 == XP_STRCMP( name, globals->curGameName ) ){ /*already open*/
|
&& 0 == XP_STRCMP( name, globals->curGameName ) ){
|
||||||
|
/* User chose already-open game; no-op */
|
||||||
XP_FREE( globals->mpool, name );
|
XP_FREE( globals->mpool, name );
|
||||||
} else if ( ceSaveCurGame( globals, XP_FALSE )
|
} else {
|
||||||
|| queryBoxChar( globals, "Do you really want to "
|
/* Save old name in case fail to open new, e.g. because dict
|
||||||
"overwrite the current game?" ) ) {
|
not there */
|
||||||
|
XP_UCHAR* oldName;
|
||||||
|
|
||||||
|
/* Need to save a second time, with auto-save, in case user
|
||||||
|
wants to overwrite yet chooses a game whose dict is
|
||||||
|
missing -- since then we'll be re-opening this game! */
|
||||||
|
ceSaveCurGame( globals, XP_TRUE ); /* may change curGameName */
|
||||||
|
|
||||||
|
oldName = globals->curGameName;
|
||||||
|
globals->curGameName = NULL; /* prevent being destroyed */
|
||||||
closeGame( globals );
|
closeGame( globals );
|
||||||
|
|
||||||
globals->curGameName = name;
|
globals->curGameName = name;
|
||||||
if ( ceLoadSavedGame( globals ) ) {
|
if ( ceLoadSavedGame( globals ) ) {
|
||||||
ceInitAndStartBoard( globals, XP_FALSE, NULL );
|
XP_FREE( globals->mpool, oldName );
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "failed to open chosen game" );
|
XP_LOGF( "failed to open chosen game" );
|
||||||
|
XP_FREE( globals->mpool, globals->curGameName );
|
||||||
|
globals->curGameName = oldName;
|
||||||
|
if ( !ceLoadSavedGame( globals ) ) {
|
||||||
|
XP_LOGF( "failed to open old game too!!!" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ceInitAndStartBoard( globals, XP_FALSE, NULL );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "GetOpenFileName() failed" );
|
XP_LOGF( "GetOpenFileName() failed" );
|
||||||
|
@ -1688,7 +1718,7 @@ closeGame( CEAppGlobals* globals )
|
||||||
game_dispose( &globals->game );
|
game_dispose( &globals->game );
|
||||||
gi_disposePlayerInfo( MPPARM(globals->mpool) &globals->gameInfo );
|
gi_disposePlayerInfo( MPPARM(globals->mpool) &globals->gameInfo );
|
||||||
|
|
||||||
if ( globals->curGameName ) {
|
if ( !!globals->curGameName ) {
|
||||||
XP_FREE( globals->mpool, globals->curGameName );
|
XP_FREE( globals->mpool, globals->curGameName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue