X-Git-Url: https://git.sesse.net/?p=remoteglot;a=blobdiff_plain;f=Engine.pm;h=c364ae5daff3a800082d5abb00c3d5cdc43a41b4;hp=f2c6545213f67c1168c17f7e65bd8c730404467f;hb=6f6ae45314e4f9876ab4fa9b9ba50e0c6a5e8371;hpb=c5722d685ee1354ce6466c1cf3ec947c0045ec14 diff --git a/Engine.pm b/Engine.pm index f2c6545..c364ae5 100644 --- a/Engine.pm +++ b/Engine.pm @@ -1,15 +1,23 @@ #! /usr/bin/perl use strict; use warnings; +use IPC::Open2; package Engine; sub open { - my ($class, $cmdline, $tag) = @_; + my ($class, $cmdline, $tag, $cb) = @_; my ($uciread, $uciwrite); my $pid = IPC::Open2::open2($uciread, $uciwrite, $cmdline); + my $ev = AnyEvent::Handle->new( + fh => $uciread, + on_error => sub { + my ($handle, $fatal, $msg) = @_; + die "Error in reading from the UCI engine: $msg"; + } + ); my $engine = { pid => $pid, read => $uciread, @@ -18,8 +26,13 @@ sub open { info => {}, ids => {}, tag => $tag, + ev => $ev, + cb => $cb, + seen_uciok => 0, }; + print $uciwrite "uci\n"; + $ev->push_read(line => sub { $engine->_anyevent_handle_line(@_) }); return bless $engine; } @@ -28,38 +41,20 @@ sub print { print { $engine->{'write'} } "$msg\n"; } -sub read_lines { - my $engine = shift; - - # - # Read until we've got a full line -- if the engine sends part of - # a line and then stops we're pretty much hosed, but that should - # never happen. - # - while ($engine->{'readbuf'} !~ /\n/) { - my $tmp; - my $ret = sysread $engine->{'read'}, $tmp, 4096; +sub _anyevent_handle_line { + my ($engine, $handle, $line) = @_; - if (!defined($ret)) { - next if ($!{EINTR}); - die "error in reading from the UCI engine: $!"; - } elsif ($ret == 0) { - die "EOF from UCI engine"; + if (!$engine->{'seen_uciok'}) { + # Gobble up lines until we see uciok. + if ($line =~ /^id (\S+) (.*?)\s*$/) { + $engine->{'id'}->{$1} = $2; + } elsif ($line =~ /^uciok$/) { + $engine->{'seen_uciok'} = 1; } - - $engine->{'readbuf'} .= $tmp; + } else { + $engine->{'cb'}($engine, $line); } - - # Blah. - my @lines = (); - while ($engine->{'readbuf'} =~ s/^([^\n]*)\n//) { - my $line = $1; - $line =~ tr/\r\n//d; - push @lines, $line; - } - return @lines; + $engine->{'ev'}->push_read(line => sub { $engine->_anyevent_handle_line(@_) }); } - - 1;