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.)
This commit is contained in:
ehouse 2009-09-12 21:39:13 +00:00
parent 86b560c441
commit 6c4b991566
7 changed files with 116 additions and 70 deletions

View file

@ -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 );

View file

@ -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

View file

@ -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;
}

View file

@ -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 );

View file

@ -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,
&params->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, &params->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

View file

@ -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, &params->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 ) {

View file

@ -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,