On receipt of connection-denied message via new rerror callback, put

up new error messages and then conns dialog so user can connect again
after changing room name or just waiting.  A new game is started so
that comms is re-inited and will try again to connect to relay.
This commit is contained in:
ehouse 2009-12-04 08:18:49 +00:00
parent 14b060707f
commit c893fd4a9e
7 changed files with 105 additions and 11 deletions

View file

@ -1400,6 +1400,18 @@ positionSizeStuff( CursesAppGlobals* globals, int width, int height )
board_invalAll( board ); board_invalAll( board );
} /* positionSizeStuff */ } /* positionSizeStuff */
static void
relay_status_curses( void* XP_UNUSED(closure), CommsRelayState state )
{
XP_LOGF( "%s got status: %s", __func__, CommsRelayState2Str(state) );
}
static void
relay_error_curses( void* XP_UNUSED(closure), XWREASON XP_UNUSED(relayErr) )
{
LOG_FUNC();
}
void void
cursesmain( XP_Bool isServer, LaunchParams* params ) cursesmain( XP_Bool isServer, LaunchParams* params )
{ {
@ -1463,6 +1475,10 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
.send = LINUX_SEND, .send = LINUX_SEND,
#ifdef COMMS_HEARTBEAT #ifdef COMMS_HEARTBEAT
.reset = linux_reset, .reset = linux_reset,
#endif
#ifdef XWFEATURE_RELAY
.rstatus = relay_status_curses,
.rerror = relay_error_curses,
#endif #endif
}; };

View file

@ -26,6 +26,7 @@
typedef struct _GtkConnsState { typedef struct _GtkConnsState {
GtkAppGlobals* globals; GtkAppGlobals* globals;
CommsAddrRec* addr; CommsAddrRec* addr;
DeviceRole role;
GtkWidget* invite; GtkWidget* invite;
GtkWidget* hostName; GtkWidget* hostName;
@ -125,6 +126,18 @@ static GtkWidget*
makeRelayPage( GtkConnsState* state ) makeRelayPage( GtkConnsState* state )
{ {
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 ); GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
const gchar* hint = NULL;
if ( SERVER_ISSERVER == state->role ) {
hint = "As host, you pick the room name for the game, and must "
"connect first";
} else {
XP_ASSERT( SERVER_ISCLIENT == state->role );
hint = "As guest, you get the room name from the host. Be sure to "
"let the host connect first to validate the name.";
}
gtk_box_pack_start( GTK_BOX(vbox), gtk_label_new( hint ), FALSE, TRUE, 0 );
GtkWidget* hbox = makeLabeledField( "Room", &state->invite ); GtkWidget* hbox = makeLabeledField( "Room", &state->invite );
gtk_entry_set_text( GTK_ENTRY(state->invite), gtk_entry_set_text( GTK_ENTRY(state->invite),
@ -166,7 +179,8 @@ makeBTPage( GtkConnsState* state )
} /* makeBTPage */ } /* makeBTPage */
gboolean gboolean
gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool readOnly ) gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, DeviceRole role,
XP_Bool readOnly )
{ {
GtkConnsState state; GtkConnsState state;
XP_MEMSET( &state, 0, sizeof(state) ); XP_MEMSET( &state, 0, sizeof(state) );
@ -176,6 +190,7 @@ gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool readOnly )
state.readOnly = readOnly; state.readOnly = readOnly;
state.globals = globals; state.globals = globals;
state.addr = addr; state.addr = addr;
state.role = role;
GtkWidget* dialog; GtkWidget* dialog;
GtkWidget* vbox; GtkWidget* vbox;

View file

@ -27,7 +27,7 @@
#include "gtkmain.h" #include "gtkmain.h"
gboolean gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, gboolean gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr,
XP_Bool readOnly ); DeviceRole role, XP_Bool readOnly );
#endif /* _GTKCONNSDLG_H_ */ #endif /* _GTKCONNSDLG_H_ */
#endif /* PLATFORM_GTK */ #endif /* PLATFORM_GTK */

View file

@ -67,6 +67,8 @@ static void sendOnClose( XWStreamCtxt* stream, void* closure );
static void setCtrlsForTray( GtkAppGlobals* globals ); static void setCtrlsForTray( GtkAppGlobals* globals );
static void printFinalScores( GtkAppGlobals* globals ); static void printFinalScores( GtkAppGlobals* globals );
static void new_game( GtkWidget* widget, GtkAppGlobals* globals ); static void new_game( GtkWidget* widget, GtkAppGlobals* globals );
static void new_game_impl( GtkAppGlobals* globals, XP_Bool fireConnDlg );
#define GTK_TRAY_HT_ROWS 3 #define GTK_TRAY_HT_ROWS 3
@ -301,6 +303,34 @@ relay_status_gtk( void* closure, CommsRelayState state )
draw_gtk_status( globals->draw, globals->stateChar ); draw_gtk_status( globals->draw, globals->stateChar );
} }
static gint
invoke_new_game( gpointer data )
{
GtkAppGlobals* globals = (GtkAppGlobals*)data;
new_game_impl( globals, XP_TRUE );
return 0;
}
static void
relay_error_gtk( void* closure, XWREASON relayErr )
{
LOG_FUNC();
GtkAppGlobals* globals = (GtkAppGlobals*)closure;
gint (*proc)( gpointer data );
switch( relayErr ) {
case XWRELAY_ERROR_NO_ROOM:
case XWRELAY_ERROR_DUP_ROOM:
proc = invoke_new_game;
break;
default:
assert(0);
break;
}
(void)g_idle_add( proc, globals );
}
static void static void
createOrLoadObjects( GtkAppGlobals* globals ) createOrLoadObjects( GtkAppGlobals* globals )
{ {
@ -324,6 +354,7 @@ createOrLoadObjects( GtkAppGlobals* globals )
#endif #endif
#ifdef XWFEATURE_RELAY #ifdef XWFEATURE_RELAY
.rstatus = relay_status_gtk, .rstatus = relay_status_gtk,
.rerror = relay_error_gtk,
#endif #endif
}; };
@ -407,7 +438,7 @@ createOrLoadObjects( GtkAppGlobals* globals )
#endif #endif
if ( params->needsNewGame ) { if ( params->needsNewGame ) {
new_game( NULL, globals ); new_game_impl( globals, XP_FALSE );
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
} else if ( !isServer ) { } else if ( !isServer ) {
XWStreamCtxt* stream = XWStreamCtxt* stream =
@ -663,7 +694,7 @@ final_scores( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
} /* final_scores */ } /* final_scores */
static void static void
new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals ) new_game_impl( GtkAppGlobals* globals, XP_Bool fireConnDlg )
{ {
CommsAddrRec addr; CommsAddrRec addr;
@ -673,7 +704,7 @@ new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
comms_getInitialAddr( &addr ); comms_getInitialAddr( &addr );
} }
if ( newGameDialog( globals, &addr, XP_TRUE ) ) { if ( newGameDialog( globals, &addr, XP_TRUE, fireConnDlg ) ) {
CurGameInfo* gi = &globals->cGlobals.params->gi; CurGameInfo* gi = &globals->cGlobals.params->gi;
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT; XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT;
@ -713,6 +744,12 @@ new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
board_draw( globals->cGlobals.game.board ); board_draw( globals->cGlobals.game.board );
} }
} /* new_game_impl */
static void
new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
{
new_game_impl( globals, XP_FALSE );
} /* new_game */ } /* new_game */
static void static void
@ -723,7 +760,7 @@ game_info( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
/* Anything to do if OK is clicked? Changed names etc. already saved. Try /* Anything to do if OK is clicked? Changed names etc. already saved. Try
server_do in case one's become a robot. */ server_do in case one's become a robot. */
if ( newGameDialog( globals, &addr, XP_FALSE ) ) { if ( newGameDialog( globals, &addr, XP_FALSE, XP_FALSE ) ) {
if ( server_do( globals->cGlobals.game.server ) ) { if ( server_do( globals->cGlobals.game.server ) ) {
board_draw( globals->cGlobals.game.board ); board_draw( globals->cGlobals.game.board );
} }
@ -1263,7 +1300,7 @@ pentimer_idle_func( gpointer data )
} }
return callAgain; return callAgain;
} /* timer_idle_func */ } /* pentimer_idle_func */
static gint static gint
score_timer_func( gpointer data ) score_timer_func( gpointer data )

View file

@ -40,6 +40,7 @@ typedef struct GtkNewGameState {
gboolean revert; gboolean revert;
gboolean cancelled; gboolean cancelled;
XP_Bool loaded; XP_Bool loaded;
XP_Bool fireConnDlg;
gboolean isNewGame; gboolean isNewGame;
short nCols; /* for board size */ short nCols; /* for board size */
@ -89,7 +90,8 @@ role_combo_changed( GtkComboBox* combo, gpointer gp )
#ifndef XWFEATURE_STANDALONE_ONLY #ifndef XWFEATURE_STANDALONE_ONLY
if ( state->loaded && SERVER_STANDALONE != role ) { if ( state->loaded && SERVER_STANDALONE != role ) {
gtkConnsDlg( state->globals, &state->addr, !state->isNewGame ); gtkConnsDlg( state->globals, &state->addr, role,
!state->isNewGame );
} }
#endif #endif
} }
@ -98,7 +100,7 @@ role_combo_changed( GtkComboBox* combo, gpointer gp )
static void static void
handle_settings( GtkWidget* XP_UNUSED(item), GtkNewGameState* state ) handle_settings( GtkWidget* XP_UNUSED(item), GtkNewGameState* state )
{ {
gtkConnsDlg( state->globals, &state->addr, !state->isNewGame ); gtkConnsDlg( state->globals, &state->addr, state->role, !state->isNewGame );
} }
#endif #endif
@ -177,6 +179,15 @@ handle_revert( GtkWidget* XP_UNUSED(widget), void* closure )
gtk_main_quit(); gtk_main_quit();
} /* handle_revert */ } /* handle_revert */
static gint
call_connsdlg_func( gpointer data )
{
GtkNewGameState* state = (GtkNewGameState*)data;
gtkConnsDlg( state->globals, &state->addr, state->role,
!state->isNewGame );
return 0;
}
static GtkWidget* static GtkWidget*
makeNewGameDialog( GtkNewGameState* state ) makeNewGameDialog( GtkNewGameState* state )
{ {
@ -359,6 +370,10 @@ makeNewGameDialog( GtkNewGameState* state )
gtk_widget_show_all (dialog); gtk_widget_show_all (dialog);
if ( state->fireConnDlg ) {
(void)g_idle_add( call_connsdlg_func, state );
}
return dialog; return dialog;
} /* makeNewGameDialog */ } /* makeNewGameDialog */
@ -502,7 +517,8 @@ gtk_newgame_attr_set( void* closure, NewGameAttr attr, NGValue value )
} }
gboolean gboolean
newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame ) newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame,
XP_Bool fireConnDlg )
{ {
GtkNewGameState state; GtkNewGameState state;
XP_MEMSET( &state, 0, sizeof(state) ); XP_MEMSET( &state, 0, sizeof(state) );
@ -519,6 +535,7 @@ newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame )
gtk_newgame_attr_set, gtk_newgame_attr_set,
&state ); &state );
state.isNewGame = isNewGame; state.isNewGame = isNewGame;
state.fireConnDlg = fireConnDlg;
/* returns when button handler calls gtk_main_quit */ /* returns when button handler calls gtk_main_quit */
do { do {
@ -549,6 +566,7 @@ newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool isNewGame )
} }
gtk_widget_destroy( dialog ); gtk_widget_destroy( dialog );
state.fireConnDlg = XP_FALSE;
} while ( state.revert ); } while ( state.revert );
newg_destroy( state.newGameCtxt ); newg_destroy( state.newGameCtxt );

View file

@ -27,7 +27,7 @@
#include "gtkmain.h" #include "gtkmain.h"
gboolean newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr, gboolean newGameDialog( GtkAppGlobals* globals, CommsAddrRec* addr,
XP_Bool isNewGame ); XP_Bool isNewGame, XP_Bool fireConnDlg );
#endif /* _GTKNEWGAME_H_ */ #endif /* _GTKNEWGAME_H_ */
#endif /* PLATFORM_GTK */ #endif /* PLATFORM_GTK */

View file

@ -297,6 +297,14 @@ linux_getErrString( UtilErrID id, XP_Bool* silent )
message = "XWRELAY_ERROR_OTHER_DISCON"; message = "XWRELAY_ERROR_OTHER_DISCON";
break; break;
case ERR_RELAY_BASE + XWRELAY_ERROR_NO_ROOM:
message = "No such room. Has the host connected yet to reserve it?";
break;
case ERR_RELAY_BASE + XWRELAY_ERROR_DUP_ROOM:
message = "That room is reserved by another host. Rename your room, "
"become a guest, or try again in a few minutes.";
break;
default: default:
XP_LOGF( "no code for error: %d", id ); XP_LOGF( "no code for error: %d", id );
message = "<unrecognized error code reported>"; message = "<unrecognized error code reported>";