Process all innocent commands immediately (fixes pause/resume)
authorH.G.Muller <hgm@hgm-xboard.(none)>
Thu, 1 Dec 2016 13:41:05 +0000 (14:41 +0100)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Thu, 1 Dec 2016 13:41:05 +0000 (14:41 +0100)
To prevent that commands received during thinking will halt command
processing,eclipsing later instant commands, all commands that merely
alter a settings value in adapter or engine are now immediately executed.
UCI engines should be able to handle 'setoption' commands even during
thinking, so explicit or implicit (easy/hard) settings changes are
immediately relayed to the engine as well.
 The 'pause' and 'resume' commands are now also treated immediately;
waiting with that until the engine is done thinking subverted the
intention of the 'pause' command.
 Commands that would never be sent when an engine is thinking are still
left with the commands that require thinking to complete, as for those
thisdoes not matter.

UCI2WB.c

index adfb3d6..5ebe5ef 100644 (file)
--- a/UCI2WB.c
+++ b/UCI2WB.c
@@ -405,7 +405,7 @@ GUI2Engine()
     char line[256], command[256], *p, *q, *r, mySide, searching = 0;\r
 \r
     while(1) {\r
-       int i, x, think=0;\r
+       int i, x, difficult, think=0;\r
 \r
        if((computer == stm || computer == ANALYZE && !searching) && !suspended) {\r
            DPRINT("# start search\n");\r
@@ -422,11 +422,44 @@ GUI2Engine()
            } else pause = think = 2, StartSearch(""); // request suspending of input processing while thinking\r
        }\r
       nomove:\r
+       for(difficult=0; !difficult; ) { // read and handle commands that can (or must) be handled during thinking\r
        fflush(toE); fflush(stdout);\r
        i = 0; while((x = getchar()) != EOF && (line[i] = x) != '\n') i++;\r
        line[++i] = 0; if(x == EOF) { printf("# EOF\n"); sprintf(line, "quit -1\n"); }\r
        sscanf(line, "%s", command);\r
-       if(!strcmp(command, "offer")) { drawOffer = 1; goto nomove; } // backlogged anyway, so this can be done instantly\r
+       if(!strcmp(command, "offer")) drawOffer = 1; // backlogged anyway, so this can be done instantly\r
+       else if(!strcmp(command, "post"))  post = 1;\r
+       else if(!strcmp(command, "nopost"))post = 0;\r
+       else if(!strcmp(command, "option")) {\r
+           char name[80], *p;\r
+           if(searching) StopPonder(1), searching = 0; // force new search if settings change during analysis (multi-PV!)\r
+           if(sscanf(line+7, "UCI2WB debug output=%d", &debug) == 1) ; else\r
+           if(sscanf(line+7, "Floating Byoyomi=%d", &flob) == 1) ; else\r
+           if(sscanf(line+7, "Byoyomi=%d", &byo) == 1) ; else\r
+           if(p = strchr(line, '=')) {\r
+               *p++ = 0;\r
+               if(strstr(checkOptions, line+7)) sprintf(p, "%s\n", atoi(p) ? "true" : "false");\r
+               EPRINT((f, "# setoption %s%s %s%s", nameWord, line+7, valueWord, p))\r
+           } else EPRINT((f, "# setoption %s%s\n", nameWord, line+7))\r
+       }\r
+       else if(!strcmp(command, "pause")) {\r
+           if(computer == stm) myTime -= GetTickCount() - startTime;\r
+           suspended = 1 + pondering; // remember if we were pondering, and stop search ignoring bestmove\r
+           StopPonder(pondering || computer == stm);\r
+       }\r
+       else if(!strcmp(command, "easy")) {\r
+           if(*canPonder) { ponder = 0; StopPonder(pondering); EPRINT((f, "# setoption %s%s %sfalse\n", nameWord, canPonder, valueWord)) }\r
+       }\r
+       else if(!strcmp(command, "hard")) {\r
+           if(*canPonder) { ponder = 1; EPRINT((f, "# setoption %s%s %strue\n", nameWord, canPonder, valueWord)) StartPonder(); }\r
+       }\r
+       else difficult = 1; // difficult command; terminate loop for easy ones\r
+       } // next command\r
+\r
+       if(!strcmp(command, "resume")) {\r
+           if(suspended == 2) StartPonder(); // restart interrupted ponder search\r
+           suspended = think = 0; continue;  // causes thinking to start in normal way if on move or analyzing\r
+       }\r
        if(think) {      // command arrived during thinking; order abort for 'instant commands'\r
            if(!strcmp(command, "?") || !strcmp(command, "quit") ||\r
               !strcmp(command, "force") || !strcmp(command, "result")) { EPRINT((f, "# stop\n")); fflush(toE); }\r
@@ -468,18 +501,6 @@ GUI2Engine()
            sscanf(line, "level %d %d %d", &mps, &tc, &inc);\r
            tc = (60*tc + sec)*1000; inc *= 1000; sTime = 0; tc /= unit; inc /= unit;\r
        }\r
-       else if(!strcmp(command, "option")) {\r
-           char name[80], *p;\r
-           if(searching) StopPonder(1), searching = 0; // force new search if settings change during analysis (multi-PV!)\r
-           if(sscanf(line+7, "UCI2WB debug output=%d", &debug) == 1) ; else\r
-           if(sscanf(line+7, "Floating Byoyomi=%d", &flob) == 1) ; else\r
-           if(sscanf(line+7, "Byoyomi=%d", &byo) == 1) ; else\r
-           if(p = strchr(line, '=')) {\r
-               *p++ = 0;\r
-               if(strstr(checkOptions, line+7)) sprintf(p, "%s\n", atoi(p) ? "true" : "false");\r
-               EPRINT((f, "# setoption %s%s %s%s", nameWord, line+7, valueWord, p))\r
-           } else EPRINT((f, "# setoption %s%s\n", nameWord, line+7))\r
-       }\r
        else if(!strcmp(command, "protover")) {\r
            if(!variants) variants = sc=='s' ? "shogi,5x5+5_shogi" : VARIANTS;\r
            printf("feature variants=\"%s\" setboard=1 usermove=1 debug=1 ping=1 name=1 reuse=0 exclude=1 pause=1 sigint=0 sigterm=0 done=0\n", variants);\r
@@ -525,15 +546,6 @@ GUI2Engine()
            if(!(sm & 2)) goto nomove; // no moves enabled; continue current search\r
            if(computer == ANALYZE) StopPonder(1), searching = 0; // abort old analysis\r
        }\r
-       else if(!strcmp(command, "pause")) {\r
-           if(computer == stm) myTime -= GetTickCount() - startTime;\r
-           suspended = 1 + pondering; // remember if we were pondering, and stop search ignoring bestmove\r
-           StopPonder(pondering || computer == stm);\r
-       }\r
-       else if(!strcmp(command, "resume")) {\r
-           if(suspended == 2) StartPonder(); // restart interrupted ponder search\r
-           suspended = 0; // causes thinking to start in normal way if on move or analyzing\r
-       }\r
        else if(!strcmp(command, "xboard")) ;\r
        else if(!strcmp(command, "analyze"))computer = ANALYZE, collect = 1, sm = 0, Analyze("true");\r
        else if(!strcmp(command, "exit"))   computer = NONE, StopPonder(1), searching = 0, Analyze("false");\r
@@ -541,10 +553,6 @@ GUI2Engine()
        else if(!strcmp(command, "go"))     computer = stm;\r
        else if(!strcmp(command, "time"))   sscanf(line+4, "%d", &myTime),  myTime  = (10*myTime)/unit;\r
        else if(!strcmp(command, "otim"))   sscanf(line+4, "%d", &hisTime), hisTime = (10*hisTime)/unit;\r
-       else if(!strcmp(command, "post"))   post = 1;\r
-       else if(!strcmp(command, "nopost")) post = 0;\r
-       else if(!strcmp(command, "easy") && !!*canPonder) { ponder = 0; StopPonder(pondering); EPRINT((f, "# setoption %s%s %sfalse\n", nameWord, canPonder, valueWord)) }\r
-       else if(!strcmp(command, "hard") && !!*canPonder) { ponder = 1; EPRINT((f, "# setoption %s%s %strue\n", nameWord, canPonder, valueWord)) StartPonder(); }\r
        else if(!strcmp(command, "ping"))   { /* static int done; if(!done) pause = 1, fprintf(toE, "isready\n"), fflush(toE), printf("# send isready\n"), fflush(stdout), Sync(PAUSE); done = 1;*/ printf("po%s", line+2); }\r
        else if(!strcmp(command, "memory")) sscanf(line, "memory %d", &memory);\r
        else if(!strcmp(command, "cores")&& !!*threadOpt) { sscanf(line, "cores %d", &cores); EPRINT((f, "# setoption %s%s %s%d\n", nameWord, threadOpt, valueWord, cores)) }\r