Let LaunchSearch() also start ponder search Ponder searches are normally started when HandleEngineOutput() receives the result of thinking, but this does not cover the case where a user switches on pondering while the engine is idle. LaunchMove() now takes care of this by starting a ponder search if one is needed but none is running. This is possible because the ponder move is always appended to the move list, even when ponder is off, and thus is available.
Fix periodic updates The move and move number were not available for the stat01 commands, because the code to collect the moves for the go-searchmoves command would prevent parsing of the entire info command. So this collection is now done last, and also made responsible for extracting the current move.
Exercise UCCI option 'newgame' also after 'isready' handshake The patch that moved the sending of 'ucinewgame' to after the initial 'isready' handshake overlooked that this was actually the else-clause of an if-statement that emitted 'option newgame' for UCCI. Now it is not really clear when the latter should be emitted, as it seems to be ignored even in Elephant Eye, but treating it as a variant of 'ucinewgame' seems best. Accidentally the statement behind it did not suffer from being in the else-clause, as it processed the UCI_Variant option, which does not exist in UCCI anyway.
Do not queue ignored commands Commands that will be ignored (such as 'xboard') are now recognized with the easy commands, as it makes little sense to send them to the engine thread just to be ignored. The 'accepted' and 'rejected' commands are now also recognized and treated this way. In addition, commands are now only echoed when they are queued, in debug mode: as the GUI thread can only block on reading from the GUI we can be sure that all commands are read as soon as they arrive, and echoing them just clutters the debug logs.
Debug recent changes Bugs with respect to flushing output to the GUI and resetting 'searching' after an engine move were fixed. Some new debug print statements were left in. Playing with and without pondering against another engine now seems to work. As does the move-now command, and switching off pondering while it is doing it. Analysis also works, even with move exclusion.
Change StopPonder() into more general StopSearch() As StopPonder was only still used to unconditionally abort searches of any kind, it is changed into a general StopSearch() routine that handles the tasks that otherwise were performed before calling it. In particular it refrains from stopping a search if none is going on, and conditionally (based on its argument) sets 'searching' to idle if the move the search will come up with has to be ignored.
Fix pause/resume Tne 'pause' and 'resume' commands are executed in the GUI thread for instant obedience. But they have to take care that a move produced by an aborted think is ignored (by setting searching = 0 before stopping it), and that the engine thread has to be signalled to restart it.
Abandon backlogging of options Now that there is a general command queue to backlog commands that arrive during thinking, there is no need to do this separately for engine options. Instead these are now treated with other 'difficult' commands by the engine thread, in DoComand(). The adapter options still count as easy commands.
Let engine thread parse difficult commands The design of the adapter is completely changed: the engine thread is made responsible for parsing and execution of all commands that cannot be processed during a search. To this end it alternates between reading from the engine (while the engine is searching, or should respond to a 'uci' or 'isready' query) and from the command queue (which is emptied before we dedicate to relaying ponder output). Searches are terminated by the GUI thread when a command arrives that would interrupt the search, so that the engine thread will start looking at the command queue again. Syncing threads to wait for an engine reply is replaced by just doing a (blocking) read for engine output in the same threat, and having the processing routine return once the answer has arrived (and is processed). Instead the Sync pipe is now used to block reading of the command queue when this is empty. This change breaks several of the less elementary commands. Fix command queue
Launch searches at end of GUI loop The loop for interpreting GUI commands is restructured by launching searches at the bottom of it rather than at the top. As it was an infinite loop anyway this only eliminates the first call to LaunchSearch(), which is OK as the engine would never have to search before any commands were received. As this change brought the 'nomove' label to the top of the loop, the 'goto's to it could be replaced by 'continue's, and the label deleted. That for engines that cannot ponder the 'easy' and 'hard' commands now skip LaunchSearch() is OK, as LaunchSearch() would not do anything in that case.
Eliminate continues from GUI loop The 'continue' statements at the end of the code sections for handling specific commands, which caused matching for the remaining commands after it to be skipped, are now deleted, and the code to be skipped is placed in an 'else' clause. This to make restructuring of the GUI loop easier. The 'continue' statements for 'easy' and 'hard' commands were left, as these were harmless: it doesn't matter whether we call LaunchSearch() after them or not.
Put launching of searches in a separate routine The code section that tested if the engine should search, and would start the required search if this was the case, is now put in a routine LaunchSearch(). This is then called from the infinite loop that handles the GUI commands (where it was located before).