diff --git a/xwords4/linux/cursesmain.c b/xwords4/linux/cursesmain.c index f6bc613af..2fd110ddf 100644 --- a/xwords4/linux/cursesmain.c +++ b/xwords4/linux/cursesmain.c @@ -365,10 +365,16 @@ curses_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why, XP_U16 when, XWTimerProc proc, void* closure ) { CursesAppGlobals* globals = (CursesAppGlobals*)uc->closure; + XP_U32 nextTimer; - globals->cGlobals.timerProcs[why] = proc; - globals->cGlobals.timerClosures[why] = closure; - globals->nextTimer = util_getCurSeconds(uc) + when; + globals->cGlobals.timerInfo[why].proc = proc; + globals->cGlobals.timerInfo[why].closure = closure; + + nextTimer = util_getCurSeconds(uc) + when; + globals->cGlobals.timerInfo[why].when = nextTimer; + if ( globals->nextTimer > nextTimer ) { + globals->nextTimer = nextTimer; + } } /* curses_util_setTimer */ static void @@ -899,13 +905,24 @@ static int figureTimeout( CursesAppGlobals* globals ) { int result = INFINITE_TIMEOUT; - if ( globals->cGlobals.timerProcs[TIMER_COMMS] != 0 ) { - XP_U32 now = util_getCurSeconds( globals->cGlobals.params->util ); - XP_U32 then = globals->nextTimer; - if ( now >= then ) { - result = 0; - } else { - result = (then - now) * 1000; + XWTimerReason ii; + XP_U32 now = util_getCurSeconds( globals->cGlobals.params->util ); + + now *= 1000; + + for ( ii = 0; ii < NUM_TIMERS_PLUS_ONE; ++ii ) { + TimerInfo* tip = &globals->cGlobals.timerInfo[ii]; + if ( !!tip->proc ) { + XP_U32 then = tip->when * 1000; + if ( now >= then ) { + result = 0; + break; /* if one's immediate, we're done */ + } else { + then -= now; + if ( result == -1 || then < result ) { + result = then; + } + } } } return result; @@ -914,6 +931,31 @@ figureTimeout( CursesAppGlobals* globals ) # define figureTimeout(g) INFINITE_TIMEOUT #endif +static void +fireCursesTimer( CursesAppGlobals* globals ) +{ + XWTimerReason ii; + TimerInfo* smallestTip = NULL; + + for ( ii = 0; ii < NUM_TIMERS_PLUS_ONE; ++ii ) { + TimerInfo* tip = &globals->cGlobals.timerInfo[ii]; + if ( !!tip->proc ) { + if ( !smallestTip ) { + smallestTip = tip; + } else if ( tip->when < smallestTip->when ) { + smallestTip = tip; + } + } + } + + if ( !!smallestTip ) { + XP_ASSERT( util_getCurSeconds( globals->cGlobals.params->util ) + >= smallestTip->when ); + linuxFireTimer( &globals->cGlobals, + smallestTip - globals->cGlobals.timerInfo ); + } +} + /* * Ok, so this doesn't block yet.... */ @@ -930,7 +972,7 @@ blocking_gotEvent( CursesAppGlobals* globals, int* ch ) if ( timeout != INFINITE_TIMEOUT && numEvents == 0 ) { #ifdef XWFEATURE_RELAY - linuxFireTimer( &globals->cGlobals, TIMER_COMMS ); + fireCursesTimer( globals ); #endif } else if ( numEvents > 0 ) { @@ -1360,6 +1402,10 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) g_globals.cp.showBoardArrow = XP_TRUE; g_globals.cp.showRobotScores = params->showRobotScores; g_globals.cp.hideTileValues = params->hideValues; +#ifdef XWFEATURE_SLOW_ROBOT + g_globals.cp.robotThinkMin = params->robotThinkMin; + g_globals.cp.robotThinkMax = params->robotThinkMax; +#endif dict = params->dict; diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index d80dcbc4a..c1e5ab59c 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -1297,8 +1297,8 @@ gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why, XP_ASSERT( 0 ); } - globals->cGlobals.timerProcs[why] = proc; - globals->cGlobals.timerClosures[why] = closure; + globals->cGlobals.timerInfo[why].proc = proc; + globals->cGlobals.timerInfo[why].closure = closure; XP_ASSERT( newSrc != 0 ); globals->timerSources[why-1] = newSrc; } /* gtk_util_setTimer */ diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index 5c6ab90cc..c1e8df101 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -567,10 +567,11 @@ linux_util_makeStreamFromAddr( XW_UtilCtxt* uctx, XP_U16 channelNo ) void linuxFireTimer( CommonGlobals* cGlobals, XWTimerReason why ) { - XWTimerProc proc = cGlobals->timerProcs[why]; - void* closure = cGlobals->timerClosures[why]; + TimerInfo* tip = &cGlobals->timerInfo[why]; + XWTimerProc proc = tip->proc; + void* closure = tip->closure; - cGlobals->timerProcs[why] = NULL; + tip->proc = NULL; (*proc)( closure, why ); } /* fireTimer */ diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index 6d50b0440..26bb4b269 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -120,6 +120,12 @@ typedef void (*AddAcceptorFunc)(int listener, Acceptor func, typedef struct LinSMSData LinSMSData; #endif +typedef struct _TimerInfo { + XWTimerProc proc; + void* closure; + XP_U32 when; /* used only for ncurses */ +} TimerInfo; + struct CommonGlobals { LaunchParams* params; @@ -150,8 +156,7 @@ struct CommonGlobals { LinSMSData* smsData; #endif - XWTimerProc timerProcs[NUM_TIMERS_PLUS_ONE]; - void* timerClosures[NUM_TIMERS_PLUS_ONE]; + TimerInfo timerInfo[NUM_TIMERS_PLUS_ONE]; }; #endif