mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-18 22:26:30 +01:00
open game to receive message
This commit is contained in:
parent
e2beccc85c
commit
41cd3d8f39
4 changed files with 118 additions and 40 deletions
|
@ -38,6 +38,12 @@ extern "C" {
|
|||
|
||||
#define STREAM_INCR_SIZE 100
|
||||
|
||||
#ifdef XWFEATURE_STREAMREF
|
||||
# define REFCOUNT refCount
|
||||
#else
|
||||
# define REFCOUNT _unused_refCount
|
||||
#endif
|
||||
|
||||
#define SOCKET_STREAM_SUPER_COMMON_SLOTS \
|
||||
StreamCtxVTable* vtable; \
|
||||
void* closure; \
|
||||
|
@ -51,6 +57,7 @@ extern "C" {
|
|||
XP_U16 version; \
|
||||
XP_U8 nReadBits; \
|
||||
XP_U8 nWriteBits; \
|
||||
XP_U8 REFCOUNT; \
|
||||
XP_Bool isOpen; \
|
||||
MPSLOT
|
||||
|
||||
|
@ -93,7 +100,9 @@ mem_stream_make( MPFORMAL VTableMgr* vtmgr, void* closure,
|
|||
result->onClose = onClose;
|
||||
|
||||
result->isOpen = XP_TRUE;
|
||||
|
||||
#ifdef XWFEATURE_STREAMREF
|
||||
result->refCount = 1;
|
||||
#endif
|
||||
return (XWStreamCtxt*)result;
|
||||
} /* make_mem_stream */
|
||||
|
||||
|
@ -492,18 +501,34 @@ mem_stream_setPos( XWStreamCtxt* p_sctx, PosWhich which, XWStreamPos newpos )
|
|||
return oldPos;
|
||||
} /* mem_stream_setPos */
|
||||
|
||||
#ifdef XWFEATURE_STREAMREF
|
||||
static XWStreamCtxt*
|
||||
mem_stream_ref( XWStreamCtxt* p_sctx )
|
||||
{
|
||||
MemStreamCtxt* stream = (MemStreamCtxt*)p_sctx;
|
||||
++stream->refCount;
|
||||
return p_sctx;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
mem_stream_destroy( XWStreamCtxt* p_sctx, XWEnv xwe )
|
||||
{
|
||||
MemStreamCtxt* stream = (MemStreamCtxt*)p_sctx;
|
||||
if ( 0 ) {
|
||||
#ifdef XWFEATURE_STREAMREF
|
||||
} else if ( 0 == --stream->refCount ) {
|
||||
#else
|
||||
} else {
|
||||
#endif
|
||||
if ( stream->isOpen ) {
|
||||
stream_close( p_sctx, xwe );
|
||||
}
|
||||
|
||||
if ( stream->isOpen ) {
|
||||
stream_close( p_sctx, xwe );
|
||||
}
|
||||
|
||||
XP_FREEP( stream->mpool, &stream->buf );
|
||||
XP_FREEP( stream->mpool, &stream->buf );
|
||||
|
||||
XP_FREE( stream->mpool, stream );
|
||||
XP_FREE( stream->mpool, stream );
|
||||
}
|
||||
} /* mem_stream_destroy */
|
||||
|
||||
static StreamCtxVTable*
|
||||
|
@ -535,7 +560,9 @@ make_vtable( MemStreamCtxt* stream )
|
|||
|
||||
SET_VTABLE_ENTRY( vtable, stream_setPos, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_getPos, mem );
|
||||
|
||||
#ifdef XWFEATURE_STREAMREF
|
||||
SET_VTABLE_ENTRY( vtable, stream_ref, mem );
|
||||
#endif
|
||||
SET_VTABLE_ENTRY( vtable, stream_destroy, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_open, mem );
|
||||
SET_VTABLE_ENTRY( vtable, stream_close, mem );
|
||||
|
|
|
@ -55,6 +55,9 @@ typedef XP_U8 PosWhich;
|
|||
|
||||
|
||||
typedef struct StreamCtxVTable {
|
||||
#ifdef XWFEATURE_STREAMREF
|
||||
XWStreamCtxt* (*m_stream_ref)( XWStreamCtxt* dctx );
|
||||
#endif
|
||||
void (*m_stream_destroy)( XWStreamCtxt* dctx, XWEnv xwe );
|
||||
|
||||
XP_U8 (*m_stream_getU8)( DBG_PROC_FORMAL XWStreamCtxt* dctx );
|
||||
|
@ -110,6 +113,10 @@ struct XWStreamCtxt {
|
|||
StreamCtxVTable* vtable;
|
||||
};
|
||||
|
||||
#ifdef XWFEATURE_STREAMREF
|
||||
# define stream_ref(sc) \
|
||||
(sc)->vtable->m_stream_ref((sc))
|
||||
#endif
|
||||
|
||||
#define stream_destroy(sc,e) \
|
||||
(sc)->vtable->m_stream_destroy(sc,(e))
|
||||
|
|
|
@ -42,6 +42,7 @@ DEFINES += -DXWFEATURE_DICTSANITY
|
|||
DEFINES += -DPOINTER_SUPPORT
|
||||
DEFINES += -DPLATFORM_WASM
|
||||
DEFINES += -DXWFEATURE_CROSSHAIRS
|
||||
DEFINES += -DXWFEATURE_STREAMREF
|
||||
DEFINES += -DNATIVE_NLI
|
||||
DEFINES += -DDEBUG_REF
|
||||
DEFINES += -Wno-switch
|
||||
|
|
|
@ -603,6 +603,34 @@ onPlayerNamed( void* closure, const char* name )
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
doReplace( Globals* globals, const NetLaunchInfo* invite )
|
||||
{
|
||||
cleanupGame( globals );
|
||||
|
||||
gi_disposePlayerInfo( MPPARM(globals->mpool) &globals->gs.gi );
|
||||
XP_MEMSET( &globals->gs.gi, 0, sizeof(globals->gs.gi) );
|
||||
|
||||
globals->gs.util = wasm_util_make( MPPARM(globals->mpool) &globals->gs.gi,
|
||||
globals->dutil, globals );
|
||||
|
||||
game_makeFromInvite( MPPARM(globals->mpool) NULL, invite,
|
||||
&globals->gs.game, &globals->gs.gi,
|
||||
globals->dict, NULL,
|
||||
globals->gs.util, globals->draw,
|
||||
&globals->cp, &globals->procs );
|
||||
ensureName( globals );
|
||||
|
||||
const char* name = get_stored_value( KEY_PLAYER_NAME );
|
||||
if ( NULL != name ) {
|
||||
startGame( globals, name );
|
||||
free( (void*)name );
|
||||
} else {
|
||||
const char* msg = "Please enter your name so you opponent knows it's you";
|
||||
call_get_string( msg, "Player 1", onPlayerNamed, globals );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
onReplaceConfirmed( void* closure, bool confirmed )
|
||||
{
|
||||
|
@ -610,29 +638,7 @@ onReplaceConfirmed( void* closure, bool confirmed )
|
|||
Globals* globals = ars->globals;
|
||||
|
||||
if ( confirmed ) {
|
||||
cleanupGame( globals );
|
||||
|
||||
gi_disposePlayerInfo( MPPARM(globals->mpool) &globals->gs.gi );
|
||||
XP_MEMSET( &globals->gs.gi, 0, sizeof(globals->gs.gi) );
|
||||
|
||||
globals->gs.util = wasm_util_make( MPPARM(globals->mpool) &globals->gs.gi,
|
||||
globals->dutil, globals );
|
||||
|
||||
game_makeFromInvite( MPPARM(globals->mpool) NULL, &ars->invite,
|
||||
&globals->gs.game, &globals->gs.gi,
|
||||
globals->dict, NULL,
|
||||
globals->gs.util, globals->draw,
|
||||
&globals->cp, &globals->procs );
|
||||
ensureName( globals );
|
||||
|
||||
const char* name = get_stored_value( KEY_PLAYER_NAME );
|
||||
if ( NULL != name ) {
|
||||
startGame( globals, name );
|
||||
free( (void*)name );
|
||||
} else {
|
||||
const char* msg = "Please enter your name so you opponent knows it's you";
|
||||
call_get_string( msg, "Player 1", onPlayerNamed, globals );
|
||||
}
|
||||
doReplace( globals, &ars->invite );
|
||||
}
|
||||
|
||||
XP_FREE( globals->mpool, ars );
|
||||
|
@ -652,7 +658,7 @@ gameFromInvite( Globals* globals, const NetLaunchInfo* invite )
|
|||
} else {
|
||||
AskReplaceState* ars = XP_MALLOC( globals->mpool, sizeof(*ars) );
|
||||
ars->globals = globals;
|
||||
XP_MEMCPY( &ars->invite, invite, sizeof(ars->invite) );
|
||||
ars->invite = *invite;
|
||||
call_confirm( globals, "Invitation received; replace current game?",
|
||||
onReplaceConfirmed, ars );
|
||||
needsLoad = false;
|
||||
|
@ -660,6 +666,9 @@ gameFromInvite( Globals* globals, const NetLaunchInfo* invite )
|
|||
} else if ( invite->lang != 1 ) {
|
||||
call_alert( "Invitations are only supported for play in English right now." );
|
||||
needsLoad = false;
|
||||
} else {
|
||||
// No game open. Just do it
|
||||
doReplace( globals, invite );
|
||||
}
|
||||
|
||||
bool loaded = !needsLoad;
|
||||
|
@ -807,13 +816,39 @@ main_gameFromInvite( Globals* globals, const NetLaunchInfo* invite )
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct _OpenForMessageState {
|
||||
Globals* globals;
|
||||
int gameID;
|
||||
CommsAddrRec from;
|
||||
XWStreamCtxt* stream;
|
||||
} OpenForMessageState;
|
||||
|
||||
static void
|
||||
onOpenForMsgConfirmed( void* closure, bool confirmed )
|
||||
{
|
||||
OpenForMessageState* ofm = (OpenForMessageState*)closure;
|
||||
Globals* globals = ofm->globals;
|
||||
if ( confirmed ) {
|
||||
|
||||
char gameID[16];
|
||||
formatGameID( gameID, sizeof(gameID), ofm->gameID );
|
||||
loadAndDraw( globals, NULL, gameID, NULL );
|
||||
XP_ASSERT( globals->gs.gi.gameID == ofm->gameID );
|
||||
|
||||
if ( game_receiveMessage( &globals->gs.game, NULL, ofm->stream, &ofm->from ) ) {
|
||||
updateScreen( globals, true );
|
||||
}
|
||||
}
|
||||
stream_destroy( ofm->stream, NULL );
|
||||
XP_FREE( globals->mpool, ofm );
|
||||
}
|
||||
|
||||
void
|
||||
main_onGameMessage( Globals* globals, XP_U32 gameID,
|
||||
const CommsAddrRec* from, XWStreamCtxt* stream )
|
||||
{
|
||||
if ( gameID == globals->gs.gi.gameID ) {
|
||||
XP_Bool draw = game_receiveMessage( &globals->gs.game, NULL, stream, from );
|
||||
if ( draw ) {
|
||||
if ( gameID == globals->gs.gi.gameID ) { /* current game open */
|
||||
if ( game_receiveMessage( &globals->gs.game, NULL, stream, from ) ) {
|
||||
updateScreen( globals, true );
|
||||
}
|
||||
} else {
|
||||
|
@ -822,20 +857,28 @@ main_onGameMessage( Globals* globals, XP_U32 gameID,
|
|||
if ( have_stored_value( key ) ) {
|
||||
formatNameKey( key, sizeof(key), gameID );
|
||||
const char* name = get_stored_value( key );
|
||||
char buf[128];
|
||||
snprintf( buf, sizeof(buf), "Dropping packet for closed game \"%s\"", name );
|
||||
XP_ASSERT( !!name );
|
||||
char msg[128];
|
||||
snprintf( msg, sizeof(msg), "Move arrived for closed game \"%s\"; "
|
||||
"Shall I open it?", name );
|
||||
free( (void*)name);
|
||||
call_alert( buf );
|
||||
|
||||
OpenForMessageState* ofm = XP_MALLOC( globals->mpool, sizeof(*ofm) );
|
||||
ofm->globals = globals;
|
||||
ofm->gameID = gameID;
|
||||
ofm->from = *from;
|
||||
ofm->stream = stream_ref( stream );
|
||||
|
||||
call_confirm( globals, msg, onOpenForMsgConfirmed, ofm );
|
||||
} else {
|
||||
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(globals->mpool)
|
||||
globals->vtMgr );
|
||||
dvc_makeMQTTNoSuchGame( globals->dutil, NULL, stream, gameID );
|
||||
sendStreamToDev( stream, &from->u.mqtt.devID );
|
||||
|
||||
call_alert( "Dropping packet for non-existant game" );
|
||||
call_alert( "Dropping move for deleted game" );
|
||||
}
|
||||
}
|
||||
LOG_RETURN_VOID();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue