From: Andrew Wagner Date: 2013-03-16T10:16:50+09:00 Subject: Re: IO buffering problem --047d7b6dcf468794a204d8008228 Content-Type: text/plain; charset=UTF-8 Ha, I fixed it. You were almost right, Garthy, the UI was seemingly-randomly sending me SIGINTs. I had to tell it in the protocol initializer not to do that. Very odd. On Fri, Mar 15, 2013 at 8:09 PM, Andrew Wagner wrote: > Thanks for the response. I really don't have to handle every incoming > response. I put in the line you suggested, and it did indeed identify a > number of commands that are "unknown". But that's ok, as far as I can tell. > > As for "if" vs. "case", in my real program, I did something even more > general: > https://github.com/arwagner/tdchess/blob/master/lib/tdchess/runner.rb . > This lets you plug in any command handlers you want. I plan on having a > library of handlers for different commands, maybe a nice DSL or something > for creating new ones, etc. Obviously, I shortened all of that to isolate > this problem. > > > On Fri, Mar 15, 2013 at 7:57 PM, Garthy D < > garthy_lmkltybr@entropicsoftware.com> wrote: > >> Hi Andrew, >> >> >> On 16/03/13 09:04, Andrew Wagner wrote: >> >>> All, >>> I'm writing a chess program that has a simple text-based interface. It's >>> designed to be run by another program, which has a nice UI. Here's the >>> program as it stands now, whittled to the simplest possible use case: >>> >>> i = 0 >>> moves = ["a7a6","a6a5","a5a4","a4a3"] >>> $stdin.each do |command| >>> if command.start_with?("protover"**) >>> $stdout.puts "feature ping=0 setboard=1 ics=1 usermove=1" >>> elsif command.start_with?("usermove"**) >>> $stdout.puts "move #{moves[i]}" >>> i+=1 >>> end >>> $stdout.flush >>> end >>> >>> The "protover" thing is needed to tell the UI program how to initialize >>> the protocol, and then every time a move is made, the UI program sends >>> "usermove " to my program, which responds with "move >> move>". >>> >>> If I run this by itself, I can happily enter a few 'usermove' commands >>> manually, and get any number of canned moves back. However, when I run >>> this under the UI, I get an Interrupt: >>> >>> bin/winboard.rb:3:in `each': Interrupt >>> from bin/winboard.rb:3:in `
' >>> >>> I know that the UI program is pretty reliable, so I'm missing something >>> in the way that I'm handling IO buffering or something. If you want the >>> nitty gritty details, you can see them at >>> http://www.gnu.org/software/**xboard/engine-intf.html. I'm running on >>> MacOSX. Any suggestions? >>> >> >> Is it possible that you aren't processing one of the commands from the >> program, and the program is terminating your script, perhaps after a >> timeout or incorrect response? I'm wondering what would show up if you >> added this: >> >> else >> $stderr.print "Unknown command: '#{command}'\n" >> >> just before the second-last line. Are you handling every incoming command >> as it expects? >> >> Incidentally, you could always turn those if statements into case/when, >> something like: >> >> case command >> when /^protover/ >> ... >> when /^usermove/ >> ... >> else >> $stderr.print "Unknown command: '#{command}'\n" >> end >> >> This might make it easier if there are a lot of commands you need to >> respond to. >> >> Cheers, >> Garth >> >> > --047d7b6dcf468794a204d8008228 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Ha, I fixed it. You were almost right, Garthy, the UI was = seemingly-randomly sending me SIGINTs. I had to tell it in the protocol ini= tializer not to do that. Very odd.=C2=A0

On Fri, Mar 15, 2013 at 8:09 PM, Andrew Wagner <= span dir=3D"ltr"><wagner.andrew@gmail.com> wrote:
Thanks for the response. I really don= 9;t have to handle every incoming response. I put in the line you suggested= , and it did indeed identify a number of commands that are "unknown&qu= ot;. But that's ok, as far as I can tell.=C2=A0

As for "if" vs. "case", in my real progr= am, I did something even more general:=C2=A0https:= //github.com/arwagner/tdchess/blob/master/lib/tdchess/runner.rb . This = lets you plug in any command handlers you want. I plan on having a library = of handlers for different commands, maybe a nice DSL or something for creat= ing new ones, etc. Obviously, I shortened all of that to isolate this probl= em.


<= div class=3D"im">On Fri, Mar 15, 2013 at 7:57 PM, Garthy D <garthy_lmkltybr@entropicsoftware.com> wrote:
Hi Andrew,
=


On 16/03/13 09:04, Andrew Wagner wrote:
All,
I'm writing a chess program that has a simple text-based interface. It&= #39;s
designed to be run by another program, which has a nice UI. Here's the<= br> program as it stands now, whittled to the simplest possible use case:

i =3D 0
moves =3D ["a7a6","a6a5","a5a4","a4a3&qu= ot;]
$stdin.each do |command|
=C2=A0 =C2=A0if command.start_with?("protover")
=C2=A0 =C2=A0 =C2=A0$stdout.puts "feature ping=3D0 setboard=3D1 ics=3D= 1 usermove=3D1"
=C2=A0 =C2=A0elsif command.start_with?("usermove")
=C2=A0 =C2=A0 =C2=A0$stdout.puts "move #{moves[i]}"
=C2=A0 =C2=A0 =C2=A0i+=3D1
=C2=A0 =C2=A0end
=C2=A0 =C2=A0$stdout.flush
end

The "protover" thing is needed to tell the UI program how to init= ialize
the protocol, and then every time a move is made, the UI program sends
"usermove <some move>" to my program, which responds with &= quot;move <my move>".

If I run this by itself, I can happily enter a few 'usermove' comma= nds
manually, and get any number of canned moves back. However, when I run
this under the UI, I get an Interrupt:

bin/winboard.rb:3:in `each': Interrupt
from bin/winboard.rb:3:in `<main>'

I know that the UI program is pretty reliable, so I'm missing something=
in the way that I'm handling IO buffering or something. If you want the=
nitty gritty details, you can see them at
http://www.gnu.org/software/xboard/engine-intf.html . I&#= 39;m running on
MacOSX. Any suggestions?

Is it possible that you aren't processing one of the commands from the = program, and the program is terminating your script, perhaps after a timeou= t or incorrect response? I'm wondering what would show up if you added = this:

else
=C2=A0 $stderr.print "Unknown command: '#{command}'\n"
just before the second-last line. Are you handling every incoming command a= s it expects?

Incidentally, you could always turn those if statements into case/when, som= ething like:

case command
when /^protover/
...
when /^usermove/
...
else
=C2=A0 $stderr.print "Unknown command: '#{command}'\n" end

This might make it easier if there are a lot of commands you need to respon= d to.

Cheers,
Garth



--047d7b6dcf468794a204d8008228--