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 );
} /* 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
cursesmain( XP_Bool isServer, LaunchParams* params )
{
@ -1463,6 +1475,10 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
.send = LINUX_SEND,
#ifdef COMMS_HEARTBEAT
.reset = linux_reset,
#endif
#ifdef XWFEATURE_RELAY
.rstatus = relay_status_curses,
.rerror = relay_error_curses,
#endif
};

View file

@ -26,6 +26,7 @@
typedef struct _GtkConnsState {
GtkAppGlobals* globals;
CommsAddrRec* addr;
DeviceRole role;
GtkWidget* invite;
GtkWidget* hostName;
@ -125,6 +126,18 @@ static GtkWidget*
makeRelayPage( GtkConnsState* state )
{
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 );
gtk_entry_set_text( GTK_ENTRY(state->invite),
@ -166,7 +179,8 @@ makeBTPage( GtkConnsState* state )
} /* makeBTPage */
gboolean
gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool readOnly )
gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, DeviceRole role,
XP_Bool readOnly )
{
GtkConnsState state;
XP_MEMSET( &state, 0, sizeof(state) );
@ -176,6 +190,7 @@ gtkConnsDlg( GtkAppGlobals* globals, CommsAddrRec* addr, XP_Bool readOnly )
state.readOnly = readOnly;
state.globals = globals;
state.addr = addr;
state.role = role;
GtkWidget* dialog;
GtkWidget* vbox;

View file

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

View file

@ -67,6 +67,8 @@ static void sendOnClose( XWStreamCtxt* stream, void* closure );
static void setCtrlsForTray( GtkAppGlobals* globals );
static void printFinalScores( 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
@ -301,6 +303,34 @@ relay_status_gtk( void* closure, CommsRelayState state )
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
createOrLoadObjects( GtkAppGlobals* globals )
{
@ -324,6 +354,7 @@ createOrLoadObjects( GtkAppGlobals* globals )
#endif
#ifdef XWFEATURE_RELAY
.rstatus = relay_status_gtk,
.rerror = relay_error_gtk,
#endif
};
@ -407,7 +438,7 @@ createOrLoadObjects( GtkAppGlobals* globals )
#endif
if ( params->needsNewGame ) {
new_game( NULL, globals );
new_game_impl( globals, XP_FALSE );
#ifndef XWFEATURE_STANDALONE_ONLY
} else if ( !isServer ) {
XWStreamCtxt* stream =
@ -663,7 +694,7 @@ final_scores( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
} /* final_scores */
static void
new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
new_game_impl( GtkAppGlobals* globals, XP_Bool fireConnDlg )
{
CommsAddrRec addr;
@ -673,7 +704,7 @@ new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
comms_getInitialAddr( &addr );
}
if ( newGameDialog( globals, &addr, XP_TRUE ) ) {
if ( newGameDialog( globals, &addr, XP_TRUE, fireConnDlg ) ) {
CurGameInfo* gi = &globals->cGlobals.params->gi;
#ifndef XWFEATURE_STANDALONE_ONLY
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 );
}
} /* new_game_impl */
static void
new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
{
new_game_impl( globals, XP_FALSE );
} /* new_game */
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
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 ) ) {
board_draw( globals->cGlobals.game.board );
}
@ -1263,7 +1300,7 @@ pentimer_idle_func( gpointer data )
}
return callAgain;
} /* timer_idle_func */
} /* pentimer_idle_func */
static gint
score_timer_func( gpointer data )

View file

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

View file

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

View file

@ -297,6 +297,14 @@ linux_getErrString( UtilErrID id, XP_Bool* silent )
message = "XWRELAY_ERROR_OTHER_DISCON";
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:
XP_LOGF( "no code for error: %d", id );
message = "<unrecognized error code reported>";