My engine is in c++. The protocol is 'half' winboard, the GUI sends commands via a pipe.
Each command is a character above 100, followed by some text and ended with "END" plus the linefeed character.
For each command I created I also created a 'received signal'.
For example:
const int vb2pb_DoMove = 110;
const int pb2vb_DoMove_Received = 111;
const int vb2pb_Search = 114;
const int pb2vb_Search_Received = 115;
const int vb2pb_DoMoveAndSearch = 116;
const int pb2vb_DoMoveAndSearch_Received = 117;
const int vb2pb_SetupPosition = 118;
const int pb2vb_SetupPosition_Received = 119;
So for each command my GUI sends it waits in a loop by the received answer from the engine.
These received responses from the engine to the GUI are sent to a hidden textbox in the GUI.
That's why I call it half winboard. This scheme was made in 2001.
So it worked all these years. But lately I decided to go without the received signal from the engine, because I want to speed up some operations like fast take backs and fast move forwards to browse complete games using the arrow keys.
But a problem arises. Usually there are several messages in the pipe (separated by the LF char).
I use the following function to read a line from the pipe:
Code: Select all
string ReadPipe(void) {
string text = "";
getline(cin, text);
return text;
}
The problem is that it deletes the remaining messages waiting in the pipe.
The messages are indeed separated by the LF code, no doubts on that, since I checked each char ascii code.
So I changed the ReadPipe function to show the pipe before and after the 'getline(cin, text);' instruction.
Code: Select all
string ReadPipe(void) {
string text = "";
PrintGeneralText("ReadPipe: immediately befor 'getline(cin, text);' PipeContents=*" + PipeContents(hStdin) + "*", 1);
getline(cin, text);
PrintGeneralText("ReadPipe: message red: " + Msg2Descriptor((unsigned char)text[0]) + " *" + text + "*", 1);
PrintGeneralText("ReadPipe: immediately after 'getline(cin, text);' PipeContents=*" + PipeContents(hStdin) + "*", 1);
return text;
}
Code: Select all
ReadPipe: immediately befor 'getline(cin, text);' PipeContents=*Ç-1,24-31,00000000000000000000000B0B00000WbEND
€END
n-1,24-31,00000000000000000000000B0B00000WbEND
§ 1,0000000000000000000000000B0000BWw,InfiniteAnalysisEND
*
ReadPipe: message red: vb2pb_SetOpponentMoveInfo *Ç-1,24-31,00000000000000000000000B0B00000WbEND*
ReadPipe: immediately after 'getline(cin, text);' PipeContents=**there are 3 messages waiting in the pipe, the funny characters Ç € § are the codes that identify the messages, each message ends with "END" plus the LF char. After posting the output here in talkchess there is a line feed after each "END" string as you can see, wich doesn't happen in notepad.
The getline(cin, text); line does read properly the first message, but removes everything from the pipe as shown by the 2 asteriscs **
So the other 2 messages are simply gone.
To read the pipe I use the following function:
Code: Select all
string PipeContents(HANDLE hReadPipe) {
DWORD nBufferSize, lpBytesRead, lpTotalBytesAvail, lpBytesLeftThisMessage;
size_t find;
string msg;
if (PeekNamedPipe(hReadPipe, NULL, 0, NULL, &lpTotalBytesAvail, NULL) && lpTotalBytesAvail>0) { //'first det. if there are bytes waiting to be red
nBufferSize = lpTotalBytesAvail;
string buff(nBufferSize + 2, ' ');
if (PeekNamedPipe(hReadPipe, (LPVOID)buff.c_str(), nBufferSize, &lpBytesRead, &lpTotalBytesAvail, &lpBytesLeftThisMessage)) {
find = buff.find(Lf);
if (find == string::npos) {
PrintGeneralText("Error in PipeContents: Lf not found in buff!");
Print_to_logfile("Error in PipeContents: Lf not found in buff!");
}
else {
msg = my_Left(buff, lpTotalBytesAvail);
if (msg.length()>0) {
return msg;
}
}
}
}
return "";
}
thanks in advance,
Alvaro[