From 6c4b991566667f54f1c8dca1d157717aa9869f0f Mon Sep 17 00:00:00 2001 From: ehouse Date: Sat, 12 Sep 2009 21:39:13 +0000 Subject: [PATCH] Modify comms and games APIs so single struct of callbacks is passed instead of multiple callbacks; add callback called when relay state changes; adapt linux and palm clients to new API. (Wince changes pending.) --- xwords4/common/comms.c | 46 +++++++++++++++----------------------- xwords4/common/comms.h | 33 ++++++++++++++++++++++----- xwords4/common/game.c | 23 ++++++------------- xwords4/common/game.h | 9 +++----- xwords4/linux/cursesmain.c | 14 ++++++++---- xwords4/linux/gtkmain.c | 34 +++++++++++++++++++++++----- xwords4/palm/palmmain.c | 27 +++++++++++++++++----- 7 files changed, 116 insertions(+), 70 deletions(-) diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index 09e6d7118..a86305da7 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -77,13 +77,6 @@ typedef struct AddressRecord { #define ADDRESSRECORD_SIZE_68K 20 -typedef enum { - COMMS_RELAYSTATE_UNCONNECTED - , COMMS_RELAYSTATE_CONNECT_PENDING - , COMMS_RELAYSTATE_CONNECTED - , COMMS_RELAYSTATE_ALLCONNECTED -} CommsRelayState; - struct CommsCtxt { XW_UtilCtxt* util; @@ -93,9 +86,8 @@ struct CommsCtxt { AddressRecord* recs; /* return addresses */ - TransportSend sendproc; + TransportProcs procs; #ifdef COMMS_HEARTBEAT - TransportReset resetproc; XP_U32 lastMsgRcd; #endif void* sendClosure; @@ -201,7 +193,7 @@ static XP_S16 send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType typ, #ifdef XWFEATURE_RELAY #ifdef DEBUG -static const char* +const char* CommsRelayState2Str( CommsRelayState state ) { #define CASE_STR(s) case s: return #s @@ -226,6 +218,9 @@ set_relay_state( CommsCtxt* comms, CommsRelayState state ) CommsRelayState2Str(comms->r.relayState), CommsRelayState2Str(state) ); comms->r.relayState = state; + if ( !!comms->procs.rstatus ) { + (*comms->procs.rstatus)( comms->procs.closure, state ); + } } } @@ -247,8 +242,7 @@ CommsCtxt* comms_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isServer, XP_U16 XP_UNUSED_RELAY(nPlayersHere), XP_U16 XP_UNUSED_RELAY(nPlayersTotal), - TransportSend sendproc, IF_CH(TransportReset resetproc) - void* closure ) + const TransportProcs* procs ) { CommsCtxt* result = (CommsCtxt*)XP_MALLOC( mpool, sizeof(*result) ); XP_MEMSET( result, 0, sizeof(*result) ); @@ -256,11 +250,7 @@ comms_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isServer, MPASSIGN(result->mpool, mpool); result->isServer = isServer; - result->sendproc = sendproc; -#ifdef COMMS_HEARTBEAT - result->resetproc = resetproc; -#endif - result->sendClosure = closure; + XP_MEMCPY( &result->procs, procs, sizeof(result->procs) ); result->util = util; #ifdef XWFEATURE_RELAY @@ -435,8 +425,7 @@ addrFromStream( CommsAddrRec* addrP, XWStreamCtxt* stream ) CommsCtxt* comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util, - TransportSend sendproc, - IF_CH(TransportReset resetproc ) void* closure ) + const TransportProcs* procs ) { CommsCtxt* comms; XP_Bool isServer; @@ -463,8 +452,7 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util, nPlayersTotal = 0; } comms = comms_make( MPPARM(mpool) util, isServer, - nPlayersHere, nPlayersTotal, - sendproc, IF_CH(resetproc) closure ); + nPlayersHere, nPlayersTotal, procs ); XP_MEMCPY( &comms->addr, &addr, sizeof(comms->addr) ); comms->connID = stream_getU32( stream ); @@ -992,9 +980,9 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem ) const CommsAddrRec* addr; (void)channelToAddress( comms, channelNo, &addr ); - XP_ASSERT( !!comms->sendproc ); - result = (*comms->sendproc)( elem->msg, elem->len, addr, - comms->sendClosure ); + XP_ASSERT( !!comms->procs.send ); + result = (*comms->procs.send)( elem->msg, elem->len, addr, + comms->procs.closure ); } if ( result == elem->len ) { @@ -1137,6 +1125,7 @@ relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID ) relayErr = stream_getU8( stream ); srcID = stream_getU8( stream ); XP_LOGF( "%s: host id %x disconnected", __func__, srcID ); + set_relay_state( comms, COMMS_RELAYSTATE_CONNECTED ); /* we will eventually want to tell the user which player's gone */ util_userError( comms->util, ERR_RELAY_BASE + relayErr ); break; @@ -1144,8 +1133,8 @@ relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID ) case XWRELAY_DISCONNECT_YOU: /* Close socket for this? */ case XWRELAY_CONNECTDENIED: /* Close socket for this? */ relayErr = stream_getU8( stream ); - util_userError( comms->util, ERR_RELAY_BASE + relayErr ); set_relay_state( comms, COMMS_RELAYSTATE_UNCONNECTED ); + util_userError( comms->util, ERR_RELAY_BASE + relayErr ); /* fallthru */ default: XP_LOGF( "%s: dropping relay msg with cmd %d", __func__, (XP_U16)cmd ); @@ -1504,7 +1493,7 @@ heartbeat_checks( CommsCtxt* comms ) if ( comms->lastMsgRcvdTime < tooLongAgo ) { XP_LOGF( "%s: calling reset proc; last was %ld secs too long " "ago", __func__, tooLongAgo - comms->lastMsgRcvdTime ); - (*comms->resetproc)(comms->sendClosure); + (*comms->procs.reset)(comms->procs.closure); comms->lastMsgRcvdTime = 0; break; /* outta here */ } @@ -1787,7 +1776,8 @@ send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID, if ( buf != NULL ) { XP_U16 result; XP_LOGF( "%s: passing %d bytes to sendproc", __func__, len ); - result = (*comms->sendproc)( buf, len, &addr, comms->sendClosure ); + result = (*comms->procs.send)( buf, len, &addr, + comms->procs.closure ); success = result == len; if ( success ) { setHeartbeatTimer( comms ); @@ -1837,7 +1827,7 @@ send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType typ, XP_PlayerAddr channelNo, XP_MEMCPY( &buf[1], data, dlen ); } - nSent = (*comms->sendproc)( buf, dlen+1, addr, comms->sendClosure ); + nSent = (*comms->procs.send)( buf, dlen+1, addr, comms->procs.closure ); XP_FREE( comms->mpool, buf ); setHeartbeatTimer( comms ); diff --git a/xwords4/common/comms.h b/xwords4/common/comms.h index bd2d5e661..40763118d 100644 --- a/xwords4/common/comms.h +++ b/xwords4/common/comms.h @@ -45,6 +45,14 @@ typedef enum { ,COMMS_CONN_NTYPES } CommsConnType; +typedef enum { + COMMS_RELAYSTATE_UNCONNECTED + , COMMS_RELAYSTATE_CONNECT_PENDING + , COMMS_RELAYSTATE_CONNECTED + , COMMS_RELAYSTATE_ALLCONNECTED +} CommsRelayState; + + /* WHAT SHOULD THIS BE? Copied from Whiteboard.... PENDING */ #define XW_BT_UUID \ { 0x83, 0xe0, 0x87, 0xae, 0x4e, 0x18, 0x46, 0xbe, \ @@ -100,13 +108,29 @@ typedef struct CommsAddrRec { typedef XP_S16 (*TransportSend)( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addr, void* closure ); +#ifdef COMMS_HEARTBEAT typedef void (*TransportReset)( void* closure ); +#endif + +#ifdef XWFEATURE_RELAY +typedef void (*RelayStatusProc)( void* closure, CommsRelayState newState ); +#endif + +typedef struct _TransportProcs { + TransportSend send; +#ifdef COMMS_HEARTBEAT + TransportReset reset; +#endif +#ifdef XWFEATURE_RELAY + RelayStatusProc rstatus; +#endif + void* closure; +} TransportProcs; CommsCtxt* comms_make( MPFORMAL XW_UtilCtxt* util, XP_Bool isServer, XP_U16 nPlayersHere, XP_U16 nPlayersTotal, - TransportSend sendproc, IF_CH(TransportReset resetproc) - void* closure ); + const TransportProcs* procs ); void comms_reset( CommsCtxt* comms, XP_Bool isServer, XP_U16 nPlayersHere, XP_U16 nPlayersTotal ); @@ -128,9 +152,7 @@ CommsConnType comms_getConType( const CommsCtxt* comms ); XP_Bool comms_getIsServer( const CommsCtxt* comms ); CommsCtxt* comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, - XW_UtilCtxt* util, TransportSend sendproc, - IF_CH(TransportReset resetproc) - void* closure ); + XW_UtilCtxt* util, const TransportProcs* procs ); void comms_start( CommsCtxt* comms ); void comms_writeToStream( const CommsCtxt* comms, XWStreamCtxt* stream ); @@ -146,6 +168,7 @@ XP_Bool comms_checkComplete( const CommsAddrRec* addr ); # ifdef DEBUG void comms_getStats( CommsCtxt* comms, XWStreamCtxt* stream ); const char* ConnType2Str( CommsConnType typ ); +const char* CommsRelayState2Str( CommsRelayState state ); # endif EXTERN_C_END diff --git a/xwords4/common/game.c b/xwords4/common/game.c index 22530b4c8..57cfc517c 100644 --- a/xwords4/common/game.c +++ b/xwords4/common/game.c @@ -74,9 +74,7 @@ void game_makeNewGame( MPFORMAL XWGame* game, CurGameInfo* gi, XW_UtilCtxt* util, DrawCtx* draw, XP_U16 gameID, CommonPrefs* cp, - TransportSend XP_UNUSED_STANDALONE(sendproc), - IF_CH( TransportReset resetproc ) - void* XP_UNUSED_STANDALONE(closure) ) + const TransportProcs* procs ) { XP_U16 nPlayersHere, nPlayersTotal; @@ -89,11 +87,10 @@ game_makeNewGame( MPFORMAL XWGame* game, CurGameInfo* gi, gi->boardSize, gi->boardSize ); #ifndef XWFEATURE_STANDALONE_ONLY - if ( !!sendproc && gi->serverRole != SERVER_STANDALONE ) { + if ( !!procs && gi->serverRole != SERVER_STANDALONE ) { game->comms = comms_make( MPPARM(mpool) util, gi->serverRole != SERVER_ISCLIENT, - nPlayersHere, nPlayersTotal, - sendproc, IF_CH(resetproc) closure ); + nPlayersHere, nPlayersTotal, procs ); } else { game->comms = (CommsCtxt*)NULL; } @@ -116,9 +113,7 @@ void game_reset( MPFORMAL XWGame* game, CurGameInfo* gi, XW_UtilCtxt* XP_UNUSED_STANDALONE(util), XP_U16 gameID, CommonPrefs* cp, - TransportSend XP_UNUSED_STANDALONE(sendproc), - IF_CH(TransportReset resetproc) - void* XP_UNUSED_STANDALONE(closure) ) + const TransportProcs* procs ) { XP_U16 i; XP_U16 nPlayersHere, nPlayersTotal; @@ -144,8 +139,7 @@ game_reset( MPFORMAL XWGame* game, CurGameInfo* gi, } else if ( gi->serverRole != SERVER_STANDALONE ) { game->comms = comms_make( MPPARM(mpool) util, gi->serverRole != SERVER_ISCLIENT, - nPlayersHere, nPlayersTotal, - sendproc, IF_CH(resetproc) closure ); + nPlayersHere, nPlayersTotal, procs ); } #else # ifdef DEBUG @@ -175,9 +169,7 @@ XP_Bool game_makeFromStream( MPFORMAL XWStreamCtxt* stream, XWGame* game, CurGameInfo* gi, DictionaryCtxt* dict, XW_UtilCtxt* util, DrawCtx* draw, CommonPrefs* cp, - TransportSend XP_UNUSED_STANDALONE(sendProc), - IF_CH(TransportReset resetProc) - void* XP_UNUSED_STANDALONE(closure) ) + const TransportProcs* procs ) { XP_Bool success = XP_FALSE; XP_U8 strVersion; @@ -208,8 +200,7 @@ game_makeFromStream( MPFORMAL XWStreamCtxt* stream, XWGame* game, if ( hasComms ) { game->comms = comms_makeFromStream( MPPARM(mpool) stream, util, - sendProc, IF_CH(resetProc) - closure ); + procs ); } else { game->comms = NULL; } diff --git a/xwords4/common/game.h b/xwords4/common/game.h index cd3679319..21a76f15a 100644 --- a/xwords4/common/game.h +++ b/xwords4/common/game.h @@ -83,18 +83,15 @@ typedef struct XWGame { void game_makeNewGame( MPFORMAL XWGame* game, CurGameInfo* gi, XW_UtilCtxt* util, DrawCtx* draw, XP_U16 gameID, - CommonPrefs* cp, TransportSend sendproc, - IF_CH(TransportReset resetproc) void* closure); + CommonPrefs* cp, const TransportProcs* procs ); void game_reset( MPFORMAL XWGame* game, CurGameInfo* gi, XW_UtilCtxt* util, - XP_U16 gameID, CommonPrefs* cp, TransportSend sendproc, - IF_CH(TransportReset resetproc) void* closure ); + XP_U16 gameID, CommonPrefs* cp, const TransportProcs* procs ); XP_Bool game_makeFromStream( MPFORMAL XWStreamCtxt* stream, XWGame* game, CurGameInfo* gi, DictionaryCtxt* dict, XW_UtilCtxt* util, DrawCtx* draw, CommonPrefs* cp, - TransportSend sendProc, IF_CH(TransportReset rp) - void* closure ); + const TransportProcs* procs ); void game_saveToStream( const XWGame* game, const CurGameInfo* gi, XWStreamCtxt* stream ); diff --git a/xwords4/linux/cursesmain.c b/xwords4/linux/cursesmain.c index dd21cbb3f..536ba83d4 100644 --- a/xwords4/linux/cursesmain.c +++ b/xwords4/linux/cursesmain.c @@ -1450,6 +1450,14 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) g_globals.draw = (struct CursesDrawCtx*) cursesDrawCtxtMake( g_globals.boardWin ); + TransportProcs procs = { + .closure = &g_globals, + .send = LINUX_SEND, +#ifdef COMMS_HEARTBEAT + .reset = linux_reset, +#endif + }; + if ( !!params->fileName && file_exists( params->fileName ) ) { XWStreamCtxt* stream; stream = streamFromFile( &g_globals.cGlobals, params->fileName, @@ -1458,16 +1466,14 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) (void)game_makeFromStream( MEMPOOL stream, &g_globals.cGlobals.game, ¶ms->gi, dict, params->util, (DrawCtx*)g_globals.draw, - &g_globals.cp, - LINUX_SEND, IF_CH(linux_reset) &g_globals ); + &g_globals.cp, &procs ); stream_destroy( stream ); } else { gameID = (XP_U16)util_getCurSeconds( g_globals.cGlobals.params->util ); game_makeNewGame( MEMPOOL &g_globals.cGlobals.game, ¶ms->gi, params->util, (DrawCtx*)g_globals.draw, - gameID, &g_globals.cp, LINUX_SEND, - IF_CH(linux_reset) &g_globals ); + gameID, &g_globals.cp, &procs ); } #ifndef XWFEATURE_STANDALONE_ONLY diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index 24b2f7a7b..3c862b296 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -291,6 +291,12 @@ key_release_event( GtkWidget* XP_UNUSED(widget), GdkEventKey* event, # define MEMPOOL #endif +static void +relay_status_gtk( void* XP_UNUSED(closure), CommsRelayState state ) +{ + XP_LOGF( "%s got status: %s", __func__, CommsRelayState2Str(state) ); +} + static void createOrLoadObjects( GtkAppGlobals* globals ) { @@ -306,6 +312,17 @@ createOrLoadObjects( GtkAppGlobals* globals ) globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area, globals ); + TransportProcs procs = { + .closure = globals, + .send = LINUX_SEND, +#ifdef COMMS_HEARTBEAT + .reset = linux_reset, +#endif +#ifdef XWFEATURE_RELAY + .rstatus = relay_status_gtk, +#endif + }; + if ( !!params->fileName && file_exists( params->fileName ) ) { stream = streamFromFile( &globals->cGlobals, params->fileName, globals ); @@ -314,8 +331,7 @@ createOrLoadObjects( GtkAppGlobals* globals ) &globals->cGlobals.params->gi, params->dict, params->util, (DrawCtx*)globals->draw, - &globals->cp, - LINUX_SEND, IF_CH(linux_reset) globals ); + &globals->cp, &procs ); stream_destroy( stream ); } @@ -339,8 +355,7 @@ createOrLoadObjects( GtkAppGlobals* globals ) game_makeNewGame( MEMPOOL &globals->cGlobals.game, ¶ms->gi, params->util, (DrawCtx*)globals->draw, - params->gi.gameID, &globals->cp, LINUX_SEND, - IF_CH(linux_reset) globals ); + params->gi.gameID, &globals->cp, &procs ); addr.conType = params->conType; if ( 0 ) { @@ -646,10 +661,17 @@ new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals ) #ifndef XWFEATURE_STANDALONE_ONLY XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT; #endif + TransportProcs procs = { + .closure = globals, + .send = LINUX_SEND, +#ifdef COMMS_HEARTBEAT + .reset = linux_reset, +#endif + }; + game_reset( MEMPOOL &globals->cGlobals.game, gi, globals->cGlobals.params->util, - 0, &globals->cp, LINUX_SEND, - IF_CH(linux_reset) globals ); + 0, &globals->cp, &procs ); #ifndef XWFEATURE_STANDALONE_ONLY if ( !!globals->cGlobals.game.comms ) { diff --git a/xwords4/palm/palmmain.c b/xwords4/palm/palmmain.c index 64bf1c6c7..20f156f57 100644 --- a/xwords4/palm/palmmain.c +++ b/xwords4/palm/palmmain.c @@ -579,6 +579,17 @@ reportMissingDict( PalmAppGlobals* globals, XP_UCHAR* name ) } } /* reportMissingDict */ +static void +palmInitTProcs( PalmAppGlobals* globals, TransportProcs* procs ) +{ + XP_MEMSET( procs, 0, sizeof(*procs) ); + procs->send = palm_send; +#ifdef COMMS_HEARTBEAT + procs->reset = palm_reset; +#endif + procs->closure = globals; +} + static XP_Bool loadCurrentGame( PalmAppGlobals* globals, XP_U16 gIndex, XWGame* game, CurGameInfo* ginfo ) @@ -617,10 +628,12 @@ loadCurrentGame( PalmAppGlobals* globals, XP_U16 gIndex, } if ( success ) { + TransportProcs procs; + palmInitTProcs( globals, &procs ); success = game_makeFromStream( MEMPOOL recStream, game, ginfo, dict, &globals->util, globals->draw, &globals->gState.cp, - palm_send, IF_CH(palm_reset) globals ); + &procs ); } stream_destroy( recStream ); @@ -1201,6 +1214,7 @@ startApplication( PalmAppGlobals** globalsP ) postEmptyEvent( loadGameEvent ); globals->isFirstLaunch = false; } else { + TransportProcs procs; DictListEntry* dlep; /* if we're here because dict missing, don't re-init all prefs! */ @@ -1218,10 +1232,11 @@ startApplication( PalmAppGlobals** globalsP ) globals->gameInfo.dictName = copyString( globals->mpool, dlep->baseName ); + palmInitTProcs( globals, &procs ); game_makeNewGame( MEMPOOL &globals->game, &globals->gameInfo, &globals->util, globals->draw, 0, - &globals->gState.cp, - palm_send, IF_CH(palm_reset) globals ); + &globals->gState.cp, &procs ); + FrmPopupForm( XW_NEWGAMES_FORM ); } @@ -2016,9 +2031,11 @@ initAndStartBoard( PalmAppGlobals* globals, XP_Bool newGame ) } if ( newGame ) { + TransportProcs procs; + palmInitTProcs( globals, &procs ); game_reset( MEMPOOL &globals->game, &globals->gameInfo, - &globals->util, 0, &globals->gState.cp, - palm_send, IF_CH(palm_reset) globals ); + &globals->util, 0, &globals->gState.cp, &procs ); + #ifndef XWFEATURE_STANDALONE_ONLY if ( !!globals->game.comms ) { comms_setAddr( globals->game.comms,