From 32275017a6d57728085beac5924d9a62984cc6b2 Mon Sep 17 00:00:00 2001 From: Eric House <eehouse@eehouse.org> Date: Thu, 23 Feb 2023 15:51:40 -0800 Subject: [PATCH] implement rematch --- xwords4/common/boarddrw.c | 17 +++---- xwords4/common/server.c | 2 +- xwords4/wasm/main.c | 99 +++++++++++++++++++++++++++------------ 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/xwords4/common/boarddrw.c b/xwords4/common/boarddrw.c index 2e00efc44..6f3beb3b1 100644 --- a/xwords4/common/boarddrw.c +++ b/xwords4/common/boarddrw.c @@ -629,15 +629,16 @@ drawTradeWindowIf( BoardCtxt* board ) XP_Bool board_draw( BoardCtxt* board, XWEnv xwe ) { - if ( !!board->draw && board->boardBounds.width > 0 ) { - if ( draw_beginDraw( board->draw, xwe ) ) { + if ( !board->draw ) { + XP_LOGFF( "drawCtxt not set" ); + } else if ( 0 >= board->boardBounds.width ) { + XP_LOGFF( "boardBounds.width not set" ); + } else if ( draw_beginDraw( board->draw, xwe ) ) { + drawScoreBoard( board, xwe ); + drawTray( board, xwe ); + drawBoard( board, xwe ); - drawScoreBoard( board, xwe ); - drawTray( board, xwe ); - drawBoard( board, xwe ); - - draw_endDraw( board->draw, xwe ); - } + draw_endDraw( board->draw, xwe ); } return !board->needsDrawing && 0 == board->trayInvalBits; } /* board_draw */ diff --git a/xwords4/common/server.c b/xwords4/common/server.c index 2bf906c4e..ec1e77fd8 100644 --- a/xwords4/common/server.c +++ b/xwords4/common/server.c @@ -3988,7 +3988,7 @@ server_canRematch( const ServerCtxt* server ) : 0 < server->nv.rematchAddrsLen; break; } - LOG_RETURNF( "%s", boolToStr(result) ); + /* LOG_RETURNF( "%s", boolToStr(result) ); */ return result; } diff --git a/xwords4/wasm/main.c b/xwords4/wasm/main.c index c5c236559..64c9ebcb8 100644 --- a/xwords4/wasm/main.c +++ b/xwords4/wasm/main.c @@ -85,6 +85,7 @@ #define BUTTON_VALS "Vals" #define BUTTON_CHAT "Chat" #define BUTTON_INVITE "Invite" +#define BUTTON_REMATCH "Rematch" #define BUTTON_GAME_GAMES "Games" #define BUTTON_GAME_NEW "New Game" @@ -103,7 +104,10 @@ typedef struct _NewGameParams { char langName[32]; } NewGameParams; +static void removeGameState( GameState* gs ); static void updateScreen( GameState* gs, bool doSave ); +static void cleanupGame( GameState* gs ); +static void saveGame( GameState* gs ); static void updateDeviceButtons( Globals* globals ); static void clearScreen( Globals* globals ); static GameState* newGameState( Globals* globals ); @@ -148,7 +152,7 @@ EM_JS(void, show_name, (const char* name), { }); EM_JS(void, show_msgcount, (int count), { - let str = ""; + let str = "\u200C"; /* space that takes up vertial space in layout */ if ( 0 < count ) { str = "Pending msgs: " + count; } @@ -500,6 +504,31 @@ handleInvite( GameState* gs ) } } +static void +handleRematch( GameState* curGS ) +{ + LOG_FUNC(); + Globals* globals = curGS->globals; + GameState* newGS = newGameState( globals ); + newGS->util = wasm_util_make( MPPARM(globals->mpool) &newGS->gi, + globals->dutil, newGS ); + + if ( game_makeRematch( &curGS->game, NULL_XWE, newGS->util, + &globals->cp, (TransportProcs*)NULL, + &newGS->game, "newName" ) ) { + int gameID = newGS->gi.gameID; + + saveGame( newGS ); + removeGameState( newGS ); /* force reload with drawCtxt etc. */ + + loadAndDraw( globals, (NetLaunchInfo*)NULL, gameID, (NewGameParams*)NULL ); + } else { + XP_LOGFF( "failed" ); + cleanupGame( newGS ); + } + LOG_RETURN_VOID(); +} + static void onChatComposed( void* closure, const char* msg ) { @@ -547,6 +576,8 @@ onGameButton( void* closure, const char* button ) draw = board_prefsChanged( board, &globals->cp ); } else if ( 0 == strcmp(button, BUTTON_INVITE) ) { handleInvite(gs); + } else if ( 0 == strcmp(button, BUTTON_REMATCH) ) { + handleRematch(gs); } if ( draw ) { @@ -594,6 +625,10 @@ updateGameButtons( Globals* globals ) } buttons[cur++] = BUTTON_VALS; + + if ( gsi.canRematch ) { + buttons[cur++] = BUTTON_REMATCH; + } } } @@ -1175,7 +1210,7 @@ storeCurOpen( GameState* gs ) } static void -startGame( GameState* gs, const char* name ) +startGame( GameState* gs ) { Globals* globals = gs->globals; globals->curGame = gs; @@ -1187,11 +1222,6 @@ startGame( GameState* gs, const char* name ) resizeBoard( globals, gs ); if ( SERVER_ISCLIENT == gs->gi.serverRole ) { - if ( !!name ) { - replaceStringIfDifferent( globals->mpool, - &gs->gi.players[0].name, - name ); - } server_initClientConnection( gs->game.server, NULL_XWE ); } @@ -1211,9 +1241,6 @@ newFromInvite( Globals* globals, const NetLaunchInfo* nli ) gs->util = wasm_util_make( MPPARM(globals->mpool) &gs->gi, globals->dutil, gs ); - char playerName[32]; - main_getLocalName( globals, playerName, sizeof(playerName) ); - CommsAddrRec selfAddr = {0}; makeSelfAddr( globals, &selfAddr ); game_makeFromInvite( &gs->game, NULL_XWE, nli, @@ -1502,12 +1529,12 @@ loadAndDraw( Globals* globals, const NetLaunchInfo* invite, XP_LOGFF( "(gameID: %X)", gameID ); GameState* gs = NULL; - bool haveGame; if ( !params ) { /* First, load any saved game. We need it e.g. to confirm that an incoming invite is a dup and should be dropped. */ if ( 0 != gameID ) { gs = getSavedGame( globals, gameID ); + XP_LOGFF( "got game id %X", gameID ); } if ( !!invite ) { /* overwrite gs is ok: we'll likely want both games */ gs = gameFromInvite( globals, invite ); @@ -1568,7 +1595,7 @@ loadAndDraw( Globals* globals, const NetLaunchInfo* invite, } } if ( !!gs ) { - startGame( gs, NULL ); + startGame( gs ); } LOG_RETURN_VOID(); } @@ -1584,7 +1611,7 @@ main_gameFromInvite( Globals* globals, const NetLaunchInfo* invite ) { GameState* gs = gameFromInvite( globals, invite ); if ( gs ) { - startGame( gs, NULL ); + startGame( gs ); } } @@ -1950,6 +1977,28 @@ clearScreen( Globals* globals ) SDL_RenderPresent( globals->renderer ); } +static void +saveGame( GameState* gs ) +{ + Globals* globals = gs->globals; + XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(globals->mpool) + globals->vtMgr ); + game_saveToStream( &gs->game, &gs->gi, stream, ++gs->saveToken ); + + GameSummary summary; + game_summarize( &gs->game, &gs->gi, &summary ); + + char gameIDStr[32]; + formatGameID( gameIDStr, sizeof(gameIDStr), gs->gi.gameID ); + const XP_UCHAR* keys[] = { KEY_GAMES, gameIDStr, KEY_GAME, NULL }; + dutil_storeStream( globals->dutil, NULL_XWE, keys, stream ); + stream_destroy( stream ); + game_saveSucceeded( &gs->game, NULL_XWE, gs->saveToken ); + + keys[2] = KEY_SUMMARY; + dutil_storePtr( globals->dutil, NULL_XWE, keys, &summary, sizeof(summary) ); +} + static void updateScreen( GameState* gs, bool doSave ) { @@ -1959,34 +2008,22 @@ updateScreen( GameState* gs, bool doSave ) if ( !!gs->game.board ) { board_draw( gs->game.board, NULL_XWE ); wasm_draw_render( globals->draw, globals->renderer ); + } else { + XP_LOGFF( "no board for gid %X", gs->gi.gameID ); } SDL_RenderPresent( globals->renderer ); - + XP_LOGFF( "SDL_RenderPresent returned" ); } else { - XP_LOGFF( "not drawing %s; not visible", gs->gameName ); + XP_LOGFF( "not drawing %s/%X; not visible", gs->gameName, gs->gi.gameID ); } updateGameButtons( globals ); /* Let's save state here too, though likely too often */ if ( doSave ) { - XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(globals->mpool) - globals->vtMgr ); - game_saveToStream( &gs->game, &gs->gi, stream, ++gs->saveToken ); - - GameSummary summary; - game_summarize( &gs->game, &gs->gi, &summary ); - - char gameIDStr[32]; - formatGameID( gameIDStr, sizeof(gameIDStr), gs->gi.gameID ); - const XP_UCHAR* keys[] = { KEY_GAMES, gameIDStr, KEY_GAME, NULL }; - dutil_storeStream( globals->dutil, NULL_XWE, keys, stream ); - stream_destroy( stream ); - game_saveSucceeded( &gs->game, NULL_XWE, gs->saveToken ); - - keys[2] = KEY_SUMMARY; - dutil_storePtr( globals->dutil, NULL_XWE, keys, &summary, sizeof(summary) ); + saveGame( gs ); } + LOG_RETURN_VOID(); } void