1 require 'plugins/plugin'
8 plugin :name => 'XBoard Engine Protocol',
12 FEATURES = %w(ping setboard playother san usermove time draw sigint sigterm
13 reuse analyze myname variants colors ics name pause done)
15 attr_reader :name, :color
17 def initialize(path, name, color, match, opts = {})
24 @serializer = @match.game.serializer.new(:compact)
27 @engine = KDE::Process.new
28 @engine.on(:readyReadStandardOutput) { process_input }
29 @engine.on(:started) { on_started }
30 @engine.on('finished(int, QProcess::ExitStatus)') { on_quit }
36 text = @serializer.serialize(data[:move], data[:old_state])
45 @engine.working_directory = @opts[:workdir] if @opts[:workdir]
46 @engine.output_channel_mode = KDE::Process::OnlyStdoutChannel
47 @engine.set_program(@path, @opts[:args] || [])
55 @match.observe(:started) do
64 send_command "protover 2"
68 def send_command(text)
69 if @engine.state == Qt::Process::Running
71 os = Qt::TextStream.new(@engine)
73 puts "> #{text}" if @opts[:debug]
78 @command_queue << text
83 while @engine.can_read_line
84 line = @engine.read_line.to_s
85 line.gsub!(/\r?\n?$/, '')
86 puts "< #{line}" if @opts[:debug]
91 def process_command(text)
92 args = text.split(/\s+/)
94 m = "on_command_#{cmd}"
102 def on_command_feature(*args)
104 if arg =~ /^(\S+)=(\S+)$/
107 if FEATURES.include?(feature)
108 @features[feature] = value == '1' ? true : value
109 send_command "accepted #{feature}"
111 send_command "rejected #{feature}"
117 def on_command_move(move)
118 move = @serializer.deserialize(move, @match.history.state)
120 @match.move(self, move)
124 def extra_command(text)
125 if text =~ /^My move is: (.*)$/
131 @command_queue.each do |cmd|