open game to receive message

This commit is contained in:
Eric House 2021-02-20 09:04:57 -08:00
parent e2beccc85c
commit 41cd3d8f39
4 changed files with 118 additions and 40 deletions

View file

@ -38,6 +38,12 @@ extern "C" {
#define STREAM_INCR_SIZE 100 #define STREAM_INCR_SIZE 100
#ifdef XWFEATURE_STREAMREF
# define REFCOUNT refCount
#else
# define REFCOUNT _unused_refCount
#endif
#define SOCKET_STREAM_SUPER_COMMON_SLOTS \ #define SOCKET_STREAM_SUPER_COMMON_SLOTS \
StreamCtxVTable* vtable; \ StreamCtxVTable* vtable; \
void* closure; \ void* closure; \
@ -51,6 +57,7 @@ extern "C" {
XP_U16 version; \ XP_U16 version; \
XP_U8 nReadBits; \ XP_U8 nReadBits; \
XP_U8 nWriteBits; \ XP_U8 nWriteBits; \
XP_U8 REFCOUNT; \
XP_Bool isOpen; \ XP_Bool isOpen; \
MPSLOT MPSLOT
@ -93,7 +100,9 @@ mem_stream_make( MPFORMAL VTableMgr* vtmgr, void* closure,
result->onClose = onClose; result->onClose = onClose;
result->isOpen = XP_TRUE; result->isOpen = XP_TRUE;
#ifdef XWFEATURE_STREAMREF
result->refCount = 1;
#endif
return (XWStreamCtxt*)result; return (XWStreamCtxt*)result;
} /* make_mem_stream */ } /* make_mem_stream */
@ -492,18 +501,34 @@ mem_stream_setPos( XWStreamCtxt* p_sctx, PosWhich which, XWStreamPos newpos )
return oldPos; return oldPos;
} /* mem_stream_setPos */ } /* 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 static void
mem_stream_destroy( XWStreamCtxt* p_sctx, XWEnv xwe ) mem_stream_destroy( XWStreamCtxt* p_sctx, XWEnv xwe )
{ {
MemStreamCtxt* stream = (MemStreamCtxt*)p_sctx; 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 ) { XP_FREEP( stream->mpool, &stream->buf );
stream_close( p_sctx, xwe );
XP_FREE( stream->mpool, stream );
} }
XP_FREEP( stream->mpool, &stream->buf );
XP_FREE( stream->mpool, stream );
} /* mem_stream_destroy */ } /* mem_stream_destroy */
static StreamCtxVTable* static StreamCtxVTable*
@ -535,7 +560,9 @@ make_vtable( MemStreamCtxt* stream )
SET_VTABLE_ENTRY( vtable, stream_setPos, mem ); SET_VTABLE_ENTRY( vtable, stream_setPos, mem );
SET_VTABLE_ENTRY( vtable, stream_getPos, 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_destroy, mem );
SET_VTABLE_ENTRY( vtable, stream_open, mem ); SET_VTABLE_ENTRY( vtable, stream_open, mem );
SET_VTABLE_ENTRY( vtable, stream_close, mem ); SET_VTABLE_ENTRY( vtable, stream_close, mem );

View file

@ -55,6 +55,9 @@ typedef XP_U8 PosWhich;
typedef struct StreamCtxVTable { typedef struct StreamCtxVTable {
#ifdef XWFEATURE_STREAMREF
XWStreamCtxt* (*m_stream_ref)( XWStreamCtxt* dctx );
#endif
void (*m_stream_destroy)( XWStreamCtxt* dctx, XWEnv xwe ); void (*m_stream_destroy)( XWStreamCtxt* dctx, XWEnv xwe );
XP_U8 (*m_stream_getU8)( DBG_PROC_FORMAL XWStreamCtxt* dctx ); XP_U8 (*m_stream_getU8)( DBG_PROC_FORMAL XWStreamCtxt* dctx );
@ -110,6 +113,10 @@ struct XWStreamCtxt {
StreamCtxVTable* vtable; StreamCtxVTable* vtable;
}; };
#ifdef XWFEATURE_STREAMREF
# define stream_ref(sc) \
(sc)->vtable->m_stream_ref((sc))
#endif
#define stream_destroy(sc,e) \ #define stream_destroy(sc,e) \
(sc)->vtable->m_stream_destroy(sc,(e)) (sc)->vtable->m_stream_destroy(sc,(e))

View file

@ -42,6 +42,7 @@ DEFINES += -DXWFEATURE_DICTSANITY
DEFINES += -DPOINTER_SUPPORT DEFINES += -DPOINTER_SUPPORT
DEFINES += -DPLATFORM_WASM DEFINES += -DPLATFORM_WASM
DEFINES += -DXWFEATURE_CROSSHAIRS DEFINES += -DXWFEATURE_CROSSHAIRS
DEFINES += -DXWFEATURE_STREAMREF
DEFINES += -DNATIVE_NLI DEFINES += -DNATIVE_NLI
DEFINES += -DDEBUG_REF DEFINES += -DDEBUG_REF
DEFINES += -Wno-switch DEFINES += -Wno-switch

View file

@ -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 static void
onReplaceConfirmed( void* closure, bool confirmed ) onReplaceConfirmed( void* closure, bool confirmed )
{ {
@ -610,29 +638,7 @@ onReplaceConfirmed( void* closure, bool confirmed )
Globals* globals = ars->globals; Globals* globals = ars->globals;
if ( confirmed ) { if ( confirmed ) {
cleanupGame( globals ); doReplace( globals, &ars->invite );
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 );
}
} }
XP_FREE( globals->mpool, ars ); XP_FREE( globals->mpool, ars );
@ -652,7 +658,7 @@ gameFromInvite( Globals* globals, const NetLaunchInfo* invite )
} else { } else {
AskReplaceState* ars = XP_MALLOC( globals->mpool, sizeof(*ars) ); AskReplaceState* ars = XP_MALLOC( globals->mpool, sizeof(*ars) );
ars->globals = globals; ars->globals = globals;
XP_MEMCPY( &ars->invite, invite, sizeof(ars->invite) ); ars->invite = *invite;
call_confirm( globals, "Invitation received; replace current game?", call_confirm( globals, "Invitation received; replace current game?",
onReplaceConfirmed, ars ); onReplaceConfirmed, ars );
needsLoad = false; needsLoad = false;
@ -660,6 +666,9 @@ gameFromInvite( Globals* globals, const NetLaunchInfo* invite )
} else if ( invite->lang != 1 ) { } else if ( invite->lang != 1 ) {
call_alert( "Invitations are only supported for play in English right now." ); call_alert( "Invitations are only supported for play in English right now." );
needsLoad = false; needsLoad = false;
} else {
// No game open. Just do it
doReplace( globals, invite );
} }
bool loaded = !needsLoad; 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 void
main_onGameMessage( Globals* globals, XP_U32 gameID, main_onGameMessage( Globals* globals, XP_U32 gameID,
const CommsAddrRec* from, XWStreamCtxt* stream ) const CommsAddrRec* from, XWStreamCtxt* stream )
{ {
if ( gameID == globals->gs.gi.gameID ) { if ( gameID == globals->gs.gi.gameID ) { /* current game open */
XP_Bool draw = game_receiveMessage( &globals->gs.game, NULL, stream, from ); if ( game_receiveMessage( &globals->gs.game, NULL, stream, from ) ) {
if ( draw ) {
updateScreen( globals, true ); updateScreen( globals, true );
} }
} else { } else {
@ -822,20 +857,28 @@ main_onGameMessage( Globals* globals, XP_U32 gameID,
if ( have_stored_value( key ) ) { if ( have_stored_value( key ) ) {
formatNameKey( key, sizeof(key), gameID ); formatNameKey( key, sizeof(key), gameID );
const char* name = get_stored_value( key ); const char* name = get_stored_value( key );
char buf[128]; XP_ASSERT( !!name );
snprintf( buf, sizeof(buf), "Dropping packet for closed game \"%s\"", name ); char msg[128];
snprintf( msg, sizeof(msg), "Move arrived for closed game \"%s\"; "
"Shall I open it?", name );
free( (void*)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 { } else {
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(globals->mpool) XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(globals->mpool)
globals->vtMgr ); globals->vtMgr );
dvc_makeMQTTNoSuchGame( globals->dutil, NULL, stream, gameID ); dvc_makeMQTTNoSuchGame( globals->dutil, NULL, stream, gameID );
sendStreamToDev( stream, &from->u.mqtt.devID ); 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 void