fix to send after connect

This commit is contained in:
Eric House 2021-02-15 14:59:44 -08:00
parent d53ab92af3
commit 74109ce172
4 changed files with 113 additions and 36 deletions

View file

@ -208,6 +208,7 @@ nli_makeFromStream( NetLaunchInfo* nli, XWStreamCtxt* stream )
void void
nli_makeAddrRec( const NetLaunchInfo* nli, CommsAddrRec* addr ) nli_makeAddrRec( const NetLaunchInfo* nli, CommsAddrRec* addr )
{ {
XP_MEMSET( addr, 0, sizeof(*addr) );
CommsConnType type; CommsConnType type;
for ( XP_U32 state = 0; types_iter( nli->_conTypes, &type, &state ); ) { for ( XP_U32 state = 0; types_iter( nli->_conTypes, &type, &state ); ) {
addr_addType( addr, type ); addr_addType( addr, type );

View file

@ -72,7 +72,7 @@ main.html: ${INPUTS} $(MAKEFILE) shell_minimal.html
--preload-file assets_dir --shell-file shell_minimal.html \ --preload-file assets_dir --shell-file shell_minimal.html \
-s USE_SDL_TTF=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' \ -s USE_SDL_TTF=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' \
-s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']" \ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']" \
-s EXPORTED_FUNCTIONS='["_main", "_button", "_newgame", "_gotMQTTMsg", "_jscallback", "_onDlgButton"]' \ -s EXPORTED_FUNCTIONS='["_main", "_button", "_newgame", "_gotMQTTMsg", "_jscallback", "_onDlgButton", "_MQTTConnectedChanged"]' \
-s WASM=1 \ -s WASM=1 \
${INPUTS} -o $@ ${INPUTS} -o $@

View file

@ -1,4 +1,4 @@
/* -*- compile-command: "cd ../wasm && make main.html -j3"; -*- */ /* -*- compile-command: "cd ../wasm && make MEMDEBUG=TRUE main.html -j3"; -*- */
/* /*
* Copyright 2021 by Eric House (xwords@eehouse.org). All rights reserved. * Copyright 2021 by Eric House (xwords@eehouse.org). All rights reserved.
* *
@ -105,6 +105,35 @@ EM_JS(void, setButtonText, (const char* id, const char* text), {
static void updateScreen( Globals* globals, bool doSave ); static void updateScreen( Globals* globals, bool doSave );
typedef void (*ConfirmProc)( void* closure, bool confirmed );
typedef struct _ConfirmState {
Globals* globals;
ConfirmProc proc;
void* closure;
} ConfirmState;
static void
onConfirmed( void* closure, const char* button )
{
bool confirmed = 0 == strcmp( button, BUTTON_OK );
ConfirmState* cs = (ConfirmState*)closure;
(*cs->proc)( cs->closure, confirmed );
XP_FREE( cs->globals->mpool, cs );
}
static void
call_confirm( Globals* globals, const char* msg,
ConfirmProc proc, void* closure )
{
const char* buttons[] = { BUTTON_CANCEL, BUTTON_OK, NULL };
ConfirmState* cs = XP_MALLOC( globals->mpool, sizeof(*cs) );
cs->globals = globals;
cs->proc = proc;
cs->closure = closure;
call_dialog( msg, buttons, onConfirmed, cs );
}
static void static void
call_alert( const char* msg ) call_alert( const char* msg )
{ {
@ -134,11 +163,9 @@ send_msg( XWEnv xwe, const XP_U8* buf, XP_U16 len,
XP_U16 streamLen = stream_getSize( stream ); XP_U16 streamLen = stream_getSize( stream );
XP_LOGFF( "calling call_mqttSend" );
if ( call_mqttSend( topic, stream_getPtr( stream ), streamLen ) ) { if ( call_mqttSend( topic, stream_getPtr( stream ), streamLen ) ) {
nSent = len; nSent = len;
} }
XP_LOGFF( "back from call_mqttSend" );
stream_destroy( stream, NULL ); stream_destroy( stream, NULL );
} }
@ -215,29 +242,18 @@ startGame( Globals* globals )
LOG_RETURN_VOID(); LOG_RETURN_VOID();
} }
static bool typedef struct _AskReplaceState {
gameFromInvite( Globals* globals, const NetLaunchInfo* invite ) Globals* globals;
{ NetLaunchInfo invite;
bool loaded = false; } AskReplaceState;
bool needsLoad = true;
XP_LOGFF( "model: %p", globals->game.model );
if ( NULL != globals->game.model ) {
XP_LOGFF( "have game: TRUE" );
/* there's a current game. Ignore the invitation if it has the same
gameID. Otherwise ask to replace */
if ( globals->gi.gameID == invite->gameID ) {
XP_LOGFF( "duplicate invite; ignoring" );
needsLoad = false;
} else {
call_alert( "Invitation received; replace current game?" );
// needsLoad = false;
}
} else if ( invite->lang != 1 ) {
call_alert( "Invitations are only supported for play in English right now." );
needsLoad = false;
}
if ( needsLoad ) { static void
onReplaceConfirmed( void* closure, bool confirmed )
{
AskReplaceState* ars = (AskReplaceState*)closure;
Globals* globals = ars->globals;
if ( confirmed ) {
if ( !!globals->util ) { if ( !!globals->util ) {
game_dispose( &globals->game, NULL ); game_dispose( &globals->game, NULL );
wasm_util_destroy( globals->util ); wasm_util_destroy( globals->util );
@ -250,15 +266,44 @@ gameFromInvite( Globals* globals, const NetLaunchInfo* invite )
globals->util = wasm_util_make( MPPARM(globals->mpool) &globals->gi, globals->util = wasm_util_make( MPPARM(globals->mpool) &globals->gi,
globals->dutil, globals ); globals->dutil, globals );
loaded = game_makeFromInvite( MPPARM(globals->mpool) NULL, invite, game_makeFromInvite( MPPARM(globals->mpool) NULL, &ars->invite,
&globals->game, &globals->gi, &globals->game, &globals->gi,
globals->dict, NULL, globals->dict, NULL,
globals->util, globals->draw, globals->util, globals->draw,
&globals->cp, &globals->procs ); &globals->cp, &globals->procs );
} else { startGame( globals );
loaded = true;
} }
XP_FREE( globals->mpool, ars );
}
static bool
gameFromInvite( Globals* globals, const NetLaunchInfo* invite )
{
bool needsLoad = true;
XP_LOGFF( "model: %p", globals->game.model );
if ( NULL != globals->game.model ) {
XP_LOGFF( "have game: TRUE" );
/* there's a current game. Ignore the invitation if it has the same
gameID. Otherwise ask to replace */
if ( globals->gi.gameID == invite->gameID ) {
XP_LOGFF( "duplicate invite; ignoring" );
needsLoad = false;
} else {
AskReplaceState* ars = XP_MALLOC( globals->mpool, sizeof(*ars) );
ars->globals = globals;
XP_MEMCPY( &ars->invite, invite, sizeof(ars->invite) );
call_confirm( globals, "Invitation received; replace current game?",
onReplaceConfirmed, ars );
needsLoad = false;
}
} else if ( invite->lang != 1 ) {
call_alert( "Invitations are only supported for play in English right now." );
needsLoad = false;
}
bool loaded = !needsLoad;
LOG_RETURNF( "%d", loaded ); LOG_RETURNF( "%d", loaded );
return loaded; return loaded;
} }
@ -353,9 +398,24 @@ 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 )
{ {
XP_Bool draw = game_receiveMessage( &globals->game, NULL, stream, from ); if ( gameID == globals->gi.gameID ) {
if ( draw ) { XP_Bool draw = game_receiveMessage( &globals->game, NULL, stream, from );
updateScreen( globals, true ); if ( draw ) {
updateScreen( globals, true );
}
} else {
XP_LOGFF( "dropping packet for wrong game" );
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(globals->mpool)
globals->vtMgr );
dvc_makeMQTTNoSuchGame( globals->dutil, NULL, stream, gameID );
XP_UCHAR topic[64];
formatMQTTTopic( &from->u.mqtt.devID, topic, sizeof(topic) );
XP_U16 streamLen = stream_getSize( stream );
call_mqttSend( topic, stream_getPtr( stream ), streamLen );
stream_destroy( stream, NULL );
} }
} }
@ -767,6 +827,16 @@ newgame( void* closure, bool p0, bool p1 )
call_dialog( query, buttons, onNewgameResponse, ngs ); call_dialog( query, buttons, onNewgameResponse, ngs );
} }
void
MQTTConnectedChanged( void* closure, bool connected )
{
XP_LOGFF( "connected=%d", connected);
Globals* globals = (Globals*)closure;
if ( connected && !!globals->game.comms ) {
comms_resendAll( globals->game.comms, NULL, COMMS_CONN_MQTT, XP_TRUE );
}
}
void void
gotMQTTMsg( void* closure, int len, const uint8_t* msg ) gotMQTTMsg( void* closure, int len, const uint8_t* msg )
{ {

View file

@ -30,12 +30,17 @@ function onHaveDevID(closure, devid) {
state.closure = closure; state.closure = closure;
document.getElementById("mqtt_span").textContent=devid; document.getElementById("mqtt_span").textContent=devid;
function tellConnected(isConn) {
Module.ccall('MQTTConnectedChanged', null, ['number', 'boolean'], [state.closure, isConn]);
}
state.client = new Paho.MQTT.Client("eehouse.org", 8883, '/wss', devid); state.client = new Paho.MQTT.Client("eehouse.org", 8883, '/wss', devid);
// set callback handlers // set callback handlers
state.client.onConnectionLost = function onConnectionLost(responseObject) { state.client.onConnectionLost = function onConnectionLost(responseObject) {
state.connected = false; state.connected = false;
document.getElementById("mqtt_status").textContent="Disconnected"; document.getElementById("mqtt_status").textContent="Disconnected";
tellConnected(false);
if (responseObject.errorCode !== 0) { if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage); console.log("onConnectionLost:"+responseObject.errorMessage);
} }
@ -50,6 +55,7 @@ function onHaveDevID(closure, devid) {
function onConnect() { function onConnect() {
state.connected = true state.connected = true
document.getElementById("mqtt_status").textContent="Connected"; document.getElementById("mqtt_status").textContent="Connected";
tellConnected(true);
var subscribeOptions = { var subscribeOptions = {
qos: 2, // QoS qos: 2, // QoS