Translate status bar messages.
[kaya.git] / lib / plugins / ics / lib / match_handler.rb
blob718b6351bd8b6918b6a4b493f312362243a8d15f
1 # Copyright (c) 2009-2010 Paolo Capriotti <p.capriotti@gmail.com>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 require 'interaction/match'
9 require 'dummy_player'
10 require_bundle 'ics', 'icsplayer'
11 require_bundle 'ics', 'match_helper'
13 module ICS
16 # Responds to ICS protocol events creating and updating matches.
17
18 # Only one match handler per ICS connection is required. Each game created,
19 # game deleted, and style12 event for the given connection is handled by
20 # this object.
21
22 # A map of matches by ICS game number is maintained in the @matches instance
23 # variable. It is possible to have more than one match running at the same
24 # time, since multiple games can be observed.
25
26 class MatchHandler
27   include Observer
28   
29   attr_reader :matches
30   attr_reader :protocol
31   
32   # 
33   # Create a match handler for the ICS connection associated to protocol.
34   # 
35   def initialize(view, protocol)
36     @protocol = protocol
37     @matches = { }
38     @view = view
39     
40     protocol.add_observer(self)
41   end
42   
43   # 
44   # Create a new match.
45   # 
46   # This method is called whenever a new game is created on the server.
47   # The match_info structure is filled by the protocol.
48   # 
49   def on_creating_game(data)
50     helper = MatchHelper.get(data[:helper] || :default)
51     match_info = helper.create_match(self, data)
52     @matches[match_info[:number]] = match_info
53   end
54   
55   # 
56   # Remove a match.
57   # 
58   def on_end_game(data)
59     match_info = @matches.delete(data[:game_number])
60     if match_info
61       match = match_info[:match]
62       match.close(data[:result], data[:message])
63     end
64   end
65   
66   # 
67   # Remove an examined game. Simply delegate to on_end_game.
68   # 
69   def on_end_examination(number)
70     on_end_game(:game_number => number,
71                 :result => '',
72                 :message => '')
73   end
74   
75   # 
76   # When reverting, set the :about_to_revert_to property to the
77   # move index we are about to revert to.
78   # 
79   # This is used by ICSPlayer to discard any expected navigation
80   # information on revert.
81   # 
82   def on_examination_revert(data)
83     match_info = @matches[data[:game_number]]
84     if match_info
85       match_info[:about_to_revert_to] = data[:index]
86     end
87   end
88   
89   # 
90   # Forward a style12 event to the appropriate ICSPlayer.
91   # Special care is required in some cases, because ICS can issue style12
92   # events without any sort of header.
93   # This function takes care of creating a match when a style12 event for
94   # an unknown match is received, and to start a match when the first style12
95   # arrives.
96   # 
97   def on_style12(style12)
98     # retrieve match and helper
99     helper = MatchHelper.from_style12(style12)
100     if helper.nil?
101       warn "Unsupported style12. Skipping"
102       return
103     end
104     match_info = @matches[style12.game_number]
105     if match_info and match_info[:match] and match_info[:match].closed?
106       helper.close_match(self, match_info)
107       return
108     end
109     
110     # update match using helper and save it back to the @matches array
111     match_info = helper.get_match(self, match_info, style12)
112     @matches[style12.game_number] = match_info
113     
114     return unless match_info
115     match = match_info[:match]
116     
117     if match.started?
118       match_info[:icsplayer].on_style12(style12)
119     else
120       helper.start(@protocol, @view, match_info, style12)
121     end
122   end