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
|
#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 );
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue